HSTS是强化HTTPS安全的强制策略,必须在443端口server块中配置Strict-Transport-Security响应头并带always参数,仅HTTPS响应有效;需分阶段设置max-age、审慎启用includeSubDomains与preload,并配套301跳转及全链路证书保障。

HSTS 是提升 HTTPS 网站安全等级与合规性的核心机制之一,但它不是“加一行头就完事”的开关,而是需要与证书、协议、跳转、子域治理和运维流程深度协同的策略。真正起效的前提是:全站已稳定运行 HTTPS,且所有参与域名具备有效、可信、完整链路的证书。
必须在 443 server 块中配置,并带 always 参数
HSTS 头只在 HTTPS 响应中被浏览器接受,HTTP(80 端口)响应中设置完全无效。错误地放在 http 块、location 块或 80 端口 server 中,会导致策略不生效甚至被覆盖。
- 正确写法:只在 listen 443 ssl 的 server 块内添加:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; - always 是关键:确保 404、500、304 等非 2xx 响应也携带该头,避免因状态码异常导致 HSTS 中断
- 若后端应用(如 Django、Spring Boot)也输出 HSTS,需在 Nginx 中用
proxy_hide_header Strict-Transport-Security屏蔽,防止冲突
分阶段设置 max-age,避免误锁用户
HSTS 生效后,浏览器会强制将 HTTP 请求改写为 HTTPS,且不发包——这意味着一旦主站或任一子域 HTTPS 不可用,用户可能直接无法访问。
- 首次上线务必灰度:
max-age=300(5 分钟),观察至少 15 分钟,确认无跳转失败、混合内容警告、证书错误 - 稳定后逐步延长:可先设为 15768000 秒(6 个月),再升至 31536000 秒(1 年),满足等保三级和 HSTS Preload 最低要求
- 临时禁用时,需返回
max-age=0并持续发送该头至少原 max-age 时长,浏览器才会清除本地缓存策略
谨慎启用 includeSubDomains 和 preload
这两个参数大幅扩大策略影响范围,启用即承诺——基础设施必须 100% 就绪。
-
includeSubDomains要求 api.example.com、cdn.example.com、blog.example.com 等所有一级子域均能稳定 HTTPS 访问,否则这些子域将彻底不可加载 -
preload表示申请加入浏览器内置 HSTS 列表(如 Chrome 的 hstspreload.org),提交后撤回需数月;必须同时满足:
– 全站 HTTPS 无 HTTP 回退路径
–max-age ≥ 31536000
– 含includeSubDomains
– 所有子域响应头中也含完整 HSTS 策略
– 提交前请访问 hstspreload.org 自检
配套动作缺一不可
HSTS 只解决“第二次及以后访问”的降级风险,首次 HTTP 请求仍存在被劫持可能(如 SSLstrip)。因此必须组合加固:
- 80 端口 server 块中必须配置 301 强制跳转:
return 301 https://$host$request_uri; - 检查 CDN(如 Cloudflare、阿里云 DCDN)是否透传
Strict-Transport-Security;默认常过滤自定义头,需手动开启“自定义响应头”功能 - 搭配 TLS 1.2/1.3 + PFS 密钥交换 + OCSP Stapling + 完整证书链,构成完整 HTTPS 安全闭环


















