HSTS
HTTP协议最初通过TCP传输,后为了传输安全,加入了SSL/TLS作为中间层,称为HTTPS(HTTP over SSL)。当在浏览器中输入一个域名访问时,浏览器默认会通过HTTP协议访问服务器,服务端可以返回301以跳转到HTTPS,此后所有数据传输通过HTTPS传输。然而,中间人攻击者可能会攻击拦截初始的http请求,从而控制用户后续的回话。
HTTP Strict Transport Security,即HSTS协议提供了一个机制,让服务端可以主动告知浏览器,以后的请求全部严格地通过HTTPS进行。
HSTS如何工作
启用HSTS
服务端向浏览器发送响应时,可以在响应头部中添加Strict-Transport-Security,告知浏览器开启HSTS。
如响应头部中有Strict-Transport-Security: max-age=86400
表示为当前域名启用HSTS,过期时间为1天。
如响应头部中有Strict-Transport-Security: max-age=259200; includeSubDomains
表示为当前域名和所有的子域名启用HSTS,过期时间为30天。
Tips
- 只有在安全传输中Strict-Transport-Security头部才会生效。在HTTP(而不是HTTPS)中Strict-Transport-Security头部会被忽略
- max-age的值为TTL(即生存时间),值为0时(例如
Strict-Transport-Security: max-age=0
)浏览器将关闭此域名的HSTS设置
浏览器自动跳转HTTPS
对于开启了HSTS的域名,浏览器将强制采用HTTPS。
1. 直接访问域名时跳转
在浏览器中访问域名时,如果域名开启了HSTS,浏览器将发生内部跳转,直接跳转到HTTPS进行访问。即使用户手动输入
2. 网页中的链接跳转
网页中的资源,如果其URL的域名启用了HSTS,浏览器请求此资源时将自动跳转的HTTPS。 如网页中有链接<img src="http://qlee.in/static/logo.img>
,而且qlee.in开启了HSTS,浏览器将自动到
3. 端口的处理
HTTP默认采用80端口,HTTPS默认采用443端口。当浏览器因为HSTS执行内部跳转时
- 1 如果没有显式指定端口,浏览器跳转时也不会显式指定端口,默认HTTPS会访问443端口
- 2 如果指定了80端口,浏览器跳转时会将端口转换为443端口
- 3 如果指定了其他端口,浏览器跳转时会保留指定的端口
HSTS对SSL连接的影响
HSTS中的Strict
不只是强制跳转到HTTPS,也包含了对HTTPS连接建立的处理。开启HSTS后,一旦有警告或者错误,浏览器将直接关闭HTTPS连接。包括以下几种
- SSL证书过期或者验证失败。没有开启HSTS时,一旦遇到证书过期、域名不匹配、签名验证失败等情况,浏览器将要求用户选择是否继续。而开启HSTS后,浏览器将关闭连接,无法继续访问。
- 证书通过OCSP或CRLs等方式被撤销。
取消HSTS
1. 服务器端关闭HSTS
服务端可以通过响应的添加头部Strict-Transport-Security: max-age=0
或者Strict-Transport-Security: max-age=0; includeSubDomains
来告知浏览器关闭域名的HSTS
2. 浏览器端关闭HSTS
对于chrome浏览器,地址栏中输入chrome://net-internals/#hsts
进入HSTS设置页面,可以查询、删除指定域名的HSTS设置,也可以手动为域名开启HSTS。
对于chrome和firefox浏览器,可以通过删除域名的历史记录来清除域名的HSTS设置。
HSTS preload list
google维护了一个称为“HSTS preload list”的站点域名和子域名列表,主流的web浏览器(Chrome, Firefox, Opera, Safari, IE 11 and Edge) 都采用了该域名列表,对列表中的域名强制开启HSTS。域名的所有者可以通过