今年 6 月,维基媒体基金会发布公告,旗下所有网站将默认开启 HTTPS ,这些网站中最为人所知的当然是全球最大的在线百科-维基百科。而更早时候的 3 月,百度已经发布公告,百度全站默认开启 HTTPS 。淘宝也默默做了全站 HTTPS 。
网站实现 HTTPS ,在国外已经非常普及,也是必然的趋势。 Google 、 Facebook 、 Twitter 等巨头公司早已经实现全站 HTTPS ,而且为鼓励全球网站的 HTTPS 实现, Google 甚至调整了搜索引擎算法,让采用 HTTPS 的网站在搜索中排名更靠前。但是在国内, HTTPS 网站进展并不好,大部分的电商网站也仅仅是对账户登录和交易做 HTTPS ,比如京东;很多网站甚至连登录页面也没有实现 HTTPS …这里面有很多的原因,比如现有架构改动的代价过大、 CDN 实现困难、对用户隐私和安全的不重视等。
还有个重要原因是担心网站实现 HTTPS 后,网站的用户体验和性能下降明显。事实上,通过合理部署和优化, HTTPS 网站的访问速度和性能基本不会受到影响。
一、什么是 HTTPS 网站?
在介绍 HTTPS 网站前,首先简单介绍什么是 HTTPS 。
HTTPS 可以理解为 HTTP+TLS , HTTP 是互联网中使用最为广泛的协议,目前不部分的 WEB 应用和网站都是使用 HTTP 协议传输。主流版本是 HTTP1.1 , HTTP2.0 还未正式普及, 2.0 由 Google 的 SPDY 协议演化而来,在性能上有明显的提升。
TLS 是传输层加密协议,是 HTTPS 安全的核心,其前身是 SSL ,主流版本有 SSL3.0 、 TLS1.0 、 TLS1.1 、 TLS1.2 。 SSL3.0 和 TLS1.0 由于存在安全漏洞,已经很少被使用到。
那网站为什么要实现 HTTPS ?
一言概之,为保护用户隐私和网络安全。通过数据加密、校验数据完整性和身份认证三种机制来保障安全。
由于本文的重点是 HTTPS 网站的性能加速,对于 HTTPS 通信过程和加解密算法就不展开介绍了。
感兴趣的同学可以 Google 之,基础都是一样的。
二、 HTTPS 网站的直观了解
推荐一个在线版全球知名的 HTTPS 网站检测工具-SSL Labs 。 Qualys SSL Labs 同时也是很具有影响力的 SSL 安全和性能研究机构。在线检测地址为: https://www.ssllabs.com/ssltest/。
SSL Labs 会对 HTTPS 网站的证书链、安全性、性能、协议细节进行全面检测,检测完毕后会进行打分,同时给出一份详细的检测报告和改进建议。
三、提高 HTTPS 网站性能和访问速度
如果你认为网站加上 TLS 证书,就是 HTTPS 网站了,那你就跟 12306 犯了同样的错误……
首先,网站在加上 TLS 证书时,为什么会变慢?这主要又两方面造成:
HTTPS 比 HTTP 在通信时会产生更多的通信过程,随之 RTT 时间就会增加;
HTTPS 通信过程的非对称和对称加解密计算会产生更多的服务器性能和时间上的消耗。
但是,每个 HTTPS 网站其实都有着巨大的优化空间。下面我们结合 WildDog 网站,来看看 QPS 值从 30000 到 80000 ,加载时延从 800ms 到 300ms ,这中间的每个优化点是怎样的。
HSTS
HTTPS 网站通常的做法是对 HTTP 的访问在服务器端做 302 跳转,跳转到 HTTPS 。但这个 302 跳转存在两个问题:
使用不安全的 HTTP 协议进行通信;
增加一个 Round-Trip Time 。
而 HSTS 是 HTTP Strict Transport Security 的缩写,服务器端配置支持 HSTS 后,会在给浏览器返回的 HTTP Header 中携带 HSTS 字段,浏览器在获取到该信息后,在接下来的一段时间内,对该网站的所有 HTTP 访问,浏览器都将请求在内部做 307 跳转到 HTTPS ,而无需任何网络过程。
Session Resume
Session Resume 即会话复用,这提升 HTTPS 网站性能最基础也是最有效的方法。
在 HTTPS 握手阶段,对服务器性能消耗最为严重的是非对称密钥交换计算,而 Session Resume 通过对已经建立 TLS 会话的合理复用,节省非对称密钥交换计算次数,可大幅提高服务器的 TLS 性能。
TLS 协议提供两种实现机制 Session Resume ,分别是 Session cache 和 Session ticket 。
Session Cache
Session Cache 的原理是使用 Session ID 查询服务器上的 session cache ,如果命中,则直接使用缓存信息。但 Session Cache 有个明显的缺点,它不支持分布式缓存,只支持单机进程间的共享缓存。这对于多个接入节点的架构很难适用。
Session ticket
Session ticket 的原理是服务器降 session 信息加密成 ticket 发送给浏览器,浏览器后续进行 TLS 握手时,会发送 ticket ,如果服务器能够解密和处理该 ticket ,则可以复用 session 。
Session ticket 可以很好的解决分布式问题,但 Session ticket 的支持率还不是很高,而且需要考虑服务器上 key 的安全性方案。
OCSP Stapling
在 HTTPS 通信过程时,浏览器会去验证服务器端下发的证书链是否已经被撤销。验证的方法有两种: CRL 和 OCSP 。
CRL 是证书撤销列表, CA 机构会维护并定期更新 CRL 列表,但这个机制存在不足:
1.CRL 列表只会越来越大;
2.如果浏览器更新不及时,会造成误判。
OCSP 是实时证书在线验证协议,是对 CRL 机制的弥补,通过 OCSP 浏览器可以实时的向 CA 机构验证证书。但 OCSP 同样存在不足:
对 CA 机构要求过高,要求实时全球高可用;
客户端的访问隐私会在 CA 机构被泄露;
增加浏览器的握手时延。
而 OCSP Stapling 是对 OCSP 缺陷的弥补,服务器可事先模拟浏览器对证书链进行验证,并将带有 CA 机构签名的 OCSP 响应保存到本地,然后在握手阶段,将 OCSP 响应和证书链一起下发给浏览器,省去浏览器的在线验证过程。
SPDY 和 HTTP2.0
SPDY 是 Google 推出的优化 HTTP 传输效率的协议,采用多路复用方式,能将多个 HTTP 请求在同一个连接上一起发出去,对 HTTP 通信效率提升明显。 HTTP2.0 是 IETF 2015 年 2 月份通过的 HTTP 下一代协议,它以 SPDY 为原型。 SPDY 和 HTTP2 目前的实现默认使用 HTTPS 协议。
Nginx stable 版本当前只能支持到 SPDY3.1 ,但最新发布的 1.9.5 版本通过打 patch 的方式,可以支持 HTTP2.0 ,这绝对是不一样的奇妙体验。不过不建议直接在线上环境部署,等到 2015 年年底吧, Nginx 会发布 Stable 版本支持 HTTP2.0.
TCP 优化
因为 TCP 是 HTTPS 的承载, TCP 的性能提升,上层业务都可以受益。
慢启动是 TCP 规范中很重要的算法,其目的是为避免网络拥塞。通过客户端和服务器之间的数据交换,从一个很保守的初始拥塞窗口值,收敛到双方都认可的可用带宽。当客户端和服务器收敛到一定带宽时,如果一段时间内,双方没有收发数据包,服务器端的拥塞窗口会被重置为初始拥塞窗口值。这对于连接中的突发数据传输性能影响是很严重的。
在没有充足的理由时,服务器端需要禁用空闲后的慢启动机制。
另外,当前浏览器和服务器之间的可用带宽已经相对较大,所以我们还应该将初始的拥塞窗口值扩大,新的 RFC 中的建议是 10 , Google 是 16 。
TLS Record Size
服务器在建立 TLS 连接时,会为每个连接分配 Buffer ,这个 Buffer 叫 TLS Record Size 。这个 Size 是可调。
Size 值如果过小,头部负载比重就会过大,最高可达 6%。
Size 值如果过大,那单个 Record 在 TCP 层会被分成多个包发送。浏览器必须等待这些全部达到后,才能解密,一旦出现丢包、拥塞、重传、甚至重新建立的情况,时延就会被相应增加。
那 TLS Record Size 值如何选择呢?有两个参数可参考。
首先, TLS Record Size 要大于证书链和 OCSP Stapling 响应大小,证书链不会分成多个 record ;
其次,要小于初始拥塞窗口值,保证服务器在通信之初可以发送足够数据而不需要等待浏览器确认
一般来说,从根 CA 机构申请的证书为 2-3KB 左右,级数越多,证书链越大, ocsp 响应为 2KB 左右,所以 TLS Record Size 是需要根据你的实际情况设置, Google 的值 5KB 。 WildDog 当前的值是 6KB 。
证书链完整且不冗余
浏览器在验证服务器下发的证书链时,不仅仅验证网站证书。如果是多级证书,网站证书和根证书之间所有的中间证书都需要被验证。一旦出现证书链出现不完整,浏览器就会暂停握手过程,自行到因特网进行验证,这个时间基本是不可估算的。
至于怎么查看,通过 openssl 命令查看,也可以通过 SSL Labs 帮你在线检测。
移动设备上的 ChaCha20-Poly1305
去年的时候,谷歌已经在 Android 的 Chrome 浏览器上增加支持一个新的 TLS 加密套件,这个加密套件就是 ChaCha20-Poly1305 。它的设计者是伊利诺伊大学的教授和研究员 Dan BernsteinChaCha20 被用来加密, Poly1305 被用来消息认证,两个操作都需要运行于 TLS 上。
当前流行的加密套件 AES-GCM 在 TLS 1.2 支持,它是不安全 RC4 和 AES-CBC 加密套件的替代品。但是,在不支持硬件 AES 的设备上会引起性能问题,如大部分的智能手机、平板电脑、可穿戴设备。
ChaCha20-Poly1305 正式为解决这个问题而生。以下是 Google 的相关测试数据,在使用 Snapdragon S4 Pro 处理器的 Nexus 4 或其他手机中, AES-GSM 的加密吞吐量是 41.5MB/s ,而 ChaCha20-Poly1305 是 130.9MB/s 。在使用 OMAP 4460 的老的 Galaxy Nexus 手机上, AES-GSM 的吞吐量是 24.1MB/s ,而 ChaCha20-Poly1305 是 75.3MB/s 。
当前, OpenSSL 1.0.2 的分支上已经开始支持 ChaCha20-Poly1305 ,而对 ChaCha20-Poly1305 支持最好的当属 BoringSSL 。通过重新对 Nginx 的 SSL 库编译,可以支持到 ChaCha20-Poly1305 ,不过对于线上环境,建议看明白源码再使用。
除此之外,还有不少优化的细节,如硬件加速、 False Start 、禁用 TLS 压缩等等,这里就不扒了。
如果觉得这篇文章有帮助,就请收藏或者分享一下,希望可以帮到更多人。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.