1、HTTPS性能优化
1.1 HTTPS性能损耗原因
前文讨论了HTTPS原理与优势:身份验证、信息加密与完整性校验等,且未对TCP和HTTP协议做任何修改。但通过增加新协议以实现更安全的通信必然需要付出代价,HTTPS协议的性能损耗主要体现如下:
1、增加延时
分析前面的握手过程,一次完整的握手至少需要两端依次来回两次通信,至少增加延时2* RTT,利用会话缓存从而复用连接,延时也至少1* RTT*。
2、消耗较多的CPU资源
除数据传输之外,HTTPS通信主要包括对对称加解密、非对称加解密(服务器主要采用私钥解密数据);压测 TS8 机型的单核 CPU:对称加密算法AES-CBC-256 吞吐量 600Mbps,非对称 RSA 私钥解密200次/s。不考虑其它软件层面的开销,10G 网卡为对称加密需要消耗 CPU 约17核,24核CPU最多接入 HTTPS 连接 4800;
静态节点当前10G 网卡的 TS8 机型的 HTTP 单机接入能力约为10w/s,如果将所有的HTTP连接变为HTTPS连接,则明显RSA的解密最先成为瓶颈。因此,RSA的解密能力是当前困扰HTTPS接入的主要难题。
1.2 HTTPS接入优化
1、CDN接入
HTTPS 增加的延时主要是传输延时 RTT,RTT 的特点是节点越近延时越小,CDN 天然离用户最近,因此选择使用 CDN 作为 HTTPS 接入的入口,将能够极大减少接入延时。CDN 节点通过和业务服务器维持长连接、会话复用和链路质量优化等可控方法,极大减少 HTTPS 带来的延时。
2、会话缓存
虽然前文提到 HTTPS 即使采用会话缓存也要至少1*RTT的延时,但是至少延时已经减少为原来的一半,明显的延时优化;同时,基于会话缓存建立的 HTTPS 连接不需要服务器使用RSA私钥解密获取 Pre-master 信息,可以省去CPU 的消耗。如果业务访问连接集中,缓存命中率高,则HTTPS的接入能力讲明显提升。当前TRP平台的缓存命中率高峰时期大于30%,10k/s的接入资源实际可以承载13k/的接入,收效非常可观。
3、硬件加速
为接入服务器安装专用的SSL硬件加速卡,作用类似 GPU,释放 CPU,能够具有更高的 HTTPS 接入能力且不影响业务程序的。测试某硬件加速卡单卡可以提供35k的解密能力,相当于175核 CPU,至少相当于7台24核的服务器,考虑到接入服务器其它程序的开销,一张硬件卡可以实现接近10台服务器的接入能力。
4、远程解密
本地接入消耗过多的 CPU 资源,浪费了网卡和硬盘等资源,考虑将最消耗 CPU 资源的RSA解密计算任务转移到其它服务器,如此则可以充分发挥服务器的接入能力,充分利用带宽与网卡资源。远程解密服务器可以选择 CPU 负载较低的机器充当,实现机器资源复用,也可以是专门优化的高计算性能的服务器。当前也是 CDN 用于大规模HTTPS接入的解决方案之一。
5、SPDY/HTTP2
前面的方法分别从减少传输延时和单机负载的方法提高HTTPS 接入性能,但是方法都基于不改变HTTP 协议的基础上提出的优化方法,SPDY/HTTP2 利用TLS/SSL 带来的优势,通过修改协议的方法来提升HTTPS 的性能,提高下载速度等。
1.3 来源JD老司机HTTPS优化指南
1.3.1 优化1:TLS Record Size 动态调整
TLS Record 协议工作在表示层,在传输层和应用层之间提供诸如数据封包,加解密,HMAC 校验等功能,如下图:
Nginx 在建立 TLS 连接时会为每个连接分配 Buffer 用于发送原数据(TLS Record Size,默认16KB),当服务端发送数据时,数据会被切分成 16KB 的多个块,每个块用 MAC 签名,加上协议的元数据以及被加密后的原数据形成一个 TLS Record 结构发送到客户端,在客户端只有当协议栈接收到完整的 TLS Record 时才能够解密验证,才会向应用层提交。
由于 16KB 的包大小以及丢包等因素的影响,相对于 TCP,HTTPS 的 TTFB( Time To First Byte ) 延时较大。
TTFB 是判断网站性能的重要指标,主流浏览器都是边下载边解析渲染的,延时较大最直观的影响就是最终用户在浏览器端看到内容的速度较慢。
当然 TLS Record Size 也不能一味地变小,比如当它等于 MSS 时,变小就会有较大的头部负担,导致整体吞吐量下降。
我们当前使用的是 TLS Record Size动态调整 算法,随着 CWND 从 Initcwnd 增长到 16K,在延时和吞吐量之间达到相对平衡。
实现思路方式: 开发动态调整工具。
1.3.2 优化2: False Start
通过启用 False Start,客户端可以在 Change Cipher Spec 和 Finished 报文后立即发送应用数据,使得原本需要两次 RTT 的完全握手变更为一次 RTT。
国内南北网络的平均延时是 50ms,这也就意味着每一个地处南方的用户访问地处北方的站点,人均可节省 50ms,效果显著。
根据 RFC7918 文档,只有使用具有前向安全的秘钥交换算法以及足够强度的对称加解密算法时 False Start 才会启动。
需要注意的是,Chrome 浏览器为了解决一些特殊 SSL 服务如 SSL Terminator 硬件设备的不兼容性,要求只有和支持 NPN/ALPN 的服务端通信才会开启 False Start。
NPN 随着 SPDY 被 HTTP/2 代替已被 Chrome 移除,而 ALPN 只在 Openssl-1.0.2 后才开始支持,加之 Openssl 新版本的 Bug 修复以及性能优化,所以如果有条件建议在服务端部署较新版本的 Openssl。
实现思路与方式:
Nginx配置如下:
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
1.3.3 优化3: OCSP Stapling
OCSP 设计之初是 CRL(Certificate Revocation List) 的替代品,希望通过在线实时的网络交互检查证书吊销状态,但是这个功能有点鸡肋:
- 暴露用户隐私,Https 旨在提高安全性和保护隐私,OCSP 显得有点背道而驰
- OCSP Responder 基本在国外,而且服务能力未知,假设访问 OCSP Responder 的延时很大,或者是客户端和 OCSP Responder 的链路主动或被动地断开,客户端无法很好地确定是否应该接受证书。
OCSP Stapling 通过服务端对 OCSP 结果的预取并把结果随着证书一起发给客户端,从而绕过客户端的在线验证过程,可以很好地解决上边两个问题。
我们在自己的网站中都应该配置使用 OCSP Stapling,但是需要注意的是 OCSP Stapling 也并非完全能起到检查证书吊销的作用,以至于像 Chrome 浏览器就已经完全不做证书吊销检查了。
实现思路与方式:
Nginx实现配置:
ssl_stapling on;
ssl_stapling_verify on;
resolver 223.5.5.5 223.6.6.6 valid=300s;
resolver_timeout 5s;
1.3.4 优化4: HSTS
HSTS(HTTP Strict Transport Security)通过在 HTTPS Response Header 中携带 Strict-Transport-Security 来告知浏览器:以后请直接通过 HTTPS 访问我,当第二次用户在浏览器端访问 HTTP 站点,浏览器会在内部做 307 重定向,直接通过 HTTPS 访问。如下图:
通过 HSTS 能有效地避免 SSL 剥离攻击,并能减少 2 个 RTT,强烈建议配置使用。但同时也需关注首次访问的中间人攻击,以及准备回滚措施以防 HTTPS 回滚。
实现思路与方式:
Nginx实现:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY";
参考资料: http://www.ttlsa.com/nginx/http-hsts-nginx/, http://www.ttlsa.com/web/hsts-for-nginx-apache-lighttpd/
1.3.5 优化5: 会话复用
常见的会话复用有 Session ID 和 Session Ticket 两种形式,其中 Session ID 是 TLS 协议的标准字段,而 Ticket 是扩展字段,根据相关统计,Ticket 的客户端支持率只有 40% 左右。
通过会话复用,把完全握手变更为简单握手,避免最耗时的秘钥协商阶段,能显著提升性能,如下图,客户端在发起连接时携带上一次完全握手时服务端返回的 SessionID,服务端收到后在内存中查找缓存的会话信息并恢复加密通信。
但是原生 Nginx 只实现了单机版本的会话复用(SSL_SESSION_CACHE 关键字),而当前我们都习惯以集群方式部署 Nginx 来达到高可用,所以我们通过新增 Nginx 模块以及对 Nginx 源码的少量改造,支持分布式会话复用,如下图,无论请求落到哪一台 Nginx 机器,都可以复用已缓存的会话信息。
该 Nginx 模块(ngx_ssl_session_cache_module)
已经开源,支持 Redis 和 Memcached 两种分布式缓存系统,且对 Openssl 没有任何代码依赖,欢迎使用,详见:
传送门:https://github.com/hzarch/ngx_ssl_session_cache_module.git
实现思路与方式:
简单的Nginx实现:
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
1.3.6 优化6: 双证书
256 位 ECC 秘钥加密强度等同于 3072 位 RSA 秘钥水平且性能更高,而且秘钥更短意味着更少的存储空间,更低的带宽占用,所以对于有条件的企业建议开启 ECC & RSA 双证书支持。
对比 ECDHE_RSA、ECDHE_ECDSA 秘钥交换认证算法所需的 RSA_SIGN、ECDSA_SIGN 算法,以下是我们在普通工作站上通过 OPENSSL SPEED 测试的性能数据,可以明显看到 ECDSA_SIGN 性能提升。
实现思路与方式:
参考资料: https://www.zeroling.com/nginx-kai-qi-https-shuang-zheng-shu-zhi-nan/
1.3.7 优化7: 对称加密优化
AES-GCM 是目前常用的分组加密算法,缺点是性能低以及移动端耗电量大,所以谷歌在 2014 年推出了一种新的流式加密算法 CHACHA20-POLY1350,在 ARM 平台上性能是 AES-GCM 的 3-4 倍。
Intel 从 Westmere 处理器开始支持一种新的 x86 指令扩展集 AES-NI,AES-NI 能从硬件上加速 AES 的性能,在支持 AES-NI 指令集的主机上实测 AES-GCM 性能是 CHACHA20 的 5 倍左右。
原先我们为权衡兼容性和安全性,所以参考 Mozilla 的推荐
(https://wiki.mozilla.org/Security/Server_Side_TLS)
默认采用中档配置,该配置假设客户端不支持 AES-NI,所以 CHACHA20 优先于 AES-GCM,然而随着底层技术的发展,移动端从 ARMV8-A 架构开始逐渐支持 AES 指令集。
像常用的 IPhone 5S,Galaxy Note 4(Exynos),红米 2,锤子 T2,荣耀 5X 等都是基于的 ARMV8 架构,考虑到当前互联网企业的用户都以年轻群体为主,所以我们改变策略优先使用 AES-GCM。
实现思路与方式:
对称加密是有客户端发起,所以对于BS架构,暂无配置资料。
1.3.8 优化8: HTTP/2
HTTP/2 是 HTTP/1.1 在 1999 年发布后的首次更新,HTTP/2 带来了诸如多路复用、头部压缩、二进制分帧等特性,能大幅提升 Web 性能。
使用时可以让客户端选择或通过 NPN/ALPN 动态协商是采用 HTTP/1.X over TLS 还是 HTTP/2 over TLS,而且后端服务无需修改代码进行适配,具有比较大的灵活性。
但是也需要注意HTTP/2 并不是万能的解药,使用时需对网站本身的情况做充分评估,需规避诸如为HTTP/1.X 调优而提出的域名散列等问题。
1.3.9 优化9: 加速卡
以上所有的优化都是 软加速 范畴,主要目的是减少 RTT,但是对于无法避免的完全握手,服务端还是会进行大量的加解密运算,以 ECDHE_RSA 为例,像 RSA_Sign 函数在 Intel E5-2650 V2 主机上每秒只能执行 1.2W 次左右,而此时 24 个核已全是满载状态。
CPU 向来都不适合处理大规模的浮点运算,解决这类问题性价比最高的方式无疑是采用硬件加速卡(GPU 就是其中一种),通过把加解密运算转移到加速卡来替换 Openssl 的加解密处理。
加速卡安装在主机的 PCIE 插槽内,受限于主机 PCIE 插槽数量,支持线性扩容,根据加速卡类型不同,像 RSA_Sign 计算性能在单卡状态下都能提升 3-6 倍左右。
实现思路与方式:
硬件加速,云上无法实现。
1.3.10 优化10: 优化注释
由于无法优化浏览器端代码,当前延时只能优化到一个 RTT,若客户端私有,可参考 TLS V1.3开发 0-RTT协议。
1.3.11 优化11: 算法分离
利用软优化以及硬件加速卡,基本能满足大部分的业务场景,但这却不是最优解,我们发现:
不同厂家不同型号的加速卡存在性能差异,同型号的加速卡不同算法也存在性能差异,像我们测试的一款 Cavium 卡,ECDHP256 和 RSA2048_Sign 存在 20% 的性能差距
Openssl-1.0.2 版本实现了更快速以及更安全的 EC_GFp_nistz256_method 方法用于 P256 曲线操作,该方法利用了 Intel AVX 扩展,性能提升显著。
在老旧的 Intel E5-2620 主机测试 Openssl-1.0.2 单核 ECDH 性能达到 8040,4 倍于 Openssl-1.0.1u,24 核全开时性能达到 9.7W,在 E5-2650 V2 上,极限性能更是达到 17.5W,远高于加速卡单卡的 5-8W。
正是由于这种差异性,我们提出算法分离的架构,希望充分利用硬件性能。
如上图,通过这种架构我们把接入集群从 CPU 密集型 转换成 IO 密集型,具体的算法运算,私钥存储等都在专有集群完成,极大地增强了接入集群的可扩展性。
另外通过这种架构我们不仅可以充分利用闲置的计算资源,也可以最优化 HTTPS 卸载服务的吞吐率,而且对于计算集群的增删改,我们支持在 Web 管控端上批量修改,卸载服务会实时拉取并应用修改,此外再辅以计算集群的整体监控,极大地简化了运维复杂度。
2、Https调优压测
任何压力都无法完全模拟线上正常环境,随此处仅供参考。
环境说明:
IP | 配置 | 带宽 | 域名 | 网站类型 | 服务器坐标 |
---|---|---|---|---|---|
120.76.121.45 | 1核2G | 1M | ssl.saevan.com | 纯静态html | 广东省深圳市 |
办公网环境: 坐标青岛,电信联通双线。
压测软件: AB
原网站ab吞吐.
[root@evan-node-1 ~]# ab -n100 -c20 http://ssl.saevan.com/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking ssl.saevan.com (be patient).....done
Server Software: EWS/2.2.23
Server Hostname: ssl.saevan.com
Server Port: 80
Document Path: /
Document Length: 14091 bytes
Concurrency Level: 20 `
Time taken for tests: 14.422 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 1432500 bytes
HTML transferred: 1409100 bytes
Requests per second: 6.93 [#/sec] (mean)
Time per request: 2884.332 [ms] (mean)
Time per request: 144.217 [ms] (mean, across all concurrent requests)
Transfer rate: 97.00 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 42 46 2.9 45 60
Processing: 97 2658 1938.3 1910 12252
Waiting: 43 59 77.7 46 641
Total: 145 2703 1938.7 1961 12302
Percentage of the requests served within a certain time (ms)
50% 1961
66% 2883
75% 3339
80% 4162
90% 5345
95% 6364
98% 8385
99% 12302
100% 12302 (longest request)
配置RSA证书后,未进行优化结果:
[root@evan-node-1 ~]# ab -n100 -c20 https://ssl.saevan.com/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking ssl.saevan.com (be patient).....done
Server Software: EWS/2.2.23
Server Hostname: ssl.saevan.com
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256
Document Path: /
Document Length: 14091 bytes
Concurrency Level: 20
Time taken for tests: 18.004 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 1432500 bytes
HTML transferred: 1409100 bytes
Requests per second: 5.55 [#/sec] (mean)
Time per request: 3600.891 [ms] (mean)
Time per request: 180.045 [ms] (mean, across all concurrent requests)
Transfer rate: 77.70 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 142 602 585.7 403 3993
Processing: 378 2493 2099.5 1854 10143
Waiting: 374 2493 2099.7 1854 10143
Total: 520 3095 2173.7 2448 11135
Percentage of the requests served within a certain time (ms)
50% 2448
66% 3007
75% 3786
80% 4304
90% 5531
95% 9210
98% 10532
99% 11135
100% 11135 (longest request)
优化Https后:
优化选项有:False Start、OCSP Stapling、HSTS、会话复用;
[root@evan-node-1 ~]# ab -n100 -c20 https://ssl.saevan.com/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking ssl.saevan.com (be patient).....done
Server Software: EWS/2.2.23
Server Hostname: ssl.saevan.com
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES128-GCM-SHA256,2048,128
Document Path: /
Document Length: 14091 bytes
Concurrency Level: 20
Time taken for tests: 17.801 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 1441200 bytes
HTML transferred: 1409100 bytes
Requests per second: 5.62 [#/sec] (mean)
Time per request: 3560.120 [ms] (mean)
Time per request: 178.006 [ms] (mean, across all concurrent requests)
Transfer rate: 79.07 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 138 440 395.2 382 2155
Processing: 91 2742 2360.6 2000 15302
Waiting: 89 2742 2360.6 2000 15302
Total: 231 3182 2409.8 2468 15457
Percentage of the requests served within a certain time (ms)
50% 2468
66% 3082
75% 3453
80% 4480
90% 7026
95% 8385
98% 9550
99% 15457
100% 15457 (longest request)
最终第三方对于SSL配置优化的评分
3、CA证书类型
3.1 SSL证书类型
基础级SSL证书(域名型DV SSL) ,即只对域名的所有者(一般是域名管理员邮箱,比如admin@hotmail.com)进行在线检查,发送验证邮件给域名管理员或以该域名结尾的邮箱,至于该域名的管理员是真实注册的单位还是另有其人,不得而知了。
专业级SSL证书(IV SSL),会对域名所有权和证书申请人的真实身份进行验证的专业级SSL证书 适用于个人专业网站。
企业级 SSL 证书(OV SSL) ,是要购买者提交组织机构资料和单位授权信等在官方注册的凭证,认证机构在签发SSL证书前不仅仅要检验域名所有权,还必须对这些资料的真实合法性进行多方查验,只有通过验证的才能颁发SSL证书。
SSL 证书(EV SSL) ,与其他SSL证书一样,都是基于SSL/TLS安全协议,都是用于网站的身份验证和信息在网上的传输加密。它跟普通SSL证书的区别也是明显的,安全浏览器的地址栏变绿,如果是不受信的SSL证书则拒绝显示,如果是钓鱼网站,地址栏则会变成红色,以警示用户。
3.2 常用证书加密算法
ECC:参考资料: https://www.wosign点com/ecc/,主要用于移动端
RSA:就是我们常用的证书类型
4、总结
如今,全世界都对HTTPS抛出了橄榄枝:
a)微信小程序要求所有的请求必须是 HTTPS 请求
b)苹果要求所有 IOS App 2016 年底强制使用 HTTPS 加密,虽然该计划暂时被延期
c)百度、谷歌优先收录 HTTPS 站点,相同权值的站点 HTTPS 排名靠前
d)Chrome 浏览器对 HTTP 页面提出警告,如下图,当前为中性警告,即默认情况下只有当 HTTP 页面检测到密码或信用卡字段时才会提示不安全,但同时 Chrome 也明确表示,该计划将会越来越严格,最终会对所有 HTTP 页面提示不安全。
通过目前软优化无法最根本解决压力问题,但以目前现状,我们还没有升级到压力问题,通过基础GET压测,并未有大幅度明显性能下降(一切测试都不能完全模拟整个生产环境),所需根据需求先上迭代,是现在增加HTTPS的一个好的渠道。