所有 SSL 文章 SSL 与证书

HSTS:HTTP 严格传输安全详解

HSTS(HTTP Strict Transport Security)是一个安全响应头,告诉浏览器始终通过 HTTPS 连接——即使用户输入 http:// 或点击 HTTP 链接。浏览器一旦收到 HSTS 头,就会自动将该域名的所有未来请求升级为 HTTPS,防止降级攻击和不安全连接。

为什么 HSTS 很重要

没有 HSTS 时,对你站点的首次请求可能是 HTTP(在 301 重定向生效之前)。在这个短暂窗口内,网络上的攻击者可以:

  • 剥离 HTTPS —— 拦截重定向并让用户停留在 HTTP(SSL 剥离攻击)
  • 窃取 Cookie —— 如果 Cookie 在初始 HTTP 请求中发送
  • 注入内容 —— 修改重定向响应

HSTS 消除了这个窗口。首次 HTTPS 访问后,浏览器不再尝试 HTTP。

如何启用 HSTS

Nginx

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;

将此添加到 HTTPS server 块(端口 443)中,不是 HTTP 重定向块。

Apache

Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"

需要 mod_headerssudo a2enmod headers)。

Cloudflare

Dashboard → SSL/TLS → Edge Certificates → HTTP Strict Transport Security (HSTS) → Enable。

HSTS 参数

参数示例含义
max-age63072000(2 年)浏览器记住使用 HTTPS 的时长(秒)
includeSubDomains将 HSTS 同时应用于所有子域名
preload表明意图加入 HSTS 预加载列表

选择 max-age

阶段max-age目的
测试300(5 分钟)在承诺之前验证 HTTPS 正常工作
确认604800(1 周)如需回滚风险较低
生产31536000(1 年)标准推荐
长期63072000(2 年)预加载列表要求

从小值开始,逐步增加。 如果 HTTPS 在长 max-age 缓存期间出现故障,访问者将完全无法访问你的网站——浏览器拒绝通过 HTTP 连接。

HSTS 预加载

HSTS 预加载列表是硬编码在浏览器中的域名列表,始终使用 HTTPS,即使是第一次访问(在收到任何 HSTS 头之前)。

预加载的要求

  1. 提供有效的 HTTPS 证书
  2. 在同一主机上将 HTTP 重定向到 HTTPS
  3. HSTS 头的 max-age ≥ 63072000(2 年)
  4. 包含 includeSubDomains 指令
  5. 包含 preload 指令
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

提交预加载

前往 hstspreload.org,输入你的域名并提交。审核后(数周到数月),你的域名将被添加到浏览器内置列表中。

预加载的注意事项

  • 很难撤销。 从预加载列表移除需要数月时间,并需要浏览器发布一个新版本。在此期间,你的域名只能通过 HTTPS 访问。
  • includeSubDomains 是强制的 —— 所有子域名都必须支持 HTTPS。如果 staging.example.com 没有证书,它将变得不可访问。
  • 只有当你确信所有当前和未来的子域名都支持 HTTPS 时才进行预加载。

常见错误

在 HTTP 响应中设置 HSTS

HSTS 必须仅在 HTTPS 上发送。如果你的 HTTP 重定向也发送了 HSTS 头,浏览器会忽略它(规范要求 HTTPS)。只在端口 443 的块中设置该头。

忘记子域名

includeSubDomains 将 HSTS 应用于所有子域名。如果 internal.example.com 没有 HTTPS,它将变得不可达。启用前审计所有子域名。

过早设置过高的 max-age

如果 HTTPS 出故障(证书过期、配置错误),访问者无法回退到 HTTP。浏览器拒绝连接。先设 5 分钟,验证一切正常,然后再增加到 1 年。

如何检查 HSTS 是否生效

curl -sI https://yourdomain.com | grep -i strict-transport
# Expected: strict-transport-security: max-age=63072000; includeSubDomains

在 Chrome DevTools 中:Network 标签 → 点击请求 → Headers → 查找 Strict-Transport-Security

常见问题

HSTS 能替代 HTTP→HTTPS 重定向吗?

不能。HSTS 和重定向服务于不同目的。重定向捕获首次 HTTP 请求。HSTS 告诉浏览器以后不再发起 HTTP 请求(在首次 HTTPS 访问之后)。两者都需要。

HSTS 会导致问题吗?

会,如果 HTTPS 出故障的话。使用长 max-age 时,浏览器拒绝将 HTTP 作为回退。这就是为什么应该从短 max-age 开始,只有在 HTTPS 稳定后才增加。

如果我在 Cloudflare 上还需要 HSTS 吗?

Cloudflare 处理访客→Cloudflare 的连接,但在源站启用 HSTS 保护完整链路。通过 Cloudflare 面板为边缘启用 HSTS,如果使用 Full (Strict) 模式,也在源站启用。

HSTS 和 upgrade-insecure-requests CSP 指令有什么区别?

upgrade-insecure-requests 告诉浏览器通过 HTTPS 而非 HTTP 加载子资源(图片、脚本)——修复混合内容。HSTS 告诉浏览器始终对整个域名使用 HTTPS。它们解决不同问题,可以同时使用。

相关文章

部署 2026-05-07
如何将 HTTP 重定向到 HTTPS
使用服务端重定向强制所有流量使用 HTTPS。Nginx、Apache 和 .htaccess 的 301 永久重定向配置示例。
SSL 与证书 2026-05-08
什么是 HTTPS?完整指南
HTTPS 加密浏览器与网站之间的连接。了解 HTTPS 的工作原理、TLS 握手、HTTP 与 HTTPS 的区别、性能影响,以及如何免费启用。
部署 2026-05-08
如何在 Nginx 上安装 SSL 证书
在 Nginx 上安装 SSL 证书的分步指南。涵盖文件上传、完整 server 块配置、TLS 最佳实践、HTTP/2、HSTS、重定向设置、测试以及 6 个常见错误的排查方法。
部署 2026-05-08
如何在 Apache 上安装 SSL 证书
使用 mod_ssl 在 Apache 上安装 SSL 证书的分步指南。涵盖文件上传、VirtualHost 配置、TLS 最佳实践、HSTS、HTTP 重定向以及 5 个常见错误的排查方法。
在浏览器中获取免费 SSL 证书
无需安装,无需账号。私钥始终留在你的设备上。
获取证书