hsts是浏览器端记忆型安全锁,需https响应触发且依赖301跳转兜底;配置前须确保证书有效、443端口正常、headers模块启用;须分80/443端口隔离配置,参数应渐进式上线,并严格验证生效状态。

HSTS 不是跳转指令,而是浏览器端的“记忆型安全锁”。它让浏览器在收到一次有效 HTTPS 响应后,自动把后续所有 HTTP 请求(包括手动输 http://)改写为 HTTPS。但这个机制只在 HTTPS 响应中生效,且首次访问仍需靠服务端 301 跳转兜底——两者必须配合,缺一不可。
确保 HTTPS 基础完全就绪
配置 HSTS 前,三件事必须全部满足,否则策略根本不会被浏览器接受:
- SSL/TLS 证书已部署、有效、受信:不能是自签名、过期、或域名不匹配(如证书只覆盖
www.example.com,但用户访问的是example.com) - Web 服务在 443 端口正常响应 HTTPS 请求,且能返回完整页面(不只是首页)
- 服务器 headers 模块已启用:Nginx 需加载
headers模块,Apache 需启用mod_headers
分端口配置:80 跳转 + 443 发 HSTS 头
HTTP 和 HTTPS 的逻辑必须物理隔离,不能混在同一 server 块里:
-
80 端口 server 块:只做一件事——用
return 301 https://$host$request_uri;强制跳转。禁用rewrite,避免 Host 头注入风险;$host不带端口,不拼$http_host -
443 端口 server 块:只在这里添加 HSTS 响应头,例如:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;always参数确保 404、500、304 等状态码也携带该头
参数设置与上线节奏要谨慎
别一上来就设 1 年有效期或开 preload,出问题几乎无法回滚:
- 首次上线用
max-age=300(5 分钟),用curl -I https://example.com验证响应头是否出现、值是否正确 - 确认无误后逐步延长:1 天 → 30 天 → 180 天 → 最终到 31536000(1 年)
-
includeSubDomains必须等所有子域(如api.example.com、cdn.example.com)都支持 HTTPS 后再启用 -
preload是高危操作:提交前必须满足 hstspreload.org 全部硬性要求(含全站 HTTPS 重定向、1 年以上 max-age、所有子域证书有效),一旦收录,关掉 HTTPS 用户半年内打不开网站
验证与排障要点
HSTS 是否生效,不能只看响应头有没有,要看浏览器是否真记住了:
- 用 Chrome 访问
chrome://net-internals/#hsts,输入域名查是否已缓存;可点击 Delete domain security policies 清除本地测试 - 用隐身窗口访问
http://example.com,观察是否跳转到 HTTPS(注意:Chrome 对已预载域名会直接拦截 HTTP 请求,不发包,此时看不到跳转过程) - 若用 CDN(如 Cloudflare、阿里云 DCDN),检查其控制台是否开启 HSTS 开关,确认未覆盖源站响应头
- 常见故障:服务器系统时间偏差超证书有效期、测试环境误开 HSTS 导致全员访问失败、CDN 缓存了旧的 HTTP 响应











