如何做到兼顧安全與性能?電商網站HTTPS優化探索與實踐
原創【51CTO.com原創稿件】眾所周知,數據HTTP明文傳輸過程中,會遇到如劫持、篡改、監聽、竊取等一系列問題,解決這一問題的方法就是做HTTPS改造。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方案之系統改造篇
HTTPS接入層定義
系統改造的頭等大事是開通443端口,成熟的網絡系統會包含CDN、硬件負載均衡、應用防火墻、Web服務器、應用服務器,最后到數據層。難道整個鏈路都要做HTTPS?在每層都增加SSL握手消耗嗎?答案是否定的。
所以,應該盡早完成SSL握手,做SSL過程中首要考慮的是HTTPS接入層的定位。
如下圖,是蘇寧易購架構中HTTPS接入層的位置
如圖中所示,我們把HTTPS接入層放在CDN和應用系統之間,采用四層+七層負載均衡的架構。四層負載并不處理HTTPS卸載,它的主要職責是做TCP的分發。在七層負載完成整個SSL握手,而后面應用系統走80 端口,這樣就相當于完成了HTTPS整個卸載的過程。
這樣做的好處,一方面,系統應用層面不需要為HTTPS做任何調整;另一方面,將來所有HTTPS的調度、優化和配置都可以在接入層完成。
頁面資源替換
第一步,理解Mixed Content
對于一個頁面而言,請求頁面的請求是用HTTPS加載,一旦內部頁面元素有HTTP的性質,這時RFC標準里就會出現一個錯誤,叫Mixed Content(混淆錯誤)。所以,如果要加載一個安全的HTTPS頁面,就不應該在其中混淆HTTP請求。
第二步,//替換http://
用//替換http://,這樣就可以讓頁面所有的元素做一個適配,去遵循原來的請求。
第三步,x-request-url的定義和使用
當然,我們在//替換過程中也遇到了一些坑。舉個例子,下圖是蘇寧易購單點登錄系統交互的過程:
如圖中所示,當用戶authID失效,發起請求https://xxx.suning.com/authStatus鑒權,接入層會對所有請求做卸載,地址就會變成HTTP 。進入業務系統做鑒權的話,Reponse 302就會跳轉到單點登錄系統。這時會將第二步的頁面記錄為原始頁面,返回到用戶端,用戶去請求單點登錄系統,單點登錄系統完成鑒權以后,再回跳時,是HTTP地址,最終導致用戶端Mix Content。
因此,我們引入x-request-url解決問題,如下圖:
所有原始請求協議都記錄在x-request-url中,如果業務系統鑒權,一定要遵循x-request-url記錄的協議,就可應對回跳導致的用戶端Mix Content問題。
App原生無法識別//的問題
出現瀏覽器可以識別//,但 App原生無法識別//的原因很簡單,因為瀏覽器本身做了適配。
當時,蘇寧服務端有一個系統,專門提供一個接口,向各個端提供圖片。做完HTTPS改造之后,PC端和客戶端都沒有問題。但是第二天,很多用戶突然就不能加載圖片,原因是請求在APP原生情況下沒法識別//。
這里的解決方法,只能是客戶端開發人員做適配,下圖是App無法識別//的一個例子
如何處理商用CDN上的證書和私鑰?
CPN證書的處理是大多數小型互聯網企業都會遇到的問題。因為這些小企業不像阿里、京東可自建CDN,蘇寧也是一樣。蘇寧的CDN由自建和商用兩種組成,一旦使用商用CDN,就會面臨HTTPS如何過去的問題。企業只要將私鑰給到第三方或廠商之后,在所有廠商的CDN服務器都沒辦法控制。當有黑客攻擊完廠商服務器后,加密已沒任何意義,因為私鑰已經泄露。
如下圖,業界比較公認的應對方式分別是:雙證書的策略、四層加速和Keyless解決方案。
- 雙證書的策略。它的思想很簡單,相當于用戶到CDN端,提供的是CDN的證書,做加解密。從CDN到應用服務器端用的是應用自有的證書來做加解密。這樣的方式,可以保證應用端的密鑰不用提供給CDN廠商,但根本的問題還是沒有解決,那就是CDN廠商的證書仍然有泄露的可能。如果泄露了,用戶端還是會受到影響。
- 四層加速。很多CDN廠商都有能力提供TCP加速,做動態、還原和擇優等。CDN廠商只做四層模式和TCP代理,不考慮請求緩存,這樣就沒必要將證書暴露給CDN廠商,這樣的方式適用于動態回源請求,比如加入購物車、提交訂單、登錄等。
- Keyless解決方案。適用于金融,提供一臺實時計算的 Key Server 。
當CDN 要用到私鑰時,通過加密通道將必要的參數傳給 Key Server,由 Key Server 算出結果并返回即可。
HTTPS測試策略
當引入一個新的協議,如何進行測試呢?主要步驟,如下圖:
- 源碼掃描。當開發人員完成資源替換后,利用Jenkins遍歷代碼庫,shell腳本掃描出HTTP鏈接。
- 對頁面爬蟲掃描。我們會寫一些爬蟲腳本,對測試環境的鏈接進行掃描。
- 測試環境驗證。自動化測試固然好,但是主要核心流程還是需要手動覆蓋一遍,防止HTTPS對頁面加載出現未知影響。如有些頁面是用HTTPS去訪問,可能這個系統還不支持HTTPS,必須要手動驗證。
- 線上預發和引流測試。HTTPS的改造版本發到線上對用戶來講是沒有影響的,因為用戶使用的還是HTTP流量??梢赃x擇線上預發的方式,預發驗證完畢后,通過301的方式,將用戶的流量從HTTP切到HTTPS,這個后面講灰度時還會深入講。
另外,我們還引入了引流測試系統: 它的思路很簡單,根據域名、用戶請求做捕獲,將所有捕獲流量放到Copy Server中去擴大,放大若干倍,然后通過Sender再發送回到系統中。這樣的方式,可以通過用戶的真實流量,來驗證HTTPS的功能性和性能影響有多大。
HTTPS方案之性能優化篇
談如何優化HTTPS的性能之前,我們先來看看整個TLS握手流程,如下圖:
如圖中所示,一個握手過程最壞的情況下,要分為八個步驟:
- 發送Syn包到Web客戶端,收到并確認后,同時發送SynAck到服務器,這時還是一個HTTP的請求。
- HTTP轉換HTTPS,需要做一次302或者301跳轉。
- 用戶再次發送HTTPS請求,做一次TCP握手。
- 做TLS完全握手第一階段,Client hello到Server hello。
- 當證書首次到客戶端,客戶端需要走驗證流程,做CA域名解析。
- 第二次,TLS握手。
- 在線證書合法性校驗的過程。
- TLS完全握手第二階段,底部灰色部分才是真正的數據通訊。
蘇寧易購的全站HTTPS方案在性能優化方面做了很多事情,如HSTS、Session resume、Ocsp stapling的合理使用,如客戶端HTTPS性能、HttpDNS 解決 DNS攻擊劫持等優化。
HSTS的合理使用
Web安全協議HSTS的作用是強制客戶端(如瀏覽器)使用HTTPS與服務器創建連接。
優點是減少HTTP做302跳轉的開銷。302跳轉不僅暴露了用戶的訪問站點,也很容易被中間者劫持(降級劫持、中間人攻擊),最重要是降低了訪問速度(影響性能)。
缺點是HSTS在max-age過期時間內,在客戶端是強制HTTPS的,服務端無法控制。因此,當需要降級時,HTTPS無法及時切換到HTTP。當然你也可以通過手動動態去配置maxage的值,這樣可以通過將maxage設置為0來達到降級效果。還有HSTS是嚴格的HTTPS,一旦網絡證書錯誤時,網頁將直接無法訪問(用戶無法選擇忽視)。
Session resume的合理使用
當用戶端和客戶端、客戶端和服務端完成第一次TLS握手之后,第二次數據傳輸還需要TLS握手嗎?這里可以采用Session復用的方式。Session resume(會話復用),是RFC標準中早就定好的一個機制,HTTPS最初發布時就已經涉及其中。
Session復用有Session ID和Session tickets兩種方式,下圖是實現流程:
Session ID。使用 client hello 中的 session ID查詢服務端的 session cache, 如果服務端有對應的緩存,則直接使用已有的 session 信息提前完成握手,稱為簡化握手。Session ID 是 TLS 協議的標準字段,市面上的瀏覽器全部都支持 Session ID。需要注意的是,單機多進程間共享ssl session對集群環境是沒有意義的。因此,在這里需要實現多機共享Session ID。可以放在redis中,nginx提供了專門處理Session ID的模塊ssl_session_fetch_by_lua_block。
Session tickets。Session tickets是會話ID的一種補充,server 將 session 信息加密成 ticket 發送給瀏覽器,瀏覽器在后續握手請求時會發送 ticket,server 端如果能成功解密和處理 ticket,就能完成簡化握手。顯然,session ticket 的優點是不需要服務端消耗大量資源來存儲 session 內容。但是session ticket 只是 TLS 協議的一個擴展特性,目前的支持率不是很廣泛,只有 60% 左右,還需要維護一個全局的 key 來加解密,需要考慮 KEY 的安全性和部署效率。
Ocsp stapling的合理使用
Ocsp 全稱在線證書狀態檢查協議 (rfc6960),用來向 CA 站點查詢證書狀態,比如證書是否被撤銷,是否已經過期等。通常情況下,瀏覽器使用 OCSP 協議發起查詢請求,CA 返回證書狀態內容,然后瀏覽器接受證書是否可信的狀態。
如下圖,是Ocsp實現流程:
這個過程非常消耗時間,因為 CA 站點有可能在國外,導致網絡不穩定,RTT 也比較大。那有沒有辦法不直接向 CA 站點請求 OCSP 內容呢?
ocsp stapling 就能實現這個功能。ocsp stapling的原理簡單來說是服務端代替客戶端完成CA校驗證書的過程,節省用戶端的時間開銷。就是當瀏覽器發起 client hello 時會攜帶一個 certificate status request 的擴展,服務端看到這個擴展后將 OCSP 內容直接返回給瀏覽器,完成證書狀態檢查。
由于瀏覽器不需要直接向 CA 站點查詢證書狀態,這個功能對訪問速度的提升非常明顯。
HTTPS方案之灰度上線篇
灰度上線可遵循灰度、降級和開閉三大原則?;叶仍瓌t是指整個上線過程要按區域、版本、用戶等級來進行灰度,通過灰度收集上來的用戶數據來決定整個計劃的進行。降級原則保證每一步的操作都是可逆可回滾的,即對擴展開放,對修改關閉,這是可復用設計的基石。
HTTPS開關控制
HTTPS開關控制方面,蘇寧主要建設內容管理、CDN、客戶端三大開關:
- 內容管理開關。內容管理開關的作用是保證所有運營維護的鏈接都可以被替換。
- CDN開關。每個頁面,從HTTP到HTTPS都需要做301跳轉,這些跳轉都配置在CDN中。
- 客戶端開關。就是移動加速SDK的開關。
上線過程中遇到的新問題
做完開關控制,在正式上線的過程中,又遇到了一些新問題如:Referrer、DNS劫持、HTTPS性能監控等。
Referrer
目前大部分瀏覽器,在發生協議降級時默認不發送Referrer 信息,最典型的場景就是從HTTPS 頁面點鏈接跳到HTTP 網站時,瀏覽器并不會在請求頭中帶上Referer 字段。當Referrer帶不過去,對大數據的影響非常大,因為沒辦法追溯流量來源。
針對現代的瀏覽器,這個問題可以通過給頁面加上meta 標簽來解決:<meta name="referrer" content="always" />
DNS劫持
DNS劫持是指非法破壞域名的解析過程導致請求被解析到一個錯誤節點以達到某些惡意目的。當我們使用HTTP時,DNS異??赡苓€不會影響請求的功能性,但HTTPS因為非法節點沒有證書和私鑰,肯定是無法響應了。
蘇寧的做法的是通過一些波測監控DNS的正常,如下圖,我們監測到蘇寧中華特色館在某個地區有大量DNS解析異常。
出現DNS劫持,對用戶影響很大,一旦出現一次頁面打不開,用戶就會認為這個頁面有問題,不會在進行二次訪問。
如下圖,是蘇寧易購河北地區出現的問題:
如圖中所示,頁面整個框架都在,但就是沒有圖片,最終確定是由DNS劫持導致的。
這里的應對方法就是要建立完整的風控體系,在全國各地建設波測節點,做整個請求圖片、頁面的記錄,并保存,如下圖:
當時,河北地區用戶發出請求后,TCP沒有辦法建立連接,使用SSL無法握手。原因是DNS劫持,被映射到非法的錯誤節點上了。應對方法還是我剛才說的降級手段,通過IP
判斷是河北移動的用戶就對HTTPS進行降級成HTTP,其他地方還繼續使用HTTPS策略。待當地運營商解決問題之后,再進行恢復。
HTTPS性能監控
如下圖,是蘇寧易購移動端的監控頁面:
HTTPS灰度最重要的一個是做好監控,必須要有一個監控覆蓋,要做好灰度,每一步上線時都要分析一下業務、性能、站內站外投放,CPS等數據。一切數據分析都正常之后,再逐步擴大區域,按APP的版本和用戶級別進行部署。
HTTPS未來展望篇
這里分享一個基于UDP的低時延的互聯網傳輸層協議:QUIC(Quick UDP Internet Connection)。TCP/IP協議族是互聯網的基礎。這個UDP協議由谷歌提出,其用意是替代TCP協議。這兩種協議,UDP更為輕量,錯誤校驗也要少得多,但可靠性方面要弱于TCP。目前,針對QUIC協議,國外一些公司在試用階段,強調的是既保證安全,又能保證握手不會對原來的傳輸造成影響,這也許是未來的發展方向。
【作者簡介】
朱羿全,蘇寧云商IT總部架構師,先后參與了全景應用性能監控平臺搭建、移動端性能優化與提升、移動端統一接入層建設等工作,主導了蘇寧易購全站HTTPS上線和優化工作。專注于應用層網絡性能優化,在HTTPS、HTTP/2等領域擁有豐富的經驗,目標是通過優化,以保證復雜網絡環境下,通信的快速、穩定和安全。
以上內容根據朱羿全老師在 WOTA2017 “電商大促背后的技術挑戰”專場的演講內容整理。
由于篇幅問題,一些加密套件、SPDY&HTTP/2、HTTP/2 壓測工具、SSL硬件加速卡等合理使用,沒有在文中一一分享,更詳細內容請見:視頻 & PPT
本月熱文推薦TOP3
【51CTO原創稿件,合作站點轉載請注明原文作者和出處為51CTO.com】