HTTPS 的作用是在會話層、表示層引入 TLS/SSL 握手協議,通過數據加密、解密方式,來應對數據明文傳輸過程中遇到的問題,保障數據的完整性、一致性,為用戶帶來更安全的網絡體驗、更好的隱私保護。
然而,HTTPS 增加了 TLS/SSL 握手環節,再加上應用數據傳輸需要經過對稱加密,對性能提出了更大的挑戰。
作為一個好的架構,一定要均衡安全和性能兩方面,如果讓天秤向任何一方傾斜過多,都會影響最終的用戶體驗。
因此,為了兼顧安全與性能,蘇寧的全站 HTTPS 改造從 2015 年底開始進行,歷時一年多時間,主要做了系統 HTTPS 改造、HTTPS 性能優化和 HTTPS 灰度上線這三方面工作,讓用戶在 HTTPS 下訪問能夠獲得極致體驗成為了可能。
全站 HTTPS 方案概述
蘇寧易購從 2015 年開始規劃做 HTTPS 相關的事情,當時可借鑒的資料非常少,電商類網站相關的 HTTPS 改造的詳盡案例更是難求。
如下圖,是蘇寧易購全站的 HTTPS 方案:
如圖中所示,整個方案分三步構建,分別是系統改造、性能優化和灰度上線:
系統改造。原有系統想要支持 HTTPS,必須進行改造,首先要建立 HTTPS 接入層,也就是開通 443 端口,讓所有的應用系統支持 HTTPS 訪問。
在此基礎上做頁面資源替換,解決當一個 HTTPS 頁面出現 HTTP 請求時就會出現錯誤的問題。做完這兩件事,CDN 上證書的處理、HTTPS 測試方案等問題也就迎刃而解。
性能優化。做系統改造,增加兩次 TLS 握手,必然會對性能造成一定的開銷和損失,如何去彌補性能的損失,達到性能和安全兼顧呢?性能優化部分包含若干優化點,下文會詳細展開。
灰度上線。唐山網站建設這部分是時間花費最多的,HTTPS 一步步上線的過程中,踩坑最多,其中部分是前面沒有發現的問題。
這證明不能一次性將整個全站、全地區、全用戶一次性堆成 HTTPS,可以根據流量所處的運營商和城市及用戶級別去做灰度上線。
HTTPS 方案之系統改造篇
01、HTTPS 接入層定義
系統改造的頭等大事是開通 443 端口,成熟的網絡系統會包含 CDN、硬件負載均衡、應用防火墻、Web 服務器、應用服務器,最后到數據層。難道整個鏈路都要做 HTTPS?在每層都增加 SSL 握手消耗嗎?答案是否定的。
所以,應該盡早完成 SSL 握手,做 SSL 過程中首要考慮的是 HTTPS 接入層的定位。
如下圖,是蘇寧易購架構中 HTTPS 接入層的位置:
如圖中所示,我們把 HTTPS 接入層放在 CDN 和應用系統之間,采用四層+七層負載均衡的架構。
四層負載并不處理 HTTPS 卸載,它的主要職責是做 TCP 的分發。在七層負載完成整個 SSL 握手,而后面應用系統走 80 端口,這樣就相當于完成了 HTTPS 整個卸載的過程。
這樣做的好處,一方面,系統應用層面不需要為 HTTPS 做任何調整;另一方面,將來所有 HTTPS 的調度、優化和配置都可以在接入層完成。
02、頁面資源替換
第一步,理解 Mixed Content
對于一個頁面而言,請求頁面的請求是用 HTTPS 加載,一旦內部頁面元素有 HTTP 的性質,這時 RFC 標準里就會出現一個錯誤,叫 Mixed Content(混淆錯誤)。
所以,如果要加載一個安全的 HTTPS 頁面,就不應該在其中混淆 HTTP 請求。
第二步,// 替換 http://
用 // 替換 http://,這樣就可以讓頁面所有的元素做一個適配,去遵循原來的請求。
第三步,x-request-url 的定義和使用
當然,我們在//替換過程中也遇到了一些坑。舉個例子,下圖是蘇寧易購單點登錄系統交互的過程:
如圖中所示,當用戶 authID 失效,發起請求 https://xxx.suning.com/authStatus 鑒權,接入層會對所有請求做卸載,地址就會變成 HTTP。
進入業務系統做鑒權的話,Reponse 302 就會跳轉到單點登錄系統。這時會將第二步的頁面記錄為原始頁面,返回到用戶端,用戶去請求單點登錄系統,單點登錄系統完成鑒權以后,再回跳時,是 HTTP 地址,最終導致用戶端 MixContent。
因此,我們引入 x-request-url 解決問題,如下圖:
所有原始請求協議都記錄在 x-request-url 中,如果業務系統鑒權,一定要遵循 x-request-url 記錄的協議,就可應對回跳導致的用戶端 Mix Content 問題。