search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

全站HTTPs的那些坑

「全站HTTPs」儼然成了目前的熱門話題,很多網站都在摩拳擦掌要實行全站HTTPs。湊巧,我們(滬江)也在推行這個計劃。

一開始大家想得都很簡單,把證書購買了、配好了,相應的路徑改一改,就沒有問題。事實也確實如此,單個獨立站點的HTTPs改造是很容易的。一旦走向「全站」,才發現事情遠遠比想象的要複雜,全站意味著所有資源面對所有客戶端,涉及的因素異常多,網路上又沒有太多資料,只能自己摸索。下面我簡單講講遇到的幾個問題,提供一些經驗給大家參考。

HSTS

如果一個網站既提供了HTTP服務,又提供了HTTPs服務(在過渡期通常如此),怎樣引導用戶訪問HTTPs的站點呢?這就是HSTS(HTTP Strict Transport Security)的作用。通過Web伺服器上的設置,在收到HTTP訪問請求時,返回的header裡帶有Strict-Transport-Security欄位,告知瀏覽器必須使用HTTPs進行訪問。

但是,HSTS並不能避免首次跳轉時遇到的劫持。要徹底解決這個問題,可以申請加入Preload List(預載入列表)。

Preload List是由Google Chrome維護的「HTTPs站點列表」,Chrome, Firefox, Safari, Edge, IE 11均在使用。一旦瀏覽器發現要訪問的站點在Preload List上,默認就會發起HTTPs鏈接。這樣,就避免了HSTS的首次跳轉被劫持的隱患。

SSL卸載

通常的方案里,HTTPs的加密傳輸只限於客戶端出發的公網階段,在內網的通訊流量仍然採用非加密的HTTP傳輸。這種「把加密流量轉換為非加密流量」的過程,就是常說的SSL/TLS卸載(Offloading,以下簡稱「SSL卸載」)。

有一些公司會採用F5來做負載均衡,F5應付單純的L4和L7的流量是沒有問題的,但進行SSL卸載時性能往往會急劇降低,F5可以提供專門的加速卡來解決這個問題,但價格不便宜。所以,還需要專門環節來進行SSL卸載,常見的Nginx和HAProxy都可以執行這個任務。

2010年Intel出品的Westmere系列處理器之後,CPU支持AES-NI(Advanced Encryption Standard New Instructions)指令集,可以極大提高軟體進行SSL加解密的速度(通常的數據是5倍左右)。但是,單純採用CPU並不會直接享受這種好處,還需要對應的OpenSSL提供支持。想要知道自己的OpenSSL是否利用了AES-NI加速,可以用OpenSSL的命令行調試,加上-evp參數,測試速度是否有明顯變化即可。

# without EVP API

openssl speed aes-256-cbc

Doing aes-256 cbc for 3s on 16 size blocks: 14388425 aes-256 cbc's in 3.00s

# with EVP API

openssl speed -evp AES256

Doing aes-256-cbc for 3s on 16 size blocks: 71299827 aes-256-cbc's in 3.00s

客戶端證書

HTTP的服務是很好驗證的。一般來說,無論客戶端是瀏覽器,還是其它工具,還是程序代碼,同樣的行為,結果都是相同的。所以只要一種客戶端驗證通過,基本就可以認為這個服務是沒有問題的。HTTPs的站點則不是如此。

與HTTP不同,HTTPs的連接建立是需要進行證書驗證的,一定要從根證書開始形成完整的信任鏈條,連接才可以建立成功。然而,瀏覽器、普通工具、程序類庫,它們所信任的根證書在管理上是互相獨立的。比如,與瀏覽器不同的是,C#信任的根證書在local machine store或者current user store中,Java信任的根證書在JDK安裝目錄下的cacerts目錄中,iOS和Android的證書管理又有不同。好在廠商一般都提供了非常詳細的說明,仔細閱讀即可。

因為瀏覽器的證書在使用中又可以持續更新,用戶往往感知不到,如果「想當然」認為瀏覽器驗證通過就萬事大吉,很可能會出問題。比如國內有不少網站使用WoSign簽發的證書,但老版本的JDK並不信任WoSign的根證書,用瀏覽器瀏覽沒問題的網站,程序就會報錯,除非手動導入證書。Android的信任列表是隨固件更新而更新的,4.2以後才內置WoSign的信任。因為WoSign行為不端,前幾天Firefox, Chrome, Safari等主流瀏覽器又取消了對它的信任,也就意味著WoSign證書有安全風險,所以已經內置WoSign根證書的程序也應當做對應的設置。

伺服器端證書

還是上面的現象:用瀏覽器驗證沒有問題的HTTPs站點,用程序訪問就有問題。這是為什麼?

在伺服器上證書配置錯誤,只有最終證書,而缺少中級證書的情況,我見過幾次了。通常,最終證書里包含了中級證書相關的信息,所以如果缺少中級證書,瀏覽器為了建立證書鏈,會做一次耗時的操作來獲取中級證書,而且這一切都發生在HTTPs連接真正建立之前。更糟糕的是,不少瀏覽器為了「表現更好」,會想辦法繞過這個問題。所以缺少中級證書的情況一直存在,一直不會被發現,而程序調用的速度總是上不去,甚至有一定幾率報錯(我就遇到過這個詭異的問題)。

如果把證書鏈配置完全,還要注意證書鏈的大小。有一些網站的完整證書異乎尋常地大,達到若干kb甚至幾十kb,也就是說,在建立連接之前,就必須先傳輸這麼多的數據。如果做單純的PC網頁瀏覽,或許不會有問題。但對於移動端和程序調用來說,這就是一場災難。最好的辦法,是用OpenSSL配合WireShark之類的工具,自己動手來測試。如果你熟悉TCP相關的知識,往往可以得到更好的優化方案。

OCSP和CRL也不可忽略。這兩項技術用來保證撤回證書(讓證書失效)的有效性。如果你仔細觀察,會發現證書里都指定了對應的OCSP或者CRL的URL,用來檢查證書是否失效。按道理說,在每次建立HTTPs連接時,都應當進行OCSP或CRL檢查。返回結果通常在1k左右,如果請求非常頻繁,這個因素也應當考慮。

SNI

大家都熟悉「虛擬主機」的概念,它可以讓多個域名對應到同一個IP,讓同一台伺服器服務多個站點。在HTTP時代,可以在header中通過host來指定需要訪問的域名,一切看起來都那麼完美。

但是在HTTPs時代,卻沒有這樣的好事,傳統的HTTPs服務很難讓多個域名對應到同一個IP。在進行到HTTP通訊之前,必須先建立驗證證書建立連接。如果一個IP上綁定了多個域名,這個階段伺服器根本沒法知道請求對應的是哪個域名,無疑會造成極大的不便。

為了解決這種問題,SNI(Server Name Identification)應運而生了。這種技術說起來複雜,大家可以把它簡單理解為「建立SSL/TLS通訊時的host header」,這樣就解決了一個IP只能配單張證書的問題。

然而SNI的誕生歷史並不長,許多客戶端的支持都存在奇怪的問題。比如JDK7支持SNI,但是JDK8的支持又有bug。而且這種支持往往需要調用原生的API才可以實現,Resteasy之類的類庫並不支持。如果對SNI的支持有問題,即便配置正確也可能無法建立連接,因為服務端並不能識別此請求需要的證書。

CDN

CDN已經是業界流行的技術了,對稍微大一點的網站來說,沒有CDN幾乎是不可想象的。HTTP時代的CDN方案相當成熟,HTTPs的情況則不是如此。

要使用HTTPs的CDN服務,就要決定是否將證書交給CDN提供商。基於目前的商業信譽水平,把證書交給CDN提供商的風險不可不考慮。惡意揣測,別有用心的人一旦拿到證書,可以很方便地通過DNS劫持發起中間人攻擊,而完全不被感知到。

另外,HTTP時代大家都喜歡將資源分散到多個不同的域名,因為建立連接的成本很低,而同一個域名的併發連接數有限。在HTTPs環境下,每次建立連接的成本高了很多,頻繁下載和驗證證書對移動設備和移動網路影響很大(尤其是證書很大的情況)。如果域名非常分散,影響就更加顯著。所以在HTTPs時代,把域名收縮集中反而是更好的辦法。

內容及其它

因為HTTPs的內容中無法引用HTTP的資源,所以應當保證網頁中資源文件的鏈接都是HTTPs的。遺留的許多系統很可能並不注意這些事情,資源都採用絕對地址的形式,這樣改起來工作量很大。如果要修改,最好一步到位,直接改成「協議相對URL」。

絕對地址URL:http://www.a.com/b.css

協議相對URL://www.a.com/b.css

這樣瀏覽器就可以根據當前的協議,自動生成資源的絕對地址,無論是HTTP還是HTTPs,都可以自由切換。

如果資源都是自有的,切換HTTPs就相對容易。如果存在外部,尤其是UGC的資源,切換到HTTPs就很麻煩。如果是超鏈接,通常採用專門的跳轉服務,也就是下面這樣:

https://link.my.com/target=www.you.com

如果是圖片這類資源,可以設定專門的程序將其抓取過來存放在自己的伺服器上,再將地址替換掉即可。但是,這樣做很可能要自己承擔流量壓力,同時還要承擔惡意程序攻擊的風險。

如果是視頻、遊戲等富文本、交互複雜的資源,如果源站沒有提供HTTPs的服務,多半只能忍痛割愛,放棄內嵌展現的形式了。

最後再補充兩點經驗:

如果真的決定上HTTPs,最好有個人把OpenSSL玩熟,否則很多問題會讓你摸不著頭腦,OpenSSL是很好的調試工具,很方便定位問題。

HTTPs能解決運營商內容劫持的問題,如果是DNS劫持,要不要抱著「吾與汝偕亡」的態度上HTTPs,需要慎重考慮,我知道不少網站是HTTP與HTTPs可以隨時切換的,進可攻,退可守。



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦