0

Nginx HSTS max-age设置建议:分阶段配置方案与最佳实践

2026.05.26 | youres | 15次围观

配置 Nginx 的 HSTS 安全响应头时,max-age 参数是最核心的设置。它的值直接决定了浏览器记住"这个域名必须用 HTTPS"的时间长度。设得太短,防护效果有限;设得太长,一旦配置出错恢复成本高。新手经常卡在不知道该选哪个值,本文从官方推荐出发,给出分阶段的实操建议。

max-age 的基本概念

Strict-Transport-Security 响应头的标准格式如下:

Strict-Transport-Security: max-age=过期秒数

max-age 的单位是秒,不是分钟也不是天。比如 max-age=3600 表示浏览器在接下来 1 小时内只接受该域名的 HTTPS 连接。HSTS 的官方规范 RFC 6797 明确要求 max-age 不能为 0,否则等于告诉浏览器禁用 HSTS。

官方推荐的分阶段配置方案

HSTS 官方提交网站 hstspreload.org 给出了一套标准的分阶段上线流程,建议按以下顺序逐步增加 max-age 值,每一阶段都要充分观察后再进入下一阶段:

第一阶段:5 分钟(300 秒)

add_header Strict-Transport-Security "max-age=300";

适合刚启用 HSTS 的站点,用途是快速验证 Nginx 配置是否生效。如果出现 HTTPS 不可用的问题,5 分钟后浏览器自动解除限制,把风险控制在最小范围。生产环境不建议长期使用这个值,它的主要目的是测试。

第二阶段:1 周(604800 秒)

add_header Strict-Transport-Security "max-age=604800";

在确认所有页面都能正常通过 HTTPS 访问后,可以将 max-age 调整为一周。这个时间足够测试子域名和内部系统是否都正确配置了 HTTPS。如果发现问题,一周后浏览器自动恢复 HTTP 访问,不至于影响太长时间。

第三阶段:1 个月(2592000 秒)

add_header Strict-Transport-Security "max-age=2592000";

这是大多数生产网站的推荐值。一个月的时间足以验证不同地区、不同网络环境下的访问情况,同时即使后续需要回滚,一个月后浏览器也会自动放弃强制 HTTPS,运维压力相对可控。

想要加入预加载列表?max-age 必须达到这个门槛

如果你的目标是让域名进入 Chrome 等主流浏览器的 HSTS 预加载列表,从而在用户首次访问前就强制 HTTPS,hstspreload.org 对 max-age 有硬性要求:

  • 最低要求:31536000 秒(1 年)
  • 当前实际门槛:63072000 秒(2 年)

提交预加载时,响应头需要包含 includeSubDomains 指令,否则会被拒绝。同时,hstspreload.org 要求所有子域名(包括内部不可公开访问的域名)都必须支持 HTTPS,如果某个子域名还在用 HTTP,这个配置就不要急着提交。

# 预加载级别 HSTS 配置示例
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";

常见错误:max-age 和 preload 同时写容易踩的坑

很多人在配置时容易把 includeSubDomains 和 preload 写错顺序,或者漏掉了关键的 always 参数。Nginx 的 add_header 指令在 if 块内默认不继承父级块的配置,所以推荐写法是:

server {
    listen 443 ssl http2;
    ssl_certificate     /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # 关键:必须加 always 参数,否则在某些返回码下响应头不会生效
    add_header Strict-Transport-Security "max-age=2592000; includeSubDomains" always;
}

如果在同一个 server 块里同时监听 443 和 80 端口做 HTTP 跳转,建议把 HSTS 响应头只加在 443 的 server 块里,避免 HTTP 端口也带上这个头。如果在 80 端口的 server 块里也加了 HSTS 头,浏览器收到 HTTP 响应时会直接忽略。

不同场景的推荐值汇总

总结一下不同阶段的 max-age 推荐值:

  • 测试阶段:300 秒(5 分钟) — 快速验证配置
  • 灰度阶段:604800 秒(1 周) — 扩大范围测试
  • 正式上线:2592000 秒(1 个月) — 大多数生产环境推荐值
  • 预加载提交:63072000 秒(2 年) — 必须达到的最低门槛

如何验证 max-age 是否生效

配置完成后,用 curl 验证响应头是最直接的方式:

curl -I https://youres.cn
# 关注 Strict-Transport-Security 行,确认 max-age 值正确

如果浏览器仍然走 HTTP,可以打开开发者工具的 Network 面板,查看 HTTPS 响应头中是否包含 Strict-Transport-Security。如果发现 HSTS 不生效,建议排查是否缺少 always 参数,或者响应头被其他配置覆盖了。

总结

HSTS max-age 的设置没有绝对正确的唯一值,关键是根据自己站点的 HTTPS 成熟度来选择合适的阶段。新站先用小值测试,老站准备提交预加载就一步到位设到 2 年。配置时记得加上 always 参数,确保响应头在各种 HTTP 状态码下都能正常发出。如果你想了解 HSTS 不生效的更多排查方法,可以参考我之前的文章。

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论
883文章数 0评论数
作者其它文章