1. 程式人生 > 實用技巧 >什麼是HTTP隧道,怎麼理解HTTP隧道呢?

什麼是HTTP隧道,怎麼理解HTTP隧道呢?

總述:

HTTP 1.1引入了HTTP tunnel,提供了支援任意流量的TCP隧道的能力。

HTTP proxy是一箇中間人,是客戶端去請求代理,代理修改請求再去請求網站,proxy不能代理HTTPS請求,因為代理不可能獲得網站的私鑰。

HTTP tunnel 不需要改寫請求包,將C S之間的流量直接轉發,所以可以傳輸代理TLS加密的HTTPS流量。

HTTP tunnel**:

HTTP tunnel使用CONNECT方法進行建立隧道連線通訊
HTTP tunnel是HTTP/1.1中引入的一個功能,主要為了解決明文的HTTP proxy無法代理跑在TLS中的流量(也就是https)的問題,同時提供了作為任意流量的TCP通道的能力。

HTTP tunnel 不需要改寫請求包,將C S之間的流量直接轉發,所以可以傳輸代理TLS加密的HTTPS流量。

HTTP tunnel的工作流程是什麼樣的?

CONNECT報文沒有後面的負載部分,只有Request-Line和header後面以兩個\r\n斷開,Request-Line和header均是由代理伺服器使用,不會發送到遠端伺服器。請求的header部分一旦結束(連續的兩組CRLF),後面所有的資料都被視為應該發給遠端伺服器(網站)的資料,代理需要把它們直接轉發,而且不限長度,直到從客戶端的TCP讀通道關閉
響應同理:對於CONNECT報文的返回值,代理伺服器在和遠端伺服器成功建立連線後,可以(標準說的是可以,但是一般都會)向客戶端(瀏覽器)返回任意一個2xx狀態碼,此時表示含義是和遠端伺服器建立連線成功,這個2xx返回報文的header部分一旦結束(連續的兩組CRLF),後面所有的資料均為遠端伺服器返回的資料,同理代理會直接轉發遠端伺服器的返回資料給客戶端,直到從遠端伺服器的TCP讀通道關閉。

HTTP proxy ,如何工作:

HTTP tunnel出來之前,HTTP proxy工作在中間人模式,即在一次請求中,客戶端(瀏覽器)銘文的請求去請求代理伺服器。代理伺服器明文去請求遠端的伺服器(網站)。整個過程的請求響應內容(密碼cookie等)代理伺服器都是可見的。且使用HTTP proxy模式要求代理伺服器對請求報文進行適當修改,RFC2616 5.1.2中要求請求代理的報文中Request-URL使用絕對路徑,即以http開頭:

使用了代理後,傳送的報文將變為:

GET http://stackoverflow.com/ HTTP/1.1\r\n
Host: stackoverflow.com\r\n
Proxy-Connection: keep-alive\r\n
\r\n

代理從請求的第一行中得知要請求的目標是stackoverflow.com,埠為預設埠(80),將第一行改寫後,向網站伺服器傳送請求:

GET / HTTP/1.1\r\n
Host: stackoverflow.com\r\n
Connection: keep-alive\r\n
\r\n

因為:如果代理HTTPS流量,那麼就會變成瀏覽器和代理握手跑TLS,代理拿到明文的請求報文,代理和網站握手跑TLS。但是代理沒有,也不可能有網站的私鑰證書,所以這麼做會導致瀏覽器和代理之間的TLS無法建立,證書校驗根本通不過。但是HTTP tunnel的出現解決了這個問題,代理伺服器不再作為中間人,不在用改寫請求。

HTTP隧道和SOCKS隧道的區別:

其中相同的地方:

  • 都能在請求中指明要請求的目標和埠。
  • 都會建立能傳輸任何流量的TCP通道,代理伺服器對流量內容不關心。
  • 都是在報文前部的描述資訊結束後,將後續所有資料視為轉發的客戶端和服務端資料,直到通道關閉。
  • 都可以進行客戶端的身份驗證,而且有多重身份驗證協議可選。

不同的地方:

  • SOCKS5的報文無論請求還是返回,內容均是固定的。而CONNECT報文作為HTTP/1.1的報文之一,當然也包括了HTTP/1.1可以傳輸任何自定義header的功能,雖然一般代理不會響應CONNECT報文上的非標準header,但是自己實現一個客戶端和伺服器通過header傳輸一些其它資料也是符合標準的。
  • SOCKS5 request報文中的address,根據address type(ATYP)位元組的值,可以顯式宣告為IPv4地址、IPv6地址、域名(domain)。而CONNECT報文中的Request-URI根據RFC要求必須為authority形式(即沒有http://字首,只包含host,以及可選的port,其中host和port要用":"分隔),也就是說CONNECT報文不會顯式的區分IP地址和域名,均作為host傳輸。
  • 由於CONNECT報文還是http,所以也可以跑在TLS裡,也就是說客戶端和代理跑一層TLS,這一層裡面客戶端和遠端伺服器再跑一層TLS。這樣當代理伺服器需要使用者名稱密碼驗證,而驗證方式又是Basic時,可以通過TLS來保護代理請求報文中的明文使用者名稱密碼。

參考來源:https://www.zhihu.com/question/21955083/answer/142736329