爱奇艺海外版HTTPS效率提升的探索和实践

视频内容类的业务对延迟比较敏感,而在海外运营场景下,这种延迟敏感更为突出,爱奇艺海外版项目在初期技术要求就是秒开,除了 CDN、边缘节点的部署外,海外后端团更是对 HTTPS 的请求做过一系列的优化,现总结之前工作中的一些技术性探索和优化,分享给大家。

01

   背景

为什么要在移动端花费这么多精力?

移动端因为设备性质以及网络环境因素等,导致新链接、以及链接复用问题放大。

bb697c2387d9e46f866fee61907653f3.png

HTTPS 请求花费的时间?

一个全新的 HTTPS 链接,从发起请求到数据返回经过几个 RTT?假设没有任何缓存,一个 HTTPS 请求得经过 10 个 RTT 才能返回内容。

一个 RTT 如果是 50ms,这个全新的请求至少花费 50*10=500ms。这还没有算后端业务处理的时间。HTTPS 请求延迟确实比较高。

a75880f0b77cb3fde4bf5e1d71776dcb.png

通常情况下业务 HTTP 的延迟容忍度较差,Server To Client 的模式,效率总归是越高越好。

现实情况会有各种缓存,减少不必要的消耗,所以很少发生上面这种极端的 10 个 RTT 情况。

  • DNS 有本地缓存或者用了 HTTPDNS 预解析,第1步可以省掉。

  • 如果浏览器声明了 HSTS ,可以省略 302 转向,第3步可以省掉。

  • 如果本地已经有主流的 CA DNS 缓存  第6步可以省掉

  • 如果 CA 本地有验证缓存或者启用 OCSP Stapling 的本地验证 7、8步可以省掉

在有各类缓存情况下,一个常规的 HTTPS 请求会保留下面 4 个 RTT 流程。

0388755527d9e46d224d3e14626c423a.png

除了 HTTPS 内容请求外,握手的阶段或者 TLS 层是否还可以再继续优化一下,让我们的 APP 或者视频播放再快那么一点?答案:肯定是的!

对于 HTTP 这种协议,我们可以从这几方面入手:提升加解密效率、减少内容传输量、链接复用...

01bf4e46ea132bf288c8e740b1c5563a.png

02

  HTTPS流程分析和优化的策略

使用 WireShark 抓包, 根据 TCP 包,我们画了下面流程图,一步步分析流程,并确定中间可优化的点。(TLS1.2 协议 ECDHE 算法)

125ef7f23a637f1502fa219c0b0a4b05.png

整个流程有以下几个阶段:

  • TLS Hello 确定协议版本、密码套件、对称密钥随机数

  • Server Certificate  服务器发送证书链

  • Client/Server Key Exchange (DH 算法,协商交换加密算法)

  • ChangeCipher Spec 对称加密双向校验

TLS Hello阶段的分析与应用

先看看 Clienthello 的几个主要的参数

struct
hello {
Version // TLS版本号
Random // 客户端随机数
Session id
Cipher Suites // 客户端支持的加密套件
Extension: support version; // 扩展TLS版本支持
}

上面的抓包 Version 是 TLS1.2,扩展中带有 TLS1.3。如果服务端支持 1.3 ,将改为 1.3 协议。

服务端先要进行对应的支持配置,如下。

 
 
ssl_protocols  TLSv1.2 TLSv1.3

Cipher Suites 是个数组,会包含新旧一堆加密算法支持,优先级从上到下。

服务端 Server Hello 返回 Cipher Suite,根据 Client 的请求匹配一个合适的加密套件。如下服务器返回支持的套件。

 
 
Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA256

上面什么意思?握手时对称加密参数交换使用 RSA。通信加密使用 256 位长度对称 AES 算法,GCM 和 SHA256 是 AES 的分组模式和摘要算法。

这个阶段优化的几个思路:

密钥交换算法改进:RSA 可以改为 DH 类算法(Diffie-Hellman),如 ECDHE。在同等复杂度下,计算效率更高,证书体积也更小。

优化 ECDHE 算法实现,优先选择效率最高的椭圆曲线实现 x25519。在 Nginx 后台使用 ssl_ecdh_curve 配置椭圆曲线优先级。

 
 
ssl_ecdh_curve X25519:secp384r1;

同时 ECDHE 支持 False Start。

启用了 False Start,在 Client 发送完 ChangeCipher Spec 就可以发送加密的应用数据,减少1个 RTT 等待时间。

服务端配置 Cipher Suites 的优先级。把性能最高的算法放在前面。

ssl_prefer_server_ciphers on; 
ssl_ciphers EECDH+ECDSA+AES128+SHA:RSA+AES128+SHA...

尽管 AES 的效率很高,但在一些安全性没那么高的业务下,AES 密钥的长度可以小一些,256位改为128位。

Server Certificate阶段

Certificate 阶段会将自身公钥和证书CA中间公钥发给客户端。本地验证证书合法后继续 Client Key Exchange 流程。在这个阶段,有两个方向可以优化:证书传输+证书验证。

证书传输

证书的大小当然越小越好,在生成证书阶段选择 ECDSA,而不是 RSA 证书,安全不变的条件下,密钥长度更小,运算量也更小。

比如用类似下面生成 ECDSA 证书

 
 
openssl ecparam -genkey -name prime256v1 -out key.pem

证书验证

客户端在验证证书时,会走证书链逐级验证,而且为了知道证书是否被 CA 吊销,客户端会访问 CA 下载 OCSP 数据,确认证书是否有效。

OCSP 需要向 CA 查询,因此也是要发生网络请求,如果CA服务器的延迟过大,会导致客户端在校验证书这一环节的延时变大。

OCSP Stapling

为了解决证书有效性验证的问题,出现了 OCSP Stapling。

服务器向 CA 周期性地查询证书状态,获得一个带有时间戳和签名的响应并缓存,当客户端来请求证书,在 TLS 握手阶段,服务器将该结果给客户端。

因为结果带有 CA 私钥的签名,所有结果可信,客户端在本地就可以判断证书的有效性。

b58cdfb3111ff8bf91bfc02f75f1357e.png

在Nginx中开启OCSP Stapling

ssl_stapling  on;
ssl_stapling_verify  on;
ssl_trusted_certificate    xx.pem

使用以下命令测试服务器是否开启 ocspstaping

openssl s_client -connect ip:443 -status
OCSP response: no response sent //出现以下 则没配置

密钥交换和验证的阶段

Client/ServerKey Exchange 阶段

在这一阶段主要是交换 DH 加密公钥,如选定椭圆曲线,生成椭圆曲线公钥,公钥签名,与客户端的 ClientKey Exchange 呼应,最终获取对方的公钥,用来加密 AES 的密钥。

加解密双方验证

Change Cipher Spec/Encrypted Handshake Message

在 Key Change 阶段,加密的参数均已生成,双方有了交换密钥的公钥,也有对称密钥的参数。可以进行数据传输了

如果双方都验证加密和解密没问题,那么握手正式完成。于是,就可以正常收发加密的 HTTP 请求和响应了。

以上两个阶段是否可以优化?是的,我们可以采用链接复用的方式跳过该阶段。

链接复用优化

复用有两个方式:SessionID SessionTicket,实现不同但目标一致。(一个服务端实现,一个客户端实现)

  • SessionID

客户端和服务器首次 TLS 握手连接后,双方会在内存缓存会话密钥,并用唯一的 Session ID 来标识。在下一次链接时,服务端可以知道一个进来的连接是否在之前已经建立过连接,如果在服务器中也存在这个 session 的 key,那么它就能重用。

在服务端开启 SessionID

ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
  • SessionTicket

为了解决 Session ID 的问题,就出现了 Session Ticket,服务器不再缓存每个客户端的会话密钥,而是把缓存的工作交给了客户端,类似于 HTTP 的 Cookie。

客户端与服务器首次建立连接时,服务器会加密「会话密钥」作为 Ticket 发给客户端,交给客户端缓存该 Ticket。

客户端再次连接服务器时,客户端会发送 Ticket,服务器解密后就可以获取上一次的会话密钥,然后验证有效期,如果没问题,就可以恢复会话了。

在服务端开启 Session ticket

 
 
ssl_session_tickets on;ssl_session_ticket_key xx.key;

用了链接重用技术,当再次重连 HTTPS 时,只需要 1 RTT 就可以恢复会话。对于 TLS1.3 使用 Pre-shared Key 重用技术,可以实现 0RTT 恢复链接。

采用链接重用,当然不可避免的产生重放攻击风险。

对于安全性要求非常高的业务要慎重的使用链接重用, 当然如果衡量好重用过期时间,同时业务端做好安全防范,获得的收益也不会小。

03

  总结

从 HTTP/1.0 到 HTTP/2,HTTP 协议基础一直是可靠连接 TCP。TCP 的对头阻塞、握手流程等机制问题,导致无论如何优化,HTTP 延迟始终过高。

另外 TCP 协议作为互联网最为广泛应用的协议之一,涉及无数的中间设备、操作系统,协议僵化问题导致 IETF 标准化制定的许多 TCP 新特性难以执行。

所以下一阶段的 HTTP/3 完全放弃了 TCP,经历七年之久。从 QUIC 被提交给 IETF 进行标准化,QUIC 协议的 HTTP/3 在今年终于正式发布。

基于 QUIC 更能简单的实现 0-RTT,1-RTT 的连接建立,爱奇艺海外也早早开始尝试使用 QUIC 改善用户服务,后续技术团队也将基于数据分享我们使用 QUIC 的实践。最后,不论阻碍如何,HTTP/3 的时代已经到来,让我们拭目以待。

d16a68b7e6267c547e8df69189025a23.jpeg

也许你还想看

爱奇艺海外App的网络优化实践

猎户座-持续打造爱奇艺海外高扩展性的策略引擎项目

一切数据皆可配置:爱奇艺海外站的运营后台设计实践

1319d0a29dc762a236235f19c308b50b.gif 关注我们,更多精彩内容陪伴你!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值