先前一篇博客中咱们已经说到,全网 HTTPS 已是大势所趋,多数网站都已经支持 HTTPS 访问,但是在由 HTTP 转向 HTTPS 路程中,不少网站管理员都会面临一些不可避免的问题:
1、用户使用习惯:通常咱们准备访问某个网站时,在浏览器中只会输入一个域名,并不会在域名前面加上 http:// 或者 https://,而是由浏览器自动填充的,当前所有浏览器默认填充的都是http://。
所以网站管理员采用了一个方法,通过使用301/302跳转的方式,由 http 跳转到 https,如下图所示:
2、耗时较多:上述跳转增加了一次浏览器与服务器的交互过程,所以加长了用户的访问与等待时间,影响了用户体验。
3、不安全:上述跳转是由 http 跳转到 https,其中还是用到了 http,因此容易发生劫持,遭受第三方攻击,如下图所示:
4、通常情况下,当用户访问到不安全的 https 网址时,浏览器会提示用户当前访问的网站不安全,但是还是允许用户在了解安全风险之后继续访问,如果用户继续,就会面临数据泄密的风险。如下所示:
面对上述问题,网站管理员比是比较头大,好在 HSTS 的出现使得上述问题得以迎刃而解。
1、HSTS 详情
HSTS 理解起来也比较容易,它是通过服务器发送一个响应头的方式来控制浏览器操作的,咱们先来看一下 HSTS 响应头的构成:
Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]
此响应头只有在 https 访问返回时才生效,其中[ ]中的参数表示可选
max-age:HSTS 功能生效时间,单位是秒,也就是说在这段时间内,浏览器将始终强制采用 HTTPS 来访问相应的网址
includeSubDomains:如果指定,则表示域名(例如:upyun.com)对应的每个子域名(例如:www.upyun.com 或 123.example.upyun.com),浏览器在访问时也都会强制采用 HTTPS 进行访问
preload:如果指定,则表示此域名同意申请加入由 Google 发起的 Preload List,申请地址。
举例如下:
2、实现方式
上述说明,可能不是很好理解,那咱们就拿一个实际的例子来说明一下:
1) 当只有 max-age 参数时,设置时间为 300 秒
作用是:在这300秒内,只要用户在浏览器中输入 zzx1…..club/123.gif ,则浏览器会自动强制使用 https://zzx1….club/123.gif 进行访问
(注意:这里的时间设置不宜过长,一般建议为6个月。
如果设置很长,而域名某天不再使用https,且时间并未过期,则将导致用户无法访问)
大家抓包时可能会发现,有一个 307 的状态码,这个和上述 301/302 状态码不同,它并不是服务器返回的,而是浏览器本地自动生成,即在浏览器本地自动发生了 http 到 https 的跳转,与网站服务器没有任何交互。
响应头中:Non-Authoritative-Reason:HSTS,也标明了是因为 HSTS 功能的缘故,导致浏览器本地发生了 http 到 https 的跳转。
2)当有 includeSubDomains 参数时
作用是告诉浏览器,当用户访问域名的(例如:upyun.com)每个子域名(例如:www.upyun.com 或 123.example.upyun.com)时,浏览器也必须强制采用 HTTPS 进行访问。
注意:如上所述,此参数影响范围较大,如果某些子域名没有启用 https,则将导致无法访问,所以添加请谨慎!
例如:域名 zzx…..club 响应头中添加了:includeSubDomains
而子域名 www.zzx….club 中并未设置 HSTS 的响应头, 但当用户访问子域名 www.zzx….club/123.gif 时,浏览器同样也会强制采用 https://www.zzx….club/123.gif 来进行访问,如下图所示
3)当有 preload 参数时
此参数标明:本域名同意加入由 Google 发起的 Preload List,申请地址。
咱们先说一下这个列表是干啥用的:
HSTS 的响应头是由服务器返回的,所以用户需要首先发起访问,然后才能获取到这个响应头,之后浏览器才可以根据这个响应头进行相应的强制 https 访问操作了。
然而当用户第一次发起访问时,浏览器中输入 www.zzx….club, 这个时候浏览器是没有此域名相关的 HSTS 响应头的,所以也就无法强制用 https 访问了。那服务器收到的就是用户 http 请求,然后服务器返回 301/302 告诉浏览器跳转到 https://www.zzx….club 进行访问,浏览器收到301/302后,使用 https://www.zzx….club 再次发起访问,服务器收到了用户的 https 请求,则返回 HSTS 的响应头,此时浏览器才能收到域名对应的 HSTS 响应头。
从上述过程中可以看到,用户第一次访问时,仍然无法避免进行一次 301/302 跳转,那也就是说,还是有可能被第三方攻击的。那怎么办呢?
这时就需要用到 Google 维护的一个域名列表(Preload List)了,同时 Google 将这个列表硬编码嵌入到了 chrome 浏览器中,只要加入到这个列表中的域名,当使用 chrome 访问时,chrome 就会自动将这个域名强制使用 https 进行访问。
也就是说,某个域名即使是用户第一次访问,也会被 chrome 强制转换为 https 再访问,这样也就避免了首次访问时的第三方攻击。
注意:除非网站打算长久使用 https,否则请勿随意加入,因 Preload List 是硬编码进入浏览器中的,所以更新迭代比较慢,如果加入后想退出,时间耗时会比较长,需要等浏览器版本更新(当前采用此列表的浏览器有:Chrome, Firefox, Opera, Safari, IE 11 and Edge 等)
申请加入Preload List时,Google 并不会判定申请人是否是域名所有者,因此,为了防止别人恶意将您的域名加入 Preload List,所以 preload 参数请勿随意添加到域名的响应头中。
申请加入这个列表时,步骤也比较简单, 网站 上的说明也非常清楚,我们这里就不一一阐述了,大家一步一步来就可以了。举例如下:
4)当网站开启 HSTS 后,用户将不能忽略浏览器的不安全提示,无法继续访问不安全链接,因此可以进一步保护用户的数据安全,如下:
对于那些安全性要求较高的网站,HSTS 无疑是一个不错的选择,启用这项功能后,当用户访问网站域名时,市面上主流浏览器都会强制性地使用 HTTPS 来请求网站资源,可以更加有效地保护网站和用户的数据安全。
综上所述,开启 HSTS 后,上述背景中提到的 1、2、3、4 问题都可得到很好的解决。
最后再强调一点:
HSTS 的出现,在带来安全、便捷的同时,咱们也需要谨慎操作,因为如果某个参数设置不当,就有可能将导致网站长时间无法访问,那损失就大了。
所以只要咱们能够分析明白、理解透彻,根据自身情况,合理设置每个参数,就可以达到预想的效果,既能保证安全,又可以提升网站访问效率。
1、开启 HSTS 以后,可以到 ssllabs 做一下测试,网站的安全等级会进一步提升
开启前等级为:A
开启后等级变为:A+