- Published on
一些网站优化加固措施(HSTS, HTTP/2)
最近比较无聊。看看有什么东西可以给这个网站加上。这也是我用 Apache + WordPress 的原因,够原始,很多东西都要自己动手去搞,过程中顺便学学新东西。
本网站已经通过 ATS 和 PCI DSS(支付卡行业安全标准)安全合规,评级是最高级别的A+,详情请看: https://myssl.com/adamliu.net?domain=adamliu.net&status=success
HSTS
HSTS是HTTP Strict Transport Security 的简称,中文叫作HTTP 严格传输安全。这个协议是为了追求更加极致的 HTTP 安全。
它要解决的情景是这样的:
很多人在浏览器输入网址时,是不会输入 https 协议头的,而是直接输入 adamliu.net, 或者www.adamliu.net。浏览器会自动填充协议头**HTTP**,再发生请求。(就算你的网址支持HTTPS也没用,浏览器不知道啊,因为浏览器使用HTTP是最大机会能打开网站的)
这个时候服务器收到你的HTTP请求,然后返回一个3xx 重定向,让你的浏览器使用 HTTPS 协议再次打开网页。之后你点我网址内容的超链接(当然,我的网址超链接是使用//或者https://开头,如果写死了 HTTP://开头那就是 SB 了),都会使用 HTTPS 协议。
然而
一个黑帽黑客Moxie Marlinspike在 2009 年做了个SSL Stripping的demo,使用中间人攻击 (Man-in-the-middle attack,简称MITM)在这个3xx 重定的过程中,把用户的 HTTP 请求劫持了。
他为了试验这个新型攻击方式,在某个 Tor network 节点挂了一个嗅探脚本,等了 24 小时后,他有了下面的收获。
视频截图来源:https://www.youtube.com/watch?v=MFol6IMbZ7Y&t=1757s
有个简单的图例,说明这种攻击方式。
Hacker 可以直接作为中间人,一直和你保持 HTTP 链接,这样你发的东西都会被看到。然后把你的请求转发到 WEB Server,hacker 和 WEB Server 的链接过程是是 HTTPS 的。
视频截图来源自: https://www.youtube.com/watch?v=I8yKkBa-nUk
这个时候你的浏览器会显示网站证书不正确,比如现代的谷歌浏览器会显示大大的警告。
大大的警告
为了不复述内容,你可以参考下面的链接了解 HSTS 的前世今生以及 SSL Stripping 攻击:
1. 从 HTTP 到 HTTPS 再到 HSTS https://zhuanlan.zhihu.com/p/28874099
2. 针对 SSL 的中间人攻击演示和防范 https://www.linuxde.net/2011/11/2522.html
开启 HSTS (Apache)
sudo vi /opt/bitnami/apps/wordpress/conf/httpd-app.conf
#在 <Directory> </Directory> 之间加入
Header always add Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
參考:
https://blog.myssl.com/https-security-best-practices/
https://juejin.im/entry/5981c5df518825359a2b9476
HTTP/2
使用 HTTP/2 的效果
可以访问: https://h0.adamliu.net (http/1.0),https://h1.adamliu.net(http/1.1) , https://h2.adamliu.net(http1.2)
源码在:https://github.com/adamliuxy/http012-speed-test
Chrome HAR 文件:https://github.com/adamliuxy/http012-speed-test/tree/master/har
为什么快了
为什么快了,我们可以从 HTTP/1.x 为什么慢来看。
影响速度的因素有两个,带宽和延时。
来源:https://hpbn.co/primer-on-latency-and-bandwidth/
网站一般是由许多小的资源文件构成,比如 JS , CSS,还有图片。这种资源文件一般就是几十几百 KB,现在家庭或者 4G 网络完全够了。每个 HTTP 请求都会是浏览器到服务器的一个网络来回(Roundtrip),如果两者之间的延时很大(比如两者距离太远),加上请求数量很多,最终效果就是网站的加载时间会很长。
所以网站要快,就要低延时!低延时!低延时!
🤫 如果你的是 SPA,请不要让你的 chunk 这么大,记得 split 一下。
HTTP/1.0
网站 https://h0.adamliu.net 需要 530 资源请求,每个请求都需要 TCP 握手建立链接。你看看 Waterfall 里面的橙色有多少。因为 http/1.0 会真的需要 530 TCP 链接,注意不是并发 530 个。HAR 文件可以在我的 Github 下载。
HTTP/1.1
还是 530 个资源请求。 但是只需要 6 个 TCP 链接(你数一数绿色的条条,这个并发请求)。也就是握手建立链接的时间少了,客户端和服务器直接的 Roundtrip 也少了。这主要归功于于 keep-alive 特性, 所以你看到 transferred 的大小会比 http/1.0 大了一点,因为 keep-alive 去要在 HTTP 头部注明。
HTTP/2
什么情况,怎么就一条线。因为只需要一个 TCP 链接!什么 TCP 握手啥的,一次就够了!不是说低延时就能快速打开网站么? 是的,一次链接一次握手就可以了。
为什么 HTTP/1.1 会是 6 个链接?
各大浏览器允许的最大同时连接数是很少的,基本都在 6 个左右。你可以在这里看具体的数量: https://stackoverflow.com/questions/985431/max-parallel-http-connections-in-a-browser
比如使用 Chrome,针对同一个域(Orign),只允许同时开启 6 个 TCP 链接(来源)。
所以我的测试网站需要 530 个请求,最大的能重用的 TCP 链接也就是 6 个。
问题来了,如果浏览器多开一些并发的 TCP 链接不就可以缩短加载时间吗?
问题是,网站资源请求和响应是严格顺序的,第一次的 index HTML 文档请求优先级是最高的,之后才会根据 DOM 的解析顺序去获取 JS, CSS, IMG(你可以使用 preload 来提升资源请求优先级)。一些浏览器已经知道要马上发送的请求,但是又没有 TCP 链接可以去使用,这些资源请求就会被 Queueing 和 Stalled(Waterfall 的白色和灰色区域)。
HTTP/1.x 有个限制是,不允许在同一连接上有来自多个 Response 的数据进行交织,每个 Response 都需要完全返回,才能去处理下一个请求的 Response。
建议看这本书的这一章,获取更清楚解析;https://hpbn.co/http1x/#using-multiple-tcp-connections
为什么使用 HTTP/2,本网站也没快多少?
因为你的网站请求数量不够多,而且可能你的网络延时本来就低。6 个 TCP 并发链接已经够处理了。
这是我测试的内容。每个协议我分别跑了三次。https://h2.adamliu.net 需要 530 个请求才能完成。这种极端情况,会体会出 HTTP/2 的效果。特别注意的是,为什么
开启 HTTP2.0(Apache)
- STEP 1: 安装模块
sudo vi /opt/bitnami/apache2/conf/httpd.conf
# uncomment this line
LoadModule http2_module modules/mod_http2.so
# restart apache
sudo /opt/bitnami/ctlscript.sh restart apache
sudo apachectl -M | grep http2
- STEP 2: 启用 HTTP2.0
https://docs.bitnami.com/aws/apps/trac/administration/enable-http2-apache/
sudo vi /opt/bitnami/apache2/conf/bitnami/bitnami.conf
# add the "Protocols" line
<VirtualHost \_default\_:80>
...
Protocols h2 h2c http/1.1
</VirtualHost>
...
<VirtualHost \_default\_:443>
...
Protocols h2 h2c http/1.1
</VirtualHost>
sudo /opt/bitnami/ctlscript.sh restart apache
IPv6
尴尬😅。我现在的网络运营商并不支持 IPv6.....
如要支持的话,我需要更新这个网站服务器的网络配置,比如配置 AWS VPC,还有就是配置 Apache 服务器,使其支持 IPv6 的地址。
完。