天天給 App 抓包,還不懂 HTTP 代理嗎? | 實用 HTTP

一、序

有段時間沒寫 HTTP 協議相關的文章了,突然發現文章選題池裏, 《實用 HTTP》 系列中還躺了個 HTTP 代理的主題沒有寫,那今天就來聊聊 HTTP 代理吧。

本文就是本系列的第六篇文章了,前五篇文章的傳送門:

在 HTTP 協議中,最基礎的就是請求和響應的報文,而報文又由報文頭和報文實體組成。大多數 HTTP 協議的使用場景,都是依賴設置不同的 HTTP 請求/響應 的 Header 來實現的。

既然要說到代理,先提兩個問題來當主線,從問題出發講解 HTTP 代理。

  1. 抓包工具是如何實現 HTTP 抓包的。

  2. 對於 HTTPS 流量,不安裝證書的情況下,通過抓包工具,請求和響應依然正常。

今天說的 HTTP 代理,更多的是一種抽象概念,其中的原理纔是最關鍵的。

二、HTTP 代理

2.1 什麼 HTTP 代理?

說到 HTTP 代理,作爲客戶端開發,最熟悉的就是使用 Fiddler、Charles 等工具進行抓包時,需要在手機上掛個代理,來方便我們排查一些網絡問題,這只是代理衆多使用場景中的一個。

實際上,HTTP 代理(Web 代理)是一種存在於網絡中間的實體,可以提供各種功能。如果沒有 HTTP 代理,客戶終端就要直接與終端服務器進行交互。而有了 HTTP 代理後,客戶終端就可以與代理通信,然後由代理代表客戶端與服務器進行交互。

HTTP 代理算是最容易理解的一個 HTTP 協議概念,它和我們的生活最貼近。在我們的生活中,存在各種代辦的服務。

例如你和女友準備出國遊,一些不免籤的國家,就需要提前辦理簽證。我們不熟悉自然覺得流程很複雜,這時就可以選擇交由旅行社來代理辦理簽證,你只需要根據對方提供的清單準備材料,就可以很方便的獲得簽證。在這個過程中,你節省了時間,而旅行社賺了你一點錢。

代理服務,就是代理客戶端完成事務處理的中間人,它接管客戶端的事務,代替客戶端與服務端交互。

代理服務是一個抽象的中間實體,可以存在網絡的各個中間點,瀏覽器、路由器、代理服務器、Web 服務器的反向代理等,

2.2 HTTP 代理的分類

從最熟悉的抓包工具說起,Fiddler、Charles 這種抓包工具,封裝的都非常好,哪怕我們完全不理解 HTTP 代理的細節,簡單配置就可以使用。

在使用過程中,你會發現兩種場景:

  1. 對於 HTTP 協議請求,可以直接顯示請求/響應報文的細節

  2. 對於 HTTPS ,如果沒有導入證書,請求依然可以發送至服務器,並且也可以正常返回數據,但是不會顯示報文細節。

在沒有導入證書的情況下,HTTPS 請求我們無法獲知細節,但是並不影響我們的請求和響應。

這個兩種不同的表現,也對應了兩種不同的 HTTP 代理:

  1. 普通代理。基於修訂後的 RFC 2616 在 HTTP/1.1 中被定義。這種代理扮演的是「中間人」的角色。對客戶端來說,它是服務端,而對真正的服務端來說,它又是客戶端,它就是負責在兩端之間傳遞 HTTP 報文。

  2. 隧道代理。這種一種基於 TCP 協議的隧道傳輸代理,它通過 HTTP 協議的 CONNECT 方法完成通信,以 HTTP 的方式,實現任意基於 TCP 的應用層協議代理。

接下來我們就分別對這兩種代理進行講解。

2.3 普通代理

普通代理,理解起來並不複雜,它是網絡中的中間實體,位於客戶端和服務端之間,扮演「中間人」的角色,在兩端之間來回傳遞報文。

這個「中間人」左手牽着客戶端,右手牽着服務端,在收到客戶端發送的請求報文時,需要正確的處理請求和連接狀態,同時向服務器發送新的請求,在收到響應後,將響應結果包裝成一個響應體返回給客戶端。

在普通代理的流程中,代理兩端都是有可能察覺不到「中間人」的存在。

舉個例子,我們要訪問 A 網站,實際上我們是向代理服務器發送請求,而代理服務器又再向 A 網站發起請求,最終將響應體通過代理服務器,返回給我們。在我們的角度,我們正常的向一個網站服務器發起請求,並且對方也返回給我們正確的數據,在這個過程中,我作爲客戶端,會認爲代理服務器就是 A 網站的服務器,而 A 網站的服務器,又認爲代理服務器是一個真實的用戶。

這裏說到,代理服務器作爲「中間人」是可以隱藏自己的存在,但是如果我們作爲一個“守規矩”的代理服務器,想要將客戶端的 IP 傳遞給服務端,可以通過 X-Forwarded-IP 這個自定義的 Header,來告訴服務端真正的客戶端 IP 地址。

HTTP 協議作爲一種鬆散的協議,服務器在接收到 X-Forwarded-IP 這個請求頭時,是無法驗證其真僞的。它可能是代理服務器僞造的,也可能是真實的。所以服務端從 HTTP 頭部獲取 IP 時,就需要格外小心。

普通代理很好理解,但是它也有缺陷,它只適用於 HTTP 協議。

在普通代理模式下,所有請求響應的數據,對於代理這個「中間人」來說,都是透明並且可以任意操作,這就會帶來各種數據安全的隱患。

說到網絡數據安全,首先想到的就是 HTTPS,但是 HTTPS 這種證書認證的機制,又是中間人劫持的剋星。

嚴格上來說,HTTPS 下不存在中間人攻擊,除非是人爲的犯錯了,沒有對證書嚴格校驗,或者證書被泄露。

在普通的 HTTPS 請求中,服務端不驗證客戶端的證書,中間人可以作爲客戶端與服務端完成 TLS 握手。

但是由於代理中間人沒有證書密鑰,也就無法僞造服務端和客戶端簡歷的 TLS 連接,這會導致請求失敗。

這個場景,對標到抓包工具的工作流程中,你會發現,如果想用 Charles(或Fiddler) 抓 HTTPS 的網絡數據包,就需要在手機上安裝一個 Charles 的 CA 證書,讓手機設備信任此證書,纔可以完成抓包,此時走的就是普通代理的模式。

那換個角度,假如在手機上沒有安裝 Charles 提供的證書,也並沒有影響到請求和響應,Charles 只是無法解密 HTTPS 數據,這是如何做到的呢?

這就需要用到隧道代理

2.4 隧道代理

隧道代理,又稱爲 Web 隧道(Web tunnel),這種方式可以通過 HTTP 連接發送非 HTTP 流量,這樣可以在 HTTP 上捎帶其他協議的數據。

隧道代理是利用 HTTP 的 CONNECT 方法建立起來的。CONNECT 方法,最初並不是 HTTP/1.1 的核心規範,但卻是一種得到廣泛使用的擴展,它在 2014 年發佈的 HTTP/1.1 修訂版中,纔對 CONNECT 及隧道代理有了清晰的描述。

HTTP 隧道代理的工作流程是什麼樣的?

一次普通的 HTTP 請求,Header 部分以連續的兩組 CRLF(\r\n)作爲結束標記,如果後面還有內容,就是 Content 部分的內容,也稱爲請求/響應體(Content),如果存在 Content 內容,就需要在 Header 中增加 Content-Length 來標記 Content 部分的長度。接收方(服務端)會根據這個長度來讀取數據。

CONNECT 報文的請求,是沒有 Content 部分的,只有 Request-Line 和 Header,他們僅供代理服務器使用,並不會傳遞給終端服務器。請求的 Header 部分一旦結束(兩組連續的 CRLF),後面的所有數據,都被視爲應該轉發給終端服務器的數據,代理需要把他們無腦的直接轉發,並且不限制長度,直到從客戶端的 TCP 讀通道關閉。

CONNECT 的響應報文,在代理服務器和終端服務器建立連接後,可以向客戶端返回一個 200 Connect established 的狀態碼,以此表示和終端服務器的連接,建立成功。這個 200 Connect established 的 Header 部分一旦結束(兩組連續的 CRLF),後面所有的數據均爲遠端服務器返回的數據,同理,代理服務器會直接轉發終端服務器的數據給客戶端,直到終端服務器的 TCP 讀通道關閉。

瞭解清楚 HTTP 隧道的工作流程之後,就知道 CONNECT 方法請求隧道網管創建一條到達任意目的服務器和端口的 TCP 連接,並對客戶端和服務端之間的後續數據,進行無腦的盲轉發

通過隧道代理,代理服務器不再作爲中間人,不再需要改寫瀏覽器的請求,而是把瀏覽器和終端服務器的數據,原樣轉發,這樣瀏覽器就可以直接和終端服務器進行 TLS 握手,並傳輸加密的數據。

2.4 導入證書後,Charles 抓 HTTPS 流程

Charles 作爲抓包工具,在手機上沒有導入證書的時候,是通過隧道代理來保證數據的傳輸。一旦導入證書之後,Charles 就又切換到普通代理的工作模式,此時我們就可以解析 HTTPS 的流量數據。

這裏簡單說一下原理。

在導入證書後,請求時手機就會信任 Charles 僞造的證書,而 Charles 又僞裝成真實的客戶端與服務端之間建立正確的 TLS 連接。此時,Charles 作爲「中間人」,兩端的 TLS 流量都是可以被解密的。

三、總結時刻

到這裏就瞭解清楚 HTTP 代理的細節,其實很抽象的概念,也很好理解。

簡單來說,HTTP 代理可以分爲兩類,普通代理和隧道代理。

普通代理作爲「中間人」存在,在一次請求中,客戶端明文請求代理服務器,在收到請求後,代理服務器又明文去請求終端服務器。在這整個過程中,數據都是明文傳輸,中間人可以對其中傳遞的數據進行改寫,這就是著名的中間人攻擊,可見其有多不安全。

這就引申出了支持 HTTPS 的隧道代理,此時代理服務器就不再作爲中間人,無法改寫客戶端的請求,而僅僅是在建立連接後,將客戶端的請求,通過建立好的隧道,無腦的轉發給終端服務器。

關於 HTTP 代理的細節就到這裏,有任何問題歡迎留言討論!

reference:

《HTTP 權威指南》第六章和 8.5 小結

https://imququ.com/post/web-proxy.html

https://www.zhihu.com/question/21955083

本文對你有幫助嗎?留言、轉發、點好看是最大的支持,謝謝!


「聯機圓桌」????推薦我的知識星球,一年 50 個優質問題,上桌聯機學習。

公衆號後臺回覆成長『成長』,將會得到我準備的學習資料,也能回覆『加羣』,一起學習進步;你還能回覆『提問』,向我發起提問。

發佈了327 篇原創文章 · 獲贊 8 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章