在 nginx 中设置 hsts 的 max-age 需在启用 ssl 的 https server 块中使用 add_header strict-transport-security "max-age=31536000; includesubdomains; preload" always;,避免在 http server 中配置,确保首次访问为 https 且不可通过短 max-age 降级。

在 Nginx 中设置 HSTS 的 max-age 参数,是通过 add_header 指令向响应头中添加 Strict-Transport-Security 实现的,关键在于正确书写语法、避免被子请求覆盖,并确保只在 HTTPS 环境下生效。
直接配置 max-age 值(推荐方式)
在 server 块(且仅限于启用 SSL 的 HTTPS server)中添加:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
说明:
-
max-age=31536000表示 1 年(单位为秒),这是常见安全实践值;你可按需调整,例如max-age=63072000(2 年)或max-age=3600(1 小时,适合测试) -
includeSubDomains可选,表示该策略对所有子域名也生效 -
preload可选,表示申请加入浏览器 HSTS 预加载列表(需额外提交到 hstspreload.org) -
always参数很重要:它确保即使响应状态码不是 2xx(如 301、404),HSTS 头仍会被发送,避免因重定向或错误页漏发
不要在 HTTP server 中设置 HSTS
HSTS 只应在 HTTPS 站点启用。若在 HTTP server 块里误加该头,浏览器会忽略它 —— 这是协议强制要求。典型错误配置:
# ❌ 错误:HTTP server 中设置 HSTS 无效且无意义
server {
listen 80;
add_header Strict-Transport-Security "max-age=31536000"; # 浏览器直接丢弃
}验证是否生效
部署后,用以下任一方式确认响应头已正确返回:
- 浏览器开发者工具 → Network → 刷新页面 → 查看任意响应的 Response Headers,找
Strict-Transport-Security - 命令行:
curl -I https://yourdomain.com,观察输出中是否包含该 header - 在线检测工具如 securityheaders.com 或 hstspreload.org(提交前校验)
注意事项与常见问题
几个容易踩的坑:
-
不要重复添加:多个
add_header指令在同一作用域会相互覆盖(Nginx 默认行为),建议只写一条完整 header -
location 块中慎用:若在 location 内添加,需同样带
always,否则 301/404 等非 2xx 响应不携带该头 -
首次访问必须走 HTTPS:HSTS 不会通过 HTTP 升级,用户第一次必须主动输入
https://或通过其他 HTTPS 入口进入,策略才会被浏览器记录 - 修改 max-age 后无法立即降级:浏览器只会接受更长的 max-age,不能靠发更短值来“撤回”策略;如需测试,建议先用小值(如 300),验证无误再调高











