一、背景
项目A是二级域名,并且使用 HTTPS 访问,
子项目B使用的是基于该二级域名的三级域名,仅使用 HTTP 访问,
但是上线后发现项目B访问的时候出现下图的错误。
点开高级,会看到下图的信息,见红框中的 HSTS,
另外,查看控制台的 network,产生了两次请求,而且第一次请求居然被 307了,黑人问号脸?
然后查看项目A的 network,发现 response headers 中有 HSTS 的信息。
好了,所有的证据都指向一个点:HSTS,所以就来搞清楚这个 HSTS 待敌是啥玩意儿。
二、知识点
1、什么是 HSTS
国际互联网工程组织IETF正在推行一种新的Web安全协议
全称是:HTTP Strict Transport Security
作用:简言之就是浏览器端会将 http 请求强制转为 https 请求,从此服务器端再也不要再进行重定向操作了。
开启:当客户端发起 HTTPS 请求后,服务端返回的超文本传输协议响应头中包含 Strict-Transport-Security 字段,
如:Strict-Transport-Security: max-age=31536000; includeSubDomains
这说明:① 在未来的 31536000秒(一年)内,HSTS 都是生效的,即该域名的 http 请求都将自动转为 https 请求;② includeSubDomains 意味着该域名下的所有子域名也都会采用 https 请求
2、弊端
① 当 Strict-Transport-Security 还未过期,但是域名的证书已经过期了,此时处于 HSTS 考虑,浏览器仍然会采用 https 的方式访问,即会提示不安全
② 当主域名的证书并不是通配符证书时,此时子域名会强制走 HSTS,所以也会提示不安全,无法访问
③ 虽然 HSTS 有效抵御了一些不安全的问题(下文会提到),即所有的请求都是走的 HTTPS,但是首次访问的时候走的是 HTTP 协议(暂不考虑Preload List),黑客也是有机可乘的
④ Strict-Transport-Security 过期之后的首次请求,走的又是 HTTP 协议
3、优势
不仅仅是优势,其实也是最大的安全技术:HSTS可以用来抵御SSL剥离攻击。
何为SSL剥离攻击?就是说人们访问站点的时候,一般都是使用的 HTTP 请求,然后再由服务端进行重定向操作,此时攻击者将用户访问的所有 HTTPS 协议的地址转为 HTTP 协议的地址,从而达到阻止HTTPS的目的,简言之就是偷偷地将目标地址换成指向指定的类似钓鱼网站等地址。
而 HSTS 的作用就是,当浏览器和服务端创建过一次安全连接后,之后所有的请求便都会转换成 HTTPS 协议的请求。
三、解决
我们现在的问题不是要去添加 HSTS,而是要去取消 HSTS。
从浏览器到服务端,其实中间最主要经过的就是 nginx。
1、处理 nginx
修改 nginx 的配置配置文件,发现根本就没有配置 Strict-Transport-Security ,于是就手动添加一行配置,将时间设置为 1 秒,
重启后发现了神奇的事情,查看 network 的时候,发现响应头信息中有两条 Strict-Transport-Security,又是黑人问号脸。推断其中时间为1秒的应该是nginx中的配置。
所以,修改 nginx 配置是行不通的
2、终极解决之道
中间又踩了一些坑,最后发现,应该是去调整服务端的响应头信息,
服务端主体技术是 springBoot,安全框架是 springSecurity,然后又踩了一波坑,最后发现,其实只要调整的是 springSecurity 中的配置。
配置见官网,点击链接。
配置也很简单,见下图即可。
四、后续
按照上文所述调整,理应完事大吉,但访问子域名的时候还是会有问题,这和浏览器的缓存有关系,那么此时,我们需要调整下浏览器。
此处仅以 Chrome 为例,
1、访问chrome://net-internals/#hsts
2、见下图操作
文章评论
过程很详细,有参考价值