现已加入 HSTS Preload

HSTS 是什么

HSTS 的全称是 HTTP Strict Transport Security,即 HTTP 严格传输安全。它的作用是强制客户端使用 HTTPS 来访问当前网站,而不是 HTTP。

为什么需要 HSTS

防止重定向失败

通常情况下,用户访问某个网站时,不会主动输入 https://blog.xuewen.me,而是 blog.xuewen.me。浏览器会帮助用户将地址自动补全为 http://blog.xuewen.me,当网站开启了强制 HTTPS 时,会再返回 301 将用户重定向到 https://blog.xuewen.me

在这个过程中,有两个问题:

  1. 用户首先使用了 HTTP,然后再被重定向到 HTTPS,这里就存在了中间人攻击的可能,攻击者可以通过拦截 HTTP 响应,来阻止用户被重定向到 HTTPS
  2. 多了一次重定向的过程,用户首次打开网站的速度也会受到影响,虽然这个耗时几乎可以忽略不计

当开启了 HSTS 时,只要用户访问了一次网站,浏览器就会强制后续所有的请求都使用 HTTPS。

防止无效证书

如果浏览器接收到无效证书,如证书过期、证书签发自未知的 CA 等,浏览器会给用户一个可绕过的警告,当用户选择继续浏览时,就存在被中间人窃取数据的风险。

当开启了 HSTS 时,浏览器只要收到了无效证书,就会直接拒绝用户继续访问。

如何开启 HSTS

如果需要开启 HSTS,只需要在 HTTP 响应头部添加以下响应头即可:

1
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

其中:

  1. max-age 表示在接下来的多久时间(单位为秒)内,浏览器必须使用 HTTPS 来访问网站,31536000 即为 1年
  2. includeSubDomains 表示 HSTS 对所有的子域名都生效
  3. preload 表示该域名可以被 Preload

Nginx 的配置方法为:

1
2
3
4
5
6
server {
# 省略其他配置

# 添加 Strict-Transport-Security 响应头
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
}

HSTS Preload 是什么

即使网站开启了 HSTS,用户在没有访问网站前,浏览器依然不知道当前网站是否开启了 HSTS,因此第一次打开网站时,仍然会使用 HTTP 来发起请求。

为了解决这个问题,可以将域名加入到 HSTS Preload,即 HSTS 预加载。

HSTS 预加载是由 Chrome 维护的一份域名预加载列表来完成的(Firefox, Opera, Safari, IE 11 and Edge 等浏览器也会使用该列表)。当域名被加入到预加载列表后,用户在第一次访问网站时,浏览器也能知道当前网站开启了 HSTS。

为了保证预加载列表不被篡改,浏览器不会通过网络下载预加载列表,而是直接将预加载列表硬编码到浏览器中。因此,一旦将域名加入预加载列表,再移除的时间成本就会非常高。

如何加入 HSTS Preload

加入预加载列表需要满足以下要求:

  1. 拥有有效的证书,支持 HTTPS 请求
  2. 所有的子域名都支持 HTTPS 请求
  3. 如果网站接受 HTTP 请求,那么需要把 HTTP 请求自动重定向到 HTTPS
  4. 响应头需要包含 Strict-Transport-Security,并且 max-age 至少为 31536000 (1 年),需要包含 includeSubDomains,需要包含 preload

当满足以上条件时,可以在 HSTS Preload List Submission 检查并提交域名。

提交完成后,需要等待几天时间,当域名被加入预加载列表、浏览器发布新版本,即完成了加入预加载列表的操作。在等待期间,还可以在上述网站检查域名的预加载状态,出现以下提示时,即表明预加载完成:

预加载完成提示

更新浏览器版本后,可以打开 chrome://net-internals/#hsts 来检查域名的预加载状态。

也可以在这里查看预加载列表中的所有域名:transport_security_state_static.json

参考资料:

  1. https://hstspreload.org