本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《
阿里云开发者社区用户服务协议
》和
《
阿里云开发者社区知识产权保护指引
》。如果您发现本社区中有涉嫌抄袭的内容,填写
侵权投诉表单
进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
用户反馈一个通过CDN加速的CSS资源,访问速度很慢,测试在PC上访问超过了3秒。
Netwrok-Timing分析
Chrome复现了一下问题,通过Network下的Timing信息分析这一次慢请求主要耗时在哪个时间点。通过以下图可以明显看到,这一次请求总耗时3.05s,但是有3.02s是耗时在了SSL握手上。
我们知道HTTPS请求,在完成TCP三次握手以后,需要通过TLS协议来完成SSL握手,那么这次SSL握手的时间为什么耗时这么久呢?于是抓了一个异常包,根据CDN节点IP过滤了一下交互报文,具体如下图。
通过这个报文可以看到#944号报文Server端响应了Server Hello Done,返回了证书信息给客户端,客户端响应ACK以后在#947号报文更新TCP Window滑动窗口,然后在#1291报文才继续发Client Key Exchange给Server端。从#947号包到#1291包,时间也从20:02:39到了20:02:42,耗时了3秒左右。从现象来看,这个耗时主要是"卡"在客户端这了,那么客户端这个时间到底干啥去了呢?
证书校验机制
要解释上面问题,还需要知道证书校验的机制。对于一个可信任的 CA 机构颁发的有效证书,在证书到期之前,只要 CA 没有把其吊销,那么这个证书就是有效可信任的。有时,由于某些特殊原因(比如私钥泄漏,证书信息有误,CA 有漏洞被黑客利用,颁发了其他域名的证书等等),需要吊销某些证书。那浏览器或者客户端如何知道当前使用的证书已经被吊销了呢,通常有两种方式:CRL(Certificate Revocation List,证书吊销列表)和 OCSP(Online Certificate Status Protocol,在线证书状态协议)。
(1)CRL:CRL 是由 CA 机构维护的一个列表,列表中包含已经被吊销的证书序列号和吊销时间。浏览器可以定期去下载这个列表用于校验证书是否已被吊销。可以看出,CRL 只会越来越大,而且当一个证书刚被吊销后,浏览器在更新 CRL 之前还是会信任这个证书的,实时性较差。在每个证书的详细信息中,都可以找到对应颁发机构的 CRL 地址。
(2)OCSP:OCSP 是一个在线证书查询接口,它建立一个可实时响应的机制,让浏览器可以实时查询每一张证书的有效性,解决了 CRL 的实时性问题,但是 OCSP 也引入了一个性能问题,某些客户端会在 SSL 握手时去实时查询 OCSP 接口,并在得到结果前会阻塞后续流程,这对性能影响很大,严重影响用户体验。(OCSP 地址也在证书的详细信息中)
通过浏览器上点击安全锁的小图标,可以看到证书的详细信息,如下图,我们可以看到几个关键信息
证书签发者:Let's Encrypt Authority X3
OCSP_ServerURL:
http://ocsp.int-x3.letsencrypt.org
OCSP校验超时
通过了解证书校验机制以后可以得知,这个问题有可能是慢在证书校验这一块。过滤了一下DNS报文,可以看到客户端确实有OCSP Server域名ocsp.int-x3.letsencrypt.org的DNS查询请求,该域名CNAME解析到了a771.dscq.akamai.net,最终解析到的IP是157.240.20.8
过滤了客户端跟OCSP Server端的交互包,发现客户端发起TCP三次握手,发送SYN包以后Server端未响应,客户端超时1秒以后继续发送SYN包,发送了三次均无响应,客户端证书校验失败,这个3秒刚好跟目前的耗时情况吻合。
通过一些探测网站,在国内探测了一下这个OCSP Server的地址确实表现也不是很好,大部分地区均无法访问,看来这个问题收到运营商链路问题的影响。
问题发生的完整过程
通过以上排查分析,总结一下这个问题发生的完整过程:
客户端发起一次HTTPS请求,在SSL握手的过程中,CDN服务端将证书信息发给了客户端,客户端根据证书信息,发起在线证书查询来校验证书合法性,但是由于证书校验服务地址不可达导致证书校验失败,客户端间隔一秒继续重试2次均失败,耗时3秒以后客户端停止校验,继续完成后续的SSL握手,造成最终访问慢的现象。
OCSP的原理决定了其存在隐私和性能问题
(1)浏览器直接去请求第三方CA(Certificate Authority, 数字证书认证机构),会暴露网站的访客(CA 机构会知道哪些用户在访问我们的网站);
(2)浏览器进行OCSP查询会降低HTTPS性能(访问网站会变慢) OCSP实时查询会增加客户端的性能开销, 本案例就是这种情况。
针对这种情况,OCSP Stapling 出现了。OCSP Stapling可以将原本需要客户端实时发起的 OCSP 请求转嫁给服务端,Web端将主动获取 OCSP 查询结果,并随证书一起发送给客户端,以此让客户端跳过自己去寻求验证的过程,提高 TLS握手效率,从而提高HTTPS性能。阿里云CDN也支持OCSP Stapling功能,可以由CDN服务器查询OCSP信息,从而降低客户端验证请求延迟,减少等待查询结果的响应时间。具体配置方法和原理介绍可以参考
设置OCSP Stapling
。
不过本案例中,验证过开启CDN的OCSP Stapling功能也无法解决,主要的问题是OCSP Server端在国内访问整体质量均不佳,主要是由于跨境链路和运营商的问题造成的,因此导致CDN去请求OCSP 一样质量不佳。对于这种情况,如果是直接访问的Nginx,可以通过一些方式生成OCSP Stapling 文件部署到Nginx中(这里不展开介绍)。如果是通过CDN等代理服务器方式,由于不能单独配置OCSP Stapling 文件,最好的方式还是更换证书来解决。
使用阿里云CDN的情况下,可以直接使用阿里云CDN的免费证书,或者到阿里云SSL证书服务里去申请免费证书or购买付费证书,详细请戳
这里
。