问题

博客的独立版本部署在一个内网私有Kubernetes集群中,通过公网VPS-frps-frpc-service-pod的方式暴露于公网。在开启了https支持后,我希望所有用户不论采用哪种访问方式一律访问https协议下的url。

针对本博客,用户的访问方式基本可以分为两大类:一类是通过超链接点击进入,该种方式下,只要确保外部链接中不使用http协议即可。再具体而言,搜索引擎对网站url的索引会以https优先,所以这类访问方式无需特别处理,只需要站点支持https即可。

另一类是通过在浏览器输入url进入站点。针对该场景,一种常用的方案是通过部署一个nginx拦截http请求,将其重定向至https方式访问。除此之外,我们还有另一种方案:使用hsts的方式引导客户端使用https。

关于hsts

hsts:HTTP Strict Transport Security的缩写。ietf备忘录对该特性的介绍如下:

hsts是一种让web站点能够向客户端声明本站仅支持通过安全连接访问,并让客户端将不安全连接重定向至安全连接的一种机制。

该机制主要的实现方式是由站点在http response 中加入Strict-Transport-Security的header,或者也可以使用其他的一些方式比如在user agent中配置等。

关于hsts header的具体细节,可以直接参考mozilla开发者文档中对该header详细参数的介绍

与重定向的对比

  • 实现机制:
    • http status code的3xx状态码基本流程是客户端发起http请求,到达服务器后,服务器再返回3xx状态码,客户端再次请求新的被重定向到的url。这种重定向的核心思想是针对每次需要重定向的请求,服务端对客户端发号施令,客户端依令而行。
    • 相比于重定向这种以请求为单位的思想,hsts是以域名和客户端为单位。服务端hsts的设定只需要被客户端接收一次,以后客户端便会按照规约来自动完成相应的行为(即强制使用https)。因此hsts下对服务端的长期依赖更轻。
  • 用途
    • 将http重定向至https只是3xx重定向的一个应用,除此之外重定向还可以做别的事情
    • 而hsts专为解决https强制访问而存在
  • 安全性
    • 由于3xx重定向是对每个请求而言的,如果用这种方法来处理http到https的重定向,那么每个请求都会有一个http到https的过程,那么每个请求都有可能被中间人攻击。
    • 而hsts只要解决了第一次访问时的安全问题,后续就不会再有http请求,安全性更高
  • 其他
    • 本质上而言,二者只是因为恰好能解决同一个问题,而有了一些可比性,实际上二者并不是同一类技术,所以还有一些不同点不再列出。更多对比可以参考下方链接。

开启方法

基本方法是在服务端的服务器软件中加入指定的response header,详细的header设置参考MDN文档。具体到本站对hsts的实现,采用的方式是在typecho镜像中所用到的nginx配置文件中增加如下header配置

add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";

第一次连接问题

加入该header后,是否就可以实现浏览器中输入不带https协议头的url直接跳转访问https协议的url了呢?答案是能,但是不是所有都能。

这里有一个细节需要注意,由于http协议的不安全性,hsts头在http协议下是不会生效的,因为有可能被篡改:比如可以由中间人对header中的hsts设置为关闭,此时第三方便可以移除站点的hsts的保护。因此如果用户第一次访问一个站点,没有使用https协议,即使该站点服务器开启了hsts,那么客户端也是不会跳转的。想要hsts开始生效,用户必须先访问过一次使用https保护过的站点,这样浏览器才能信任服务器的hsts配置并完成今后的自动跳转。

因此,以本博客为例,只要访问过一次https版本的本博客,以后再在浏览器输入网站访问时,便不需要输入https了,直接输入域名,即可自动跳转到https开头的url。

hsts-preload

那么更进一步的,有没什么方法可以实现不论什么情况,浏览器无脑跳https呢?为了解决用户首次访问站点可能使用不安全的连接导致hsts无法生效的问题,浏览器可以维护一个list,其中的域名永不使用非安全连接。域名的拥有者可以申请将自己的域名加入该list

总结

综上,本博客最终采用了两种方式结合的方法,满足我的需求:

  1. 第一次访问,直接输入网址访问http协议的站点首页,会被301永久转移到https协议的站点首页
  2. 在服务端开启hsts,一旦访问过本站https下的url,以后即使输入网站不加https,也会自动访问https版本
  3. 从安全性考虑,第一次重定向存在被MITM的风险,但是鉴于博客性质,风险可接受

参考

RFC 6797 - HTTP Strict Transport Security (HSTS) (ietf.org)

HTTP Strict Transport Security - HTTP | MDN (mozilla.org)

tls - What's the difference between using HSTS and doing a 301 redirection? - Information Security Stack Exchange

文章目录