1. 程式人生 > >使用 Wireshark 除錯 HTTP/2 流量

使用 Wireshark 除錯 HTTP/2 流量

提醒:本文最後更新於 447 天前,文中所描述的資訊可能已發生改變,請謹慎使用。

我們知道,HTTP/2 引入了二進位制分幀層(Binary Framing),將每個請求和響應分割成為更小的幀,並對它們進行了二進位制編碼。與此同時,HTTP/2 沿用了之前 HTTP 版本中的絕大部分語義,上層應用基本上感知不到 HTTP/2 的存在,這一點可以通過瀏覽器的網路除錯工具得到驗證。以下是使用 Chrome 訪問 HTTP/2 網站的截圖,網路面板中顯示的內容與 HTTP/1 網站相比,只有一些細微的區別(頭部欄位都是小寫,多了一些冒號開頭的頭部等)。

imququ-network

那麼究竟要如何除錯 HTTP/2 流量呢?HTTP/2 中的 Server Push、Prioritization 等功能,要如何才能看到並分析呢?Chrome 本身提供了一個非常不錯的工具,在 Chrome 位址列輸入 chrome://net-internals/#http2

即可進入。這個工具會列出瀏覽器當前所有活躍的 HTTP/2 Session,點選具體的 Session ID,可以看到全部幀資訊。

但 Chrome 的工具看到的資訊畢竟經過了解析和篩選,不如原始資訊全面,也沒辦法在其他瀏覽器例如 Firefox 中使用。本文介紹一個更為通用的 HTTP/2 除錯工具:Wireshark。

Wireshark 是一個無比強大的網路封包分析工具,大家對它應該不陌生。新版 Wireshark 才增加了對 HTTP/2 的支援,首先請從下面這個地址獲取最新的安裝包:

根據自己系統選擇合適的安裝包後,全新或覆蓋安裝都可以。我在寫本文時用的是「Wireshark 2.1.0-229-g3385c29 Intel 64.dmg」這個安裝包。

Update @ 11.8,我今天試了一下官網版本(下載地址)」,也沒問題。

由於主流瀏覽器都只支援 HTTP/2 Over TLS,也就是說當前 HTTP/2 網站都使用了 HTTPS,資料傳輸都經過了 SSL 加密。所以預設情況下,Wireshark 抓到的包是這樣的,SSL 層之上的協議細節完全看不到:

wireshark-ssl

另外一個著名的 HTTP 抓包工具 Fiddler 是通過開啟本地代理進行抓包的,它能夠解密 HTTPS 流量的原理很簡單:首先 Fiddler 作為客戶端跟服務端建立 TLS 連線,使用服務端的證書,處理請求和響應;然後 Fiddler 又作為服務端跟瀏覽器建立 TLS 連線,使用 Fiddler 的證書,處理請求和響應。所以 Fiddler 要解密 HTTPS 流量,需要先把它生成的根證書新增到系統受信任的根證書列表之中。

Wireshark 的抓包原理是直接讀取並分析網絡卡資料,要想讓它解密 HTTPS 流量,有兩個辦法:1)如果你擁有 HTTPS 網站的加密私鑰,可以用來解密這個網站的加密流量;2)某些瀏覽器支援將 TLS 會話中使用的對稱金鑰儲存在外部檔案中,可供 Wireshark 加密使用。本文重點介紹第二種方法。

Firefox 和 Chrome 都支援生成上述第二種方式的檔案,具體格式見這裡:NSS Key Log Format。但 Firefox 和 Chrome 只會在系統環境變數中存在 SSLKEYLOGFILE 路徑時才會生成它,先來加上這個環境變數(以 OSX 為例):

mkdir ~/tls && touch ~/tls/sslkeylog.log

#zsh
echo "\nexport SSLKEYLOGFILE=~/tls/sslkeylog.log" >> ~/.zshrc && source ~/.zshrc

#bash
echo "\nexport SSLKEYLOGFILE=~/tls/sslkeylog.log" >> ~/.bash_profile && . ~/.bash_profile

接著,在 Wireshark 的 SSL 配置面板的 「(Pre)-Master-Secret log filename」選項中這個檔案選上。如下圖:

wireshark-ssl-debug

「SSL debug file」也建議配上,這樣解密過程中的日誌都會記錄下來,便於除錯。

通過終端啟動 Firefox 或 Chrome(確保能讀取到環境變數):

open /Applications/Firefox.app
open /Applications/Google\ Chrome.app

這時再訪問 HTTPS 網站,sslkeylog.log 檔案中應該有瀏覽器寫入的資料了。檢查無誤後,就可以開啟 Wireshark,選擇合適的網絡卡開始抓包(本文目的是抓取 HTTP/2 資料包,可以將 TCP 埠限定在 443,讓抓到的資料少一些):

wireshark-capture

新版 Wireshark 在配置了 TLS 加密後,會自動識別並解析 HTTP/2 流量。訪問想要抓包的 HTTP/2 網站,根據 IP 和協議過濾一下,就可以輕鬆看到想要的 HTTP/2 資料包了。如下圖:

wireshark-http2

這種方法也可以用在解密使用 HTTP/1 的 HTTPS 網站上,大家可以自己動手試一試。

如果按照本文說明一直都抓不到包,也可以試試評論裡 @sodino 提供的方案:用命令列開啟 Wireshark。

--EOF--

提醒:本文最後更新於 447 天前,文中所描述的資訊可能已發生改變,請謹慎使用。