最核心配置是将add_header strict-transport-security "max-age=31536000; includesubdomains; preload" always;置于443端口https server块内,且必须加always参数以确保所有状态码响应均携带hsts头,避免策略中断。

直接在 HTTPS 的 server 块中添加 add_header Strict-Transport-Security,并确保带 always 参数,是最核心、最安全的配置方式。
必须放在 443 端口的 HTTPS server 块里
HSTS 头只对 HTTPS 响应生效,浏览器会完全忽略 HTTP(80 端口)响应里的该头。若错配在 HTTP 块中:
- 策略无效,起不到强制 HTTPS 的作用
- 若后端应用(如 Spring Boot)又自行返回 HSTS,可能造成冲突或测试环境被浏览器永久拦截
正确写法含 always 参数和关键选项
示例配置(放在 SSL 配置下方、location 外任意位置):
ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
-
always不可省略:保证 301、404、500 等非 2xx 响应也携带 HSTS,避免策略中断 -
max-age=31536000表示一年,是预加载(preload)的硬性要求 -
includeSubDomains意味着所有子域(如 api.example.com)必须已支持 HTTPS 且证书有效 -
preload仅在满足全站 HTTPS、含子域、max-age ≥ 1 年等条件后才启用
避免后端 HSTS 冲突
若 Nginx 反向代理后端服务(如 Node.js、Java 应用),而它们也返回 HSTS 头,需主动屏蔽:
- 在对应
location块中加:proxy_hide_header Strict-Transport-Security; - 再统一由 Nginx 添加自己的 HSTS 头,确保策略可控、一致
- 注意:不能加引号,也不能写在
http或server顶层之外的位置
上线前建议灰度验证
首次启用不要直接上生产级参数:
- 先用
max-age=300(5 分钟)观察 15 分钟以上 - 逐个访问子域名(
curl -I https://sub.example.com),确认返回 200 且无证书错误 - 检查浏览器
chrome://net-internals/#hsts是否已记录,或用 hstspreload.org 验证 - 确认 CDN(如 Cloudflare)未覆盖或丢弃该 Header











