
抓包分析
抓包分析工具主要有兩種:
- http/https 網絡代理工具:mitmproxy/fiddler 都屬於這一類,用於分析 http 非常方便。但是只支持 http/https,有局限性。
- tcp/udp/icmp 等網絡嗅探工具:tcpdump/tshark 都屬於這一類,網絡故障分析等場景常用。
這里主要介紹如何使用 tcpdump + wireshark 進行遠程實時抓包分析。
而 mitmproxy 抓包和 wireshark 本地抓包都相當簡單,就不介紹了。
P.S. tshark 是 wireshark 的命令行版本,用法 tcpdump 非常相似。
一、wireshark 的基本用法
WireShark 的 UI 界面如何使用,網上能搜得到各種類型的 wireshark 演示,多看幾篇博客就會了。
搜索 [xxx 協議 wireshark 抓包分析] 就能找到各種各樣的演示,比如
- 「gRPC 協議 wireshark 抓包分析」
- 「WebSocket 協議 wireshark 抓包分析」
- 「TCP 協議 wireshark 抓包分析」
- 等等
主要需要介紹的,應該是 wireshark 的數據包過濾器。
wireshark 中有兩種包過濾器:
- 捕獲過濾器:在抓包的時候使用它對數據包進行過濾。
- 顯示過濾器:對抓到的所有數據包進行過濾。
顯示過濾器是最有用的,下面簡要介紹下顯示過濾器的語法。
可以直接通過「協議名稱」進行過濾:
# 只看 tcp 流量
tcp
# 只看 http 流量
http
# 使用感嘆號(或 not)進行反向過濾
!arp # 過濾掉所有 arp 數據包
也可以通過「協議名稱.協議屬性」和「比較操作符(比如 ==)」進行更精確的過濾:
# 通過 ip 的源地址 src 或 dst 進行過濾
ip.src==192.168.1.33
# 通過 IP 地址(ip.addr)進行過濾(匹配 ip.src 或 ip.dst)
ip.addr==192.168.0.5
# 上一條過濾表達式等價於:
ip.src==192.168.0.5 or ip.dst==192.168.0.5
# 通過 tcp 端口號進行過濾
tcp.port==80
tcp.port>4000
# 通過 http 的 host 屬性進行過濾
http.host != "xxx.baidu.com"
# 通過 http.referer 屬性進行過濾
http.referer == "xxx.baidu.com"
# 多個過濾器之間用 and、or 進行組合
http.host != "xxx.baidu.com" and http.referer == "xxx.baidu.com"
二、tcpdump + ssh + wireshark 遠程實時抓包
在進行遠程網絡抓包分析時,我們通常的做法是:
- 使用
tcpdump在遠程主機上抓包,保存為 pcap 文件。 - 將 pcap 文件拷貝到本地,使用 wireshark 對其進行分析。
但是這樣做沒有時效性,而且數據拷貝來去也比較麻煩。
考慮使用流的方式,在遠程主機上使用 tcpdump 抓包,本地使用 wireshark 進行實時分析。
使用 ssh 協議進行流式傳輸的示例如下:
# eth0 更換成你的機器 interface 名稱,虛擬機可能是 ens33
ssh root@some.host "tcpdump -i eth0 -l -w -" | wireshark -k -i -
在不方便使用 ssh 協議的情況下(比如容器抓包、Android 抓包),可以考慮使用 nc(netcat) 進行數據流的轉發:
# 1. 遠程主機抓包:將數據流通過 11111 端口暴露出去
tcpdump -i wlan0 -s0 -w - | nc -l -p 11111
# 2. 本地主機從遠程主機的 11111 端口讀取數據,提供給 wireshark
nc <remote-host> 11111 | wireshark -k -S -i -
如果是抓取 Android 手機的數據,方便起見,可以通過 adb 多進行一次數據轉發:
# 方案一:root 手機后,將 arm 版的 tcpdump 拷貝到手機內進行抓包
# 1. 在 adb shell 里使用 tcpdump 抓 WiFi 的數據包,轉發到 11111 端口
## 需要先獲取到 root 權限,將 tcpdump 拷貝到 /system/bin/ 目錄下
tcpdump -i wlan0 -s0 -w - | nc -l -p 11111
# 2. 在本機使用 adb forward 將手機的 11111 端口綁定到本機(PC)的 11111 端口
adb forward tcp:11111 tcp:11111
# 3. 直接從本機(PC)的 11111 端口讀取數據,提供給 wireshark
nc localhost 11111 | wireshark -k -S -i -
## 通過數據轉發,本機 11111 端口的數據,就是安卓手機內 tcmpdump 的 stdout 內容。
# 方案二:
# 如果手機不方便 root,推薦 PC 開啟 WiFi 熱點,手機連上這個熱點訪問網絡。
# 這樣手機的數據就一定會走 PC,直接在 PC 上通過 wireshark 抓包就行。
# 如果你只需要簡單地抓 http/https 包,請使用 fiddler/mitmproxy
如果需要對 Kubernetes 集群中的容器進行抓包,推薦直接使用 ksniff!
Windows 系統
另外如果你本機是 Windows 系統,要分 shell 討論:
cmd: 可以直接使用上述命令。powershell: PowerShell 管道對native commands的支持不是很好,管道兩邊的命令貌似是串行執行的,這會導致 wireshark 無法啟動!目前沒有找到好的解決方法。。
另外如果你使用 wsl,那么可以通過如下命令使 wsl 調用 windows 中的 wireshark 進行抓包分析:
# 添加軟鏈接
sudo ln -s "$(which wireshark.exe)" /usr/local/bin/wireshark
添加了上述軟鏈接后,就可以正常地在 wsl 中使用前面介紹的所有抓包指令了(包括 ksniff)。
它能正常調用 windows 中的 wireshark,數據流也能正常地通過 shell 管道傳輸。
2. termshark: 直接通過命令行 UI 進行實時抓包分析
有的時候,遠程實時抓包因為某些原因無法實現,而把 pcap 數據拷貝到本地分析又比較麻煩。
這時你可以考慮直接使用命令行版本的 wireshark UI: termshark,直接在命令行進行實時的抓包分析。
kubectl-debug 默認的調試鏡像中,就自帶 termshark.
