各種加密代理協議的簡單對比
目前我們常用的加密代理有協議有 HTTPS,SOCKS5-TLS 和 shadowsocks,此文從各個角度簡單分析各個協議的優劣,以幫助各位選擇合適的協議。
先簡單說些背景知識,以上協議都是基於 TCP 的代理協議,代理協議(Proxy Procotol)與 VPN 不同,僅可被用於通過代理伺服器轉發 TCP 連接(shadowsocks 支持代理 UDP),而 VPN 可被用於 IP 層上的所有協議,如 TCP、UDP、ICMP 等。所以在使用代理時,ping 等 ICMP 應用是不可以被代理的。
然後簡單解釋一下什麼是 TLS,TLS 又名 SSL,是針對數據流的安全傳輸協議。簡單來說,一個 TCP 鏈接,把其中原本要傳輸的數據,按照 TLS 協議去進行加密傳輸,那麼即可保證其中傳輸的數據安全。這個安全至少體現在以下幾個方面:
- 數據被加密,任何可以截取到 TCP 數據流的人,無法解密出原始數據;
- 數據不可被篡改,一旦篡改會導致解密失敗,連接斷開;
- 伺服器身份驗證,基於 X509 的證書體系去確認目標伺服器是否為真實的伺服器。
明文的 HTTP 套上一層 TLS,也就變成了 HTTPS,SOCKS5 套上 TLS,就變成了 SOCKS5-TLS。TLS 協議是整個互聯網安全的基石,幾乎所有需要安全傳輸的地方都使用了 TLS,如銀行、政府等等。
當被用作代理協議時,HTTP 層和 SOCKS5 層去進行具體的代理連接控制,如進行身份驗證、告知需要轉發的目標主機名等。所以不需要 TLS 他們也可以用作代理,只不過所有數據都是明文傳輸,不具備安全性。加上 TLS 後,由 TLS 去保證安全。而 shadowsocks 協議則融合了代理控制和安全保證。所以後文的很多對比實際上是 shadowsocks 和 TLS 的對比。
性能
TLS 協議由於承擔了一項額外的功能,需要驗證目標伺服器身份,導致其握手時會比較複雜。
ping 的時間表示,一個 IP 層數據包從本地發出,到伺服器再返回的來回時間,即 RTT(round-trip time)。
在發起代理連接時,首先我們需要進行 TCP 3 次握手,耗時為 1 個 RTT。(此處把最後的 ACK 直接併入後續的數據傳輸部分)。
然後進行 TLS 握手,因為服務端和客戶端需要進行身份驗證並協商協議版本號、加密方式等細節,第一次連接時需要 2 個 RTT。當然 TLS 的制定者也發現這太慢了,於是引入了 TLS Session Resumption,當服務端和客戶端伺服器連接過一次後,之後的連接可以直接復用先前的協商結果,使得 RTT 降低到 1 個 RTT。但這需要伺服器和客戶端的支持。(這是為什麼 Surge benchmark 時,對於 TLS 代理第一次的測試結果可能較慢的原因之一)
對於 HTTPS 協議,當 TLS 連接建立後,客戶端通過 HTTP 層發起代理請求,服務端回應連接建立,此後進入正常的代理通訊環節,再耗費 1 個 RTT。
對於 SOCKS5-TLS 協議,當 TLS 連接建立後,如果沒有驗證的環節,那麼需要再耗費 1 個 RTT,如果有驗證(用戶名密碼),那麼需要耗費 2 個 RTT。
而對於 shadowsocks,由於使用的是預共享密鑰(pre-shared key, PSK),加密方式也是預先約定好的,所以不需要進行協商,只需要在 TCP 建立之後,再耗費一個 1 個 RTT 告知目標主機名。
總結如下:
HTTPS(TLS Session Resumption):3 個 RTT
SOCKS5-TLS 無驗證:3 個 RTT
SOCKS5-TLS 有驗證:4 個 RTT
shadowsocks:2 個 RTT
(註:最後一個 RTT 並不嚴謹,因為客戶端可以在最後一個 RTT 產生響應前,直接開始後續傳輸。另外如果使用了 TCP Fast Open,可以看作 TCP 階段 RTT 為 0。)
對於日常使用,最影響性能的就是握手速度,後續傳輸過程中的加解密性能,對於現代 CPU 來說基本都不會構成瓶頸。 shadowsocks 由於有 PSK 的特點,在 TCP 協議基礎上已經達到極限,不可能有協議能再低於 2 個 RTT。
所以,同等網路環境下,shadowsocks 是明顯快於 HTTPS 的。(體現在延遲上,而不是帶寬)
另外,最新的 TLS 1.3 協議正力圖解決這個問題,由於目前還處於草案階段,各種工具鏈不完善,現在不太好評估實際效果。
數據安全性
(此處說的數據安全性,指的是加密後的流量是否會被截取並破解的問題。)
對於 TLS,作為個人用戶,絲毫不用擔心,TLS 協議如果真的不安全了,世界早就亂套了…
對於 shadowsocks,使用的加密方法也都是工業上成熟的演算法,從數據安全性角度考慮也基本不用擔心。
抗識別
這個問題有兩個角度需要考慮:
- 觀察一段數據流量,是否能判別這是一個代理協議的流量;
- 對於一個僅暴露出 TCP 埠的黑箱,能否判斷這個埠提供了代理服務。
對於 shadowsocks 協議,在第一點上,觀察者只能判定這個數據流為未知的協議。而第二點,shadowsocks 的幾次修改,都是因為在這出了問題,目前最新的 AEAD 加密方式,應該已經解決了這個問題,但還需要時間去檢驗。
對於 HTTPS 協議,在第一點上,觀察者是無法去區分這是一個代理還是一個標準的 HTTPS 網頁訪問的(當訪問 HTTP 頁面時,如果訪問 HTTPS 會使得流量模型出現特徵)。而第二點,在妥善配置的情況下,也是完全無法判別。
但在實踐中,大部分 HTTPS 代理伺服器為了兼容瀏覽器行為,在直接被當做 HTTPS Web 伺服器訪問時,會返回代理錯誤頁或者 407 Proxy authentication required,直接暴露了自己是一個代理,如果要抗擊第二點,可以將服務端的行為修改為,如果請求的 Header 中,不包含一個有效的 Auth,那麼就返回一個標準的 200 頁面,這樣從理論上杜絕了被嗅探的可能。
總結一下,最新的 shadowsocks 已經能滿足抗識別的兩個要求,但是觀察者得到結論是「未知協議」。而使用 HTTPS,觀察者無法判斷這是一個 HTTPS 代理還是 HTTPS Web 伺服器,這是更優的結果。
Hiding true identities inside a seemingly ordinary.?—?Person of Interest S03E23
部署難度
HTTPS 協議使用廣泛,有眾多成熟的工業級工具,如 squid,haproxy,nghttp2 等等,但是由於 HTTPS 協議本身比較複雜,配置起來參數眾多,有很多性能相關參數需要自己調優,所以一般用戶配置起來會有難度。
shadowsocks 經過多年發展,目前也已經有眾多的軟體支持,但是對於不同特性的支持度不一。由於參數簡單,部署配置起來極其方便。
功能
shadowsocks 目前還存在一些功能上的缺陷:
- shadowsocks 沒有設計錯誤回報機制,對於以下錯誤,客戶端看到的行為都是伺服器主動斷開 TCP 連接:
- 密鑰或者加密方法錯誤
- 目標主機名 DNS 解析失敗
- 目標主機不可達
- 目標主機拒絕連接
這使得客戶端沒辦法根據不同的錯誤採取進一步的動作,只能簡單的向用戶返回 Socket closed by remote 錯誤。
2. shadowsocks 沒有考慮用戶鑒別,使得服務端 ACL 或者流量統計等功能無法實現,主流的 workaround 是通過不同的埠號去識別不同的用戶,但這極其浪費資源且很不優雅。
3. 部分 ISP 對於非 HTTP 和 TLS 的未知流量,會進行降速限制,這個可以通過配置 obfs 解決。
推薦閱讀:
※計算機網路:分組交換
※HTTP學習小結
※計算機網路教程之物理層
※「茴」字的五種寫法
TAG:計算機網路 |