要实现“完美”HTTPS强制规范,必须配合301重定向与HSTS:80端口server块用return 301 https://$host$request_uri安全跳转,443端口server块启用SSL并添加add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;确保首次跳转与后续自动HTTPS全覆盖。

要让 Nginx 实现“完美”的 HTTPS 强制规范,关键不是只做跳转,而是把 301 重定向 和 HSTS 安全头 配合使用:前者管“第一次访问”,后者管“后续所有访问”——浏览器一旦收到 HSTS 响应,就不再尝试 HTTP,连跳转都省了。
单独配置 80 端口的跳转 server 块
这个块只负责把 HTTP 请求干净利落地送走,不掺杂任何业务逻辑或 SSL 设置:
- 必须用
return 301 https://$host$request_uri;,不用rewrite,避免多跳和变量解析风险 -
$host动态匹配请求中的 Host 头,支持多域名(如 example.com 和 www.example.com) -
$request_uri完整保留路径、查询参数甚至锚点(#后内容不传,但 ? 后参数全带过去) - 不要加
ssl on、ssl_certificate或任何 location 块,否则 Nginx 启动会报错
443 端口 server 块启用有效 SSL 并添加 HSTS
HTTPS 服务本身必须稳定可用,HSTS 才有意义。在监听 443 的 server 块中加入以下几项:
-
listen 443 ssl http2;(http2 可选但推荐,提升加载效率) - 确认证书路径正确:
ssl_certificate指向 fullchain.pem,ssl_certificate_key指向 privkey.pem - 加上这行安全头:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; -
always参数确保即使响应状态码是 4xx/5xx,HSTS 头也照发,防止被绕过
注意 HSTS 的生效边界和测试要点
HSTS 不是配置完就立刻全局生效的,它依赖浏览器缓存策略:
-
max-age=31536000表示一年内,浏览器对这个域名的所有请求都会自动改用 HTTPS,哪怕用户手动输 http:// -
includeSubDomains让子域名(如 api.example.com、blog.example.com)也受保护,前提是它们也都支持 HTTPS - 首次访问仍走 301 跳转;之后只要 HSTS 缓存未过期,浏览器根本不会发 HTTP 请求——这是“完美规范”的核心体现
- 可用
curl -I http://example.com看是否返回 301,再用curl -I https://example.com看响应头里有没有Strict-Transport-Security
上线前必须做的三件事
配置写完只是开始,漏掉任一环节都可能让 HSTS + 301 失效:
- 运行
sudo nginx -t检查语法,特别是证书路径是否存在、Nginx 是否有读取权限(privkey.pem建议chmod 600) - 执行
sudo systemctl reload nginx(不是 restart),确保配置热更新 - 检查防火墙是否放行 443 端口(如
sudo ufw allow 443),否则 HTTPS 根本无法响应,HSTS 就无从谈起


















