nginx 强制加密传输需协同配置:443 端口启用 tlsv1.2+、强密码套件及绝对路径证书;80 端口 301 跳转至 https;添加 hsts 头防首次降级;杜绝混合内容,确保所有资源 https 加载。

要在 Nginx 中真正实现静态或动态资源的强制加密传输,核心不是“能走 HTTPS”,而是让所有资源请求无一例外地通过 TLS 加密通道完成,同时堵住降级、跳过、缓存明文等潜在漏洞。这需要配置层面的协同设计,而非单点开关。
确保 443 端口服务本身安全可信
这是强制加密的前提——如果 HTTPS 服务本身弱不禁风,再强的跳转也形同虚设:
- 必须明确监听
listen 443 ssl http2;,不能省略ssl关键字,否则 Nginx 不会加载证书 - 证书与私钥路径用绝对路径,权限严格控制:
chmod 600 /etc/nginx/ssl/*.key,防止私钥泄露 - 禁用不安全协议:只保留
ssl_protocols TLSv1.2 TLSv1.3;,彻底移除 TLSv1.0/TLSv1.1 - 密码套件聚焦前向安全(ECDHE)和 AEAD 模式(AES-GCM/ChaCha20),例如:
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384;
切断所有 HTTP 明文入口
用户可能从书签、搜索引擎、旧链接进入 http://,必须零容忍:
- 单独定义一个仅监听 80 端口的
server块,里面只做一件事:return 301 https://$host$request_uri; - 不要用
if ($scheme = http) { ... },Nginx 官方明确反对在非 location 块中使用 if 判断协议 -
server_name必须覆盖全部有效域名(如example.com www.example.com api.example.com),缺一则该域名无法跳转 - 防火墙需放行 80 和 443 端口,否则跳转请求根本到不了 Nginx
用 HSTS 让浏览器主动拒绝 HTTP
301 跳转解决的是“已访问过”的用户,而 HSTS 解决的是“首次访问”和“手动输入 http://”的场景:
- 在 443 的
server块中添加:add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; -
max-age=31536000表示一年内浏览器自动升级所有请求为 HTTPS;上线初期可先设为300(5 分钟)验证效果 -
includeSubDomains确保cdn.example.com、static.example.com等子域也受保护 -
preload是加入主流浏览器预加载列表的必要条件,启用后不可逆撤回,务必确认全站 HTTPS 已稳定运行
防止资源被非加密方式间接加载
即使主站强制 HTTPS,若页面内引用了 HTTP 资源(如图片、JS、CSS),仍会触发混合内容警告,现代浏览器可能直接阻断加载:
- 静态资源目录(
root /var/www/html;)下所有文件应仅通过 HTTPS URL 访问,避免硬编码http://链接 - 对前端项目,构建时设置
publicPath: '/'或https://example.com/,而非协议相对路径(//example.com/xxx) - 若需代理上游(如 API 或 CDN),
proxy_pass必须指向https://地址,并开启证书校验:proxy_ssl_verify on;+proxy_ssl_trusted_certificate - 可加响应头防降级:
add_header Content-Security-Policy "upgrade-insecure-requests;" always;,辅助浏览器自动升级不安全资源











