什么是HSTS max-age?
HSTS(HTTP Strict Transport Security)通过Strict-Transport-Security响应头告诉浏览器:在未来一段时间内,这个域名只允许通过HTTPS访问。
其中max-age参数就是那个"一段时间",单位是秒。比如:
意思是:接下来31536000秒(1年)内,浏览器都必须用HTTPS访问这个域名。
max-age设置为0到底会发生什么?
把max-age设置为0,本质上是在告诉浏览器:"忘掉HSTS吧,它过期了。"
浏览器收到max-age=0的响应后,会立即将对应的HSTS策略标记为过期,下次访问时不再强制跳转到HTTPS。
浏览器的处理机制
根据RFC 6797的规定,当浏览器收到max-age=0的HSTS响应头时,必须立即将对应域名的HSTS策略从本地缓存中删除。
这意味着:
- 之前被HSTS强制跳转的域名,现在可以重新访问HTTP版本
- 如果之前已经在HSTS preload列表中,这个操作对preload列表没有影响(preload是另一套机制)
实际测试效果
实际测试验证了这个过程:
- 先配置HSTS
max-age=86400(1天) - 用浏览器访问一次(浏览器记住了HSTS)
- 然后把
max-age改为0,再次访问 - 结果:浏览器确实不再强制跳转HTTPS了
什么时候需要把max-age设为0?
场景1:准备撤销HSTS
如果你之前配置了HSTS,但现在想撤销它(比如网站需要支持HTTP访问),第一步就是把max-age改为0。
但这还不够!改完之后,每个曾经访问过你网站的浏览器都还需要再访问一次,才能收到这个"max-age=0"的响应。这就是HSTS撤销最麻烦的地方。
场景2:调试HSTS问题
在调试HSTS相关问题时,把max-age设为0可以快速清除浏览器里的HSTS缓存,方便复现问题。
当然,更直接的方法是手动清除浏览器HSTS缓存(Chrome可以到关于Chrome HSTS缓存清除可参考官方文档操作)。
场景3:从HSTS preload列表中移除
如果你的域名在HSTS preload列表里,仅仅设置max-age=0是不够的。你还需要:
- 从网站上移除
Strict-Transport-Security响应头 - 到 hstspreload.org 提交移除申请
- 等待Chrome/Chromium更新preload列表
Nginx配置示例
把HSTS max-age设置为0的Nginx配置:
注意这里的always参数很重要!它确保这个响应头在所有响应状态下都被发送(包括4xx、5xx错误页面)。如果漏掉always,错误页面不会携带这个响应头,浏览器也就收不到"max-age=0"的指令。
max-age=0的注意事项
不是所有浏览器都立即生效
虽然RFC规定浏览器收到max-age=0后应立即清除HSTS缓存,但实际测试中,不同浏览器的行为可能有差异。
比如某些情况下,Chrome可能需要完全关闭再重新打开才能生效。Firefox的处理机制也有所不同,它会立即过期HSTS条目,但下次访问时才会真正清除。
用户已经访问过怎么办?
这是HSTS撤销最大的难题:你已经无法控制那些已经访问过你网站的用户浏览器了。
他们的浏览器里已经记住了你的HSTS策略,而且max-age还没过期。要让他们的浏览器"忘记"HSTS,必须让他们再访问一次你的网站(并且收到max-age=0的响应)。
如果用户短时间内不会再次访问你的网站,他们的浏览器会一直记住HSTS策略,导致无法访问HTTP版本。这也是为什么上HSTS之前一定要三思。
正确的"撤销HSTS"流程
如果你想彻底撤销HSTS,建议按这个流程操作:
- 把
max-age改为一个较小的值(比如60秒),等待足够长的时间让大多数用户的HSTS过期 - 再把
max-age改为0 - 等待一段时间,确保大多数用户都收到了
max-age=0的响应 - 最后再移除
Strict-Transport-Security响应头
这个流程可以最大程度减少对用户的影响。如果网站还在HSTS preload列表里,还需要额外提交移除申请。
总结
HSTS max-age设置为0是撤销HSTS的第一步,但不是全部。理解浏览器的HSTS缓存机制,才能在配置HSTS时做出正确的决策。
如果你正准备配置HSTS,建议先用较小的max-age值测试,确认没有问题后再逐步加大。千万别一上来就设置max-age=31536000(1年),一旦出问题,后果很严重。
相关阅读:
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论