HSTS 的作用与代价
HSTS 通过响应头让浏览器在一段时间内强制用 HTTPS 访问站点,阻断 SSL 剥离与协议降级:浏览器记住这条策略后,即使用户输入的是 http 链接也会本地改写为 https。它的生效前提是 HTTPS 已经稳定可用,因为一旦下发长期有效期,回退 HTTPS 或证书异常的站点会在有效期内无法访问。所以推荐从小有效期起步,确认稳定后再逐步加长。
基本信息
| 响应头 | Strict-Transport-Security,规范见 RFC 6797 |
|---|---|
| 主要参数 | max-age(秒)、includeSubDomains、preload |
| 生效范围 | 仅对浏览器生效,脚本与命令行客户端的行为不受影响 |
| 前置条件 | HTTP 入口 301 或 308 跳转到 HTTPS,证书链完整可信 |
| 上线策略 | 先用 max-age=300 观察,稳定后逐步提高到一年 |
| 回退成本 | includeSubDomains 与 preload 无法快速撤回,风险最高 |
参数与影响
| 参数 | 作用 | 注意事项 |
|---|---|---|
| max-age | 强制 HTTPS 的有效期(秒) | 常用一年,首次部署先从小值开始 |
| includeSubDomains | 策略覆盖所有子域 | 先确认全部子域都支持 HTTPS |
| preload | 写入浏览器预置列表 | 申请条件严格,移除周期长 |
| always(Nginx) | 让所有响应码都带该头 | 不加则错误页可能缺头 |
| 301/308 跳转 | HTTP 入口强制跳转 | 缺跳转时首次访问仍可能明文 |
Nginx 配置示例
Nginx 配置示例
# 生产稳定后:一年有效期并覆盖子域
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 首次部署先观察:max-age=300,确认没有 HTTP 依赖后再提高
# HTTP 入口必须跳转 HTTPS,否则浏览器第一次访问仍可能是明文
server {
listen 80;
server_name example.com;
return 308 https://$host$request_uri;
}要点
要点
HTTP 入口保持 301/308 跳转到 HTTPS
includeSubDomains 之前确认所有子域都支持 HTTPS(含内部系统与测试域)
preload 列表申请条件严格,评估后再操作
回退步骤要预演:万一需要下线 HTTPS,如何在有效期内恢复访问
上线后用 curl -I 与浏览器开发者工具确认响应头确实下发典型使用场景
- 站点启用 HTTPS 后的传输层加固
- 合规与等级保护检查中的传输安全项
- 修复 SSL 剥离类问题的验收项
- 多子域统一治理时评估覆盖范围
- CDN 与源站响应头一致性核查
- 迁移域名或更换证书前的风险评估
一旦下发长期 HSTS,回退 HTTPS 会造成一段时间内全站不可访问。变更证书、域名或负载均衡之前先做规划,并明确回退方案与等待周期。
检查时注意头部是否在所有响应上生效:Nginx 的 add_header 不加 always 时,4xx 与 5xx 响应可能不带该头,错误页就成了降级可利用点。