在 Nginx 中启用 HSTS 需在 HTTPS server 块中添加 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always,仅限 443 端口配置,禁用 HTTP 块添加,并建议先用 max-age=300 测试验证后再延长。

要在 Nginx 中启用 HSTS(HTTP Strict Transport Security),只需在配置中使用 add_header 指令添加 Strict-Transport-Security 响应头。关键在于正确设置参数,尤其是 max-age 和安全标志,否则可能失效或引发风险。
基础配置:启用 HSTS 并设置有效期
HSTS 的核心是告诉浏览器“未来一段时间内,只允许通过 HTTPS 访问这个域名”。最常用写法是:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
- max-age=31536000 表示 1 年(单位为秒),这是推荐的最小值,低于 6 个月可能不被主流浏览器视为可信
- includeSubDomains 表示该策略也适用于所有子域名(如 api.example.com、www.example.com)
- preload 是可选标记,表示你愿意将域名提交到浏览器内置 HSTS 预加载列表(需额外提交并满足更严要求)
- always 参数很重要——它确保即使响应状态码不是 2xx(比如 301、404),HSTS 头依然会被发送,避免因重定向或错误页漏发
必须只在 HTTPS 虚拟主机中配置
HSTS 头**不能**出现在 HTTP 服务块中。如果在 80 端口的 server 块里加了 add_header,Nginx 会照常发送,但浏览器会直接忽略——因为 RFC 明确规定:HSTS 只接受来自 HTTPS 响应的声明。
常见错误写法:
server {
listen 80;
add_header Strict-Transport-Security ...; # ❌ 无效,且可能暴露配置意图
}正确做法是仅在监听 443 的 HTTPS server 块中添加,并确保证书有效、SNI 正常工作。
测试与验证是否生效
配置后重启 Nginx(nginx -t && systemctl reload nginx),然后用以下方式确认:
- 访问站点,在浏览器开发者工具的 Network → Headers 标签页中查看响应头,确认存在
Strict-Transport-Security - 使用在线工具如 hstspreload.org 检查格式是否合规,是否满足预加载条件
- 首次访问 HTTPS 后,尝试手动输入
http://yourdomain.com,观察是否被浏览器自动跳转(注意:这依赖本地缓存,非实时强制;真正的 HSTS 效果会在下次访问时触发)
上线前建议:先用短 max-age 过渡
刚启用 HSTS 时,不建议一步设为 1 年。可先用较短周期(如 max-age=300,即 5 分钟)测试一周,确认全站资源(图片、JS、CSS、API)都支持 HTTPS、没有混合内容报错,再逐步延长至 31536000。
一旦 max-age 生效,浏览器就会强制 HTTPS,期间若证书过期或 HTTPS 配置出错,用户将无法访问网站(除非手动清除 HSTS 缓存)。因此务必确保:
- SSL 证书有效且由可信 CA 签发
- 所有子域名已部署有效 HTTPS(开启
includeSubDomains前尤其注意) - 服务器时间准确(HSTS 时间校验依赖客户端系统时间)


















