雲計算

一次HTTPS訪問慢的案例分析

問題描述

用戶反饋一個通過CDN加速的CSS資源,訪問速度很慢,測試在PC上訪問超過了3秒。

Netwrok-Timing分析

Chrome復現了一下問題,通過Network下的Timing信息分析這一次慢請求主要耗時在哪個時間點。通過以下圖可以明顯看到,這一次請求總耗時3.05s,但是有3.02s是耗時在了SSL握手上。

image.png

抓包分析

我們知道HTTPS請求,在完成TCP三次握手以後,需要通過TLS協議來完成SSL握手,那麼這次SSL握手的時間為什麼耗時這麼久呢?於是抓了一個異常包,根據CDN節點IP過濾了一下交互報文,具體如下圖。
image.png

通過這個報文可以看到#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
image.png

OCSP校驗超時

通過了解證書校驗機制以後可以得知,這個問題有可能是慢在證書校驗這一塊。過濾了一下DNS報文,可以看到客戶端確實有OCSP Server域名ocsp.int-x3.letsencrypt.org的DNS查詢請求,該域名CNAME解析到了a771.dscq.akamai.net,最終解析到的IP是157.240.20.8
image.png
image.png

過濾了客戶端跟OCSP Server端的交互包,發現客戶端發起TCP三次握手,發送SYN包以後Server端未響應,客戶端超時1秒以後繼續發送SYN包,發送了三次均無響應,客戶端證書校驗失敗,這個3秒剛好跟目前的耗時情況吻合。
image.png

通過一些探測網站,在國內探測了一下這個OCSP Server的地址確實表現也不是很好,大部分地區均無法訪問,看來這個問題收到運營商鏈路問題的影響。
image.png

問題發生的完整過程

通過以上排查分析,總結一下這個問題發生的完整過程:
客戶端發起一次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購買付費證書,詳細請戳這裡

Leave a Reply

Your email address will not be published. Required fields are marked *