现在,很多网站管理员的安全意识越来越强,他们纷纷开启了网站的https安全访问协议,但随之而来的也有苦恼,原来收录的都是http协议开头的网站,怎么调整到https协议,又怎样让浏览器直接访问https而不是先访问http然后再跳转呢?
插播一个小广告,万维景盛提供阿里云服务器优惠代购服务和云服务器运维服务,有需要的的亲们联系哦!
要解决这个问题,就要引入HSTS这个概念了。
在介绍HSTS之前,先来看看最典型的https用户访问过程:
首先假设要访问的网站是全站HTTPS但未开启HSTS
一般地,用户在客户端访问一个网站的时候,往往只输入域名,而不带有协议名。例如访问www.wanweiwang.cn,而不是https://www.wanweiwang.cn。
输入www.wanweiwang.cn访问,客户端与服务器来一次TCP三次握手,建立连接;
然后做301/302跳转到HTTPS;
客户端与服务器再来一次TCP握手,重新建连;
然后开始TSL(SSL)通信···
过程流图如下:
+-------+ +-------+ | 客户端 | | 服务器 | +--+----+ +---+---+ | | | <---------------------> | TCP三次握手 | | | | | <---------------------> | 301/302 http -> https | | | | | <---------------------> | TCP 三次握手 | | | | | |Clinet Hello| +---------------------> | Server Hello | | | | | <---------------------+ | 发送Certificate报文 | | | | | <---------------------+ | Server Hello Done | | | | + +
整个过程明显存在两个不足之处:
第一次的TCP握手和跳转是没有意义的;
其中第一次TCP握手是不安全的HTTP通信,通信依然存在被窃听,被伪装和报文被慕改的可能。
所以才有HSTS,其中 HSTS 是 HTTP Strict Transport Security 的缩写,即:“HTTP严格传输安全”。HSTS的出现就是解决这些问题的。HSTS的作用除了节省HTTPS通信RT和强制使用HTTPS,还包括:
阻止基于SSLStrip的中间人攻击;
万一证书有错误,则显示错误,用户不能回避警告。
HSTS的具体工作机制可描述如下:服务器端配置支持HSTS后,会在给客户端返回的HTTP首部中携带HSTS字段。客户端获取到该信息后,会将所有HTTP访问请求在内部做307跳转到HTTPS,整个过程而无需任何网络过程,也就是直接实现第一次TCP握手开始就是HTTPS通信。
但是HSTS是有缺陷的,如第一次访问网站的客户端,HSTS并不工作。 要解决这个问题,就要了解我们下面要讲解的HSTS preload list。
HSTS preload list
HSTS preload list是Chrome浏览器中的HSTS预载入列表,在该列表中的网站,使用Chrome浏览器访问时,会自动转换成HTTPS。Firefox、Safari、Edge浏览器也在采用这个列表。
其中更多关于如何申请加入 HSTS preload list,可以参考我的文章《启用HSTS和申请HSTS Preload List》,申请加入之后,就可以避免HSTS的缺陷,解决第一次访问网站的客户端HSTS不工作的问题。
最后的最后,还是提醒一下,如果真不打算长期使用HTTPS的情况下,还是不建议启用HSTS。
HSTS是“HTTP Strict Transport Security”(HTTP严格安全传输)的缩写,开启了这项设置以后,主流浏览器会强制性地使用HTTPS来请求资源,能够更加有效地保护你网站和用户的数据安全。一般情况(未启用HSTS),浏览器会允许用户在了解了安全风险之后继续使用不安全的连接来访问,但如果启用了HSTS,则不允许这样做,所以你得有一定要长期使用HTTPS的打算,才能启动HSTS。
首先本站linpx.com加入了 Chrome 的 HSTS Preload List 了,在 chromium 的 transport_security_state_static.json 中可以查看
启用HSTS
HSTS 是一个响应头,格式如下:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload;
max-age,单位是秒,用来告诉浏览器在指定时间内,这个网站必须通过 HTTPS 协议来访问。也就是对于这个网站的 HTTP 地址,浏览器需要先在本地替换为 HTTPS 之后再发送请求
includeSubDomains,可选参数,如果指定这个参数,表明这个网站所有子域名也必须通过 HTTPS 协议来访问
preload,可选参数,预加载到浏览器缓存
HSTS 这个响应头只能用于 HTTPS 响应;网站必须使用默认的 443 端口;必须使用域名,不能是 IP。而且启用 HSTS 之后,一旦网站证书错误,用户无法选择忽略。
这里贴一个 Nginx 开启 HSTS 的简易教程
打开网站所对应的Nginx的conf配置文件
假设我的配置文件是在 /usr/local/nginx/conf/vhost 的目录
vim /usr/local/nginx/conf/vhost/www.wanweiang.cn.conf
加入
server { ··· add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; ···
申请Preload List
HSTS 必须要在浏览器访问过你的网站一次以后才会生效,如果希望提前生效,需要申请 HSTS Preloading List。
目前这个 Preload List 由 Google Chrome 维护,Chrome、Firefox、Safari、IE 11 和 Microsoft Edge 都在使用。如果要想把自己的域名加进这个列表,首先需要满足以下条件:
拥有合法的证书(如果使用 SHA-1 证书,过期时间必须早于 2016 年);
将所有 HTTP 流量重定向到 HTTPS;
确保所有子域名都启用了 HTTPS;
输出 HSTS 响应头:
max-age 不能低于 18 周(10886400 秒);
必须指定 includeSubdomains 参数;
必须指定 preload 参数;
觉得妥了就去 HSTS Preload List (hstspreload.appspot.com) 这个页面申请。
在唯一一个文本框输入你的网站即可,这个列表是人工审核,因此可能需要一段时间
已经成功加入HSTS网站是这样的效果
特别提醒:对于 HSTS 以及 HSTS Preload List,如果你不能确保永远提供 HTTPS 服务,就不要启用。因为一旦 HSTS 生效,你再想把网站重定向为 HTTP,之前的老用户会被无限重定向,唯一的办法是换新域名。
同时,因为已经看了很多遍QuQu的文章,很熟悉也很认同他说述的 所以本文比较多部分参考了:imququ.com/post/sth-about-switch-to-https.htm
本文由 Chakhsu Lau 创作,采用 知识共享署名4.0 国际许可协议进行许可