HTTP 代理在企業中有著應泛的應用。但 HTTP 代理信令是明文傳輸的,非常不利於商業秘密和個人隱私的保護。本文介紹一種使用 TLS 技術對 HTTP 實行加密保護的方法。

對於明文 HTTP 請求,代理通信的流程如下:

Agent Proxy Site
| | |
| <1> tcp dial to proxy:8080 | |
|<--------------------------->| |
| <2> GET / HTTP/1.1 | |
| Host: baidu.com | <3> tcp dial to baidu.com:80 |
|---------------------------->|<---------------------------->|
| | <4> GET / HTTP/1.1 |
| | Host: baidu.com |
| |----------------------------->|
| | <5> HTTP/1.1 200 OK |
| <4> HTTP/1.1 200 OK |<-----------------------------|
|<----------------------------| |
| | |

  • <1> 客戶端同代理伺服器建立 TCP 連接
  • <2> 客戶端將 HTTP 請求發送給代理伺服器
  • <3> 代理伺服器解析 HTTP 請求,獲取目標伺服器地址並建立 TCP 連接
  • <4> 代理伺服器將客戶端 HTTP 請求發送給目標伺服器
  • <5> 目標服器將響應內容發送給代理伺服器
  • <6> 代理伺服器將目標伺服器的響應內容發送給客戶端

如是你要訪問 HTTPS 站點,則需遵循另外一套流程:

Agent Proxy Site
| | |
| <1> tcp dial to proxy:8080 | |
|<--------------------------->| |
| <2> CONNECT baidu.com:443 | |
|---------------------------->| <3> tcp dial to baidu.com:443|
| <4> HTTP/1.1 200 OK |<---------------------------->|
|<----------------------------| |
| | |
| https data | https data |
|<--------------------------->|<---------------------------->|
| | |

  • <1> 客戶端同代理伺服器建立 TCP 連接
  • <2> 客戶端向發送給代理伺服器發送 CONNECT 請求
  • <3> 代理伺服器解析 HTTP 請求,獲取目標伺服器地址並建立 TCP 連接
  • <4> 代理伺服器向客戶端發送 Connection Established 響應(圖中標為 OK)

接下來代理伺服器會不斷將客戶端發來數據轉發給目標伺服器,並把目標伺服器的發來的數據轉發給客戶端。

那為什麼 HTTP 請求和 HTTPS 請求的代理通信流程不一樣呢?因為對於明文的 HTTP 請求,代理伺服器可以通過解析請求內容獲取目標伺服器的域名和埠,進而發起 TCP 連接。可對於 HTTPS 請求,客戶端在發送 HTTP 請求之前要發送 TLS 握手數據。Proxy 收到 TLS 握手數據後是不知道要把這些數據轉發給哪台伺服器的。所以,協議要求客戶端要先發送一個 CONNECT 請求來告訴代理伺服器目標伺服器的域名和埠。

大家注意,對於 HTTP 請求,Agent 和 Proxy 之間的通信中全明文的;對於 HTTPS 請求,Agent 的 CONNECT 請求也是通過明文發送給 Proxy 的。因為是明文協議,所以存在安全風險。

我們知道,HTTPS 就是使用 TLS 對明文 HTTP 協議進行的加密的。那我們可不可以使用 TLS 對 Agent 和 Proxy 之間的通信進行加密呢?理論上是可行的,但現實中卻不可行,因為改造現有系統來支持 TLS 版 HTTP 代理的工作量太大了。那就沒有其他辦法了嗎?有,那就是引入二級代理,其代理通信流程如下:

Agent Local Proxy Remote Proxy Site
| | | |
| <1> tcp dial to proxy:8080 | | |
|<--------------------------->| | |
| <2> GET / HTTP/1.1 | | |
| Host: baidu.com | | |
|---------------------------->| <3> tls handshake | |
| |<--------------------------->| |
| ~=================================~ |
| | <4> CONNECT baidu.com:80 | |
| |---------------------------->| |
| | | <5> tcp dial to baidu.com:80 |
| | <6> HTTP/1.1 200 OK |<---------------------------->|
| |<----------------------------| |
| | <7> GET / HTTP/1.1 | |
| | Host: baidu.com | <8> GET / HTTP/1.1 |
| |---------------------------->| Host: baidu.com |
| | |----------------------------->|
| | | <9> HTTP/1.1 200 OK |
| | <10> HTTP/1.1 200 OK |<-----------------------------|
| |<----------------------------| |
| ~=================================~ |
| <11> HTTP/1.1 200 OK | | |
|<----------------------------| | |
| | | |

對於 HTTPS 請求,通信流程則稍微簡單一些:

Agent Local Proxy Remote Proxy Site
| | | |
| <1> tcp dial to proxy:8080 | | |
|<--------------------------->| | |
| <2> CONNECT baidu.com:443 | | |
|---------------------------->| <3> tls handshake | |
| |<--------------------------->| |
| ~=================================~ |
| | <4> CONNECT baidu.com:443 | |
| |---------------------------->| |
| | | <5> tcp dial to baidu.com:443|
| | <6> HTTP/1.1 200 OK |<---------------------------->|
| <7> HTTP/1.1 200 OK |<----------------------------| |
|<----------------------------| | |
| https data | https data | https data |
|<--------------------------->|<--------------------------->|<---------------------------->|
| ~=================================~ |
| | | |

這裡的核心是引入 Local ProxyRemote Proxy 兩台代理伺服器。對 Agent 來說,Local Proxy 就是一台普通的代理伺服器,一般部署在本機。Local Proxy 收到代理請求後不會直接連接目標伺服器,而是先跟 Remote Proxy 建立 TLS 連接,並使用 CONNECT 請求將目標伺服器的信息發送給 Remote Proxy,Remote Proxy 收到 CONNECT 請求後執行代理連輯。Local Proxy 既是 Agent 的 Proxy,又是 Remote Proxy 的 Agent,具有雙重人格。Local Proxy 和 Remote Proxy 之間的通信使用 TLS 加密,保證不被惡意用戶竊取。

最後,TLS 加密 HTTP 代理的缺點。

第一,TLS 通信需要 SSL 證書。SSL 證書一般只簽發給域名,所以還需要註冊一個域名。好在我們可以去 https://www.freenom.com 註冊一年期免費域名,然後使用 letsencrypt.org/ 簽發三月期證書,所以這個問題不大。

第二,就是 TLS 握手效率的問題。TLS v1.2 握手流程確實很繁瑣,至少要四次通信才能完成握手,延遲的確很大。但是,TLS v1.3 對握手流程做了大幅優化,只需兩次通信即可,大大縮短了握手延遲。所以,只要能使用 TLS v1.3,這個問題也不大。

推薦閱讀:

相关文章