Wireshark 抓包教程:過濾器寫法與常見問題分析
Wireshark 怎麼用:選中有流量的網路卡開始抓包,復現問題後停止,再用顯示過濾器(如 ip.addr == 203.0.113.10、tcp.flags.syn == 1)篩出相關的包,右鍵追蹤 TCP 流看完整會話。伺服器沒有圖形介面時,用 tcpdump -w 抓成 pcap 檔案,下載到電腦上用 Wireshark 開啟分析。
Wireshark 是一款開源的抓包和協議分析工具,用法可以概括成四步:在有流量的網路卡上開始抓包,復現問題後停止;抓的時候用捕獲過濾器(BPF 語法,如 host 203.0.113.10)少抓無關的包;停下以後用顯示過濾器(Wireshark 欄位語法,如 ip.addr == 203.0.113.10)篩出要看的包;最後右鍵追蹤 TCP 流,看三次握手、重傳和每一段的耗時,判斷問題出在網路還是應用。機房裡的伺服器大多沒有圖形介面,做法是在伺服器上用 tcpdump -w 抓成 pcap 檔案,下載到自己電腦上用 Wireshark 開啟。下面從安裝講到分析,每一步都給出可以照做的操作和過濾表示式。
Wireshark 怎麼用:安裝並完成第一次抓包
安裝。 Windows 上執行官方安裝包,安裝過程中會一併安裝 Npcap,Wireshark 靠它從網路卡收包,這一步不要跳過。Linux 上用包管理器安裝,並把自己加入 wireshark 組,免得每次都用 root 執行圖形介面:
# Debian / Ubuntu:安裝時詢問是否允許非 root 使用者抓包,選“是”
sudo apt install wireshark
sudo usermod -aG wireshark $USER # 重新登入後生效
# RHEL / Rocky / AlmaLinux:圖形介面和命令列工具分為兩個包
sudo dnf install wireshark wireshark-cli
第一次抓包。
- 開啟 Wireshark,啟動頁列出了所有網路卡,每塊網路卡後面有一條流量小曲線,選曲線在跳動的那塊。筆記本上通常是“WLAN”或“乙太網”;Linux 上的 any 表示同時抓所有網路卡。
- (可選)在網路卡列表上方的捕獲過濾器輸入框裡填條件,例如
host 203.0.113.10,只抓與這台伺服器相關的包。 - 雙擊網路卡或點左上角藍色的鯊魚鰭按鈕,開始抓包。
- 去復現問題:開啟那個打不開的網頁、執行那條連不上的命令。
- 點紅色方塊停止,按 Ctrl+S 儲存為 pcapng 檔案,留作對比和交給同事分析。
抓包時間儘量短,只覆蓋問題發生的那幾秒到幾分鐘。抓了半小時再在幾十萬個包裡找問題,比重新抓一次還慢。
看懂 Wireshark 介面:分組列表、分組詳情與位元組
停止抓包後,主視窗分成上中下三塊:
| 區域 | 顯示什麼 | 怎麼用 |
|---|---|---|
| 分組列表(上) | 每個包一行:序號 No.、時間 Time、源和目的位址、協議、長度、摘要 Info | 找包、排序,看整體的時間順序 |
| 分組詳情(中) | 選中包的逐層解析:Frame、Ethernet II、IPv4、TCP,再往上是 HTTP、DNS 等 | 展開看具體欄位,右鍵欄位可以直接生成過濾條件 |
| 分組位元組(下) | 原始十六進位制和 ASCII | 核對某個欄位的原始值,明文協議能直接讀出內容 |
四個設定能明顯提高效率:
- 時間列改成“與上一個顯示的包的間隔”:View → Time Display Format → Seconds Since Previous Displayed Packet。配合過濾器,一眼看出哪兩個包之間等了很久。
- 把常看的欄位加成列:在分組詳情裡右鍵某個欄位,選 Apply as Column(應用為列),例如把
tcp.stream或dns.qry.name加到列表裡。 - 右鍵生成過濾器:右鍵欄位選 Apply as Filter → Selected(作為過濾器應用 → 選中),不用手寫表示式。
- 看懂預設配色:淺紫色是 TCP,淺藍色是 UDP,黑底紅字是 Wireshark 判定有問題的 TCP 包(重傳、亂序、重複確認、零視窗等),先看黑底的行。
選單以英文介面為準,中文介面的譯名在不同版本中略有出入。
Wireshark 過濾器:捕獲過濾器與顯示過濾器寫法對照
兩套過濾器的分工不同:捕獲過濾器在抓包前設定,決定哪些包被寫進檔案,語法與 tcpdump 相同;顯示過濾器在抓包後使用,只決定顯示哪些包,隨時可以改。同一個需求,兩種寫法對照如下:
| 需求 | 捕獲過濾器(BPF) | 顯示過濾器 |
|---|---|---|
| 與某台主機相關的所有包 | host 203.0.113.10 |
ip.addr == 203.0.113.10 |
| 只看某台主機發出的包 | src host 203.0.113.10 |
ip.src == 203.0.113.10 |
| 某個網段 | net 203.0.113.0/24 |
ip.addr == 203.0.113.0/24 |
| TCP 443 連接埠 | tcp port 443 |
tcp.port == 443 |
| 某個連接埠,不分 TCP、UDP | port 53 |
tcp.port == 53 || udp.port == 53 |
| HTTP | tcp port 80(只能按連接埠) |
http |
| DNS | port 53(含 TCP 上的 DNS) |
dns |
| 帶 SYN 標誌的包 | tcp[tcpflags] & tcp-syn != 0 |
tcp.flags.syn == 1 |
| 排除自己的 SSH 會話 | not port 22 |
!(tcp.port == 22) |
| 某個 MAC 位址 | ether host 00:1b:21:3a:4f:10 |
eth.addr == 00:1b:21:3a:4f:10 |
| 不小於 1000 位元組的包 | greater 1000 |
frame.len >= 1000 |
幾條寫法規則和常見錯誤:
- 兩種語法不能互換。把
ip.addr == 203.0.113.10填進捕獲過濾器,或者把host 203.0.113.10填進顯示過濾器,輸入框會變紅,說明語法不對。 - 顯示過濾器按協議名過濾更準確。
http匹配的是 Wireshark 識別為 HTTP 的包,跑在 8080 連接埠上的 HTTP 也算;捕獲過濾器只認連接埠號,tcp port 80漏掉 8080。反過來,HTTP 跑在非標準連接埠時,Wireshark 可能認不出來,右鍵 Decode As 指定協議即可。 - “不等於”要小心。
ip.addr != 203.0.113.10在 3.6 之前的版本里意思是“源或目的有一個不是它”,幾乎會匹配所有包;3.6 起改為“源和目的都不是它”。寫成!(ip.addr == 203.0.113.10)在任何版本里含義都一致。 - 邏輯運算:
&&(and)、||(or)、!(not),文字匹配用contains,例如http.host contains "example"。
在機房伺服器上抓包,第一件事通常是排除自己的 SSH 會話,否則抓包輸出經 SSH 回傳又產生新的包,越抓越多。
追蹤 TCP 流:看三次握手、重傳和連線失敗
追蹤流。 在任意一個 TCP 包上右鍵 → Follow → TCP Stream(追蹤流 → TCP 流,快捷鍵 Ctrl+Alt+Shift+T),Wireshark 會自動把顯示過濾器設為 tcp.stream eq 5 這樣的形式,只留下這一條連線的包,並彈出視窗按順序拼出雙方傳送的內容。明文協議(HTTP、SMTP、Redis 等)能直接讀出請求和回應;HTTPS 只能看到加密資料,但包的時間和大小照樣能分析。
看三次握手。 過濾 tcp.flags.syn == 1,每條連線的前兩個包就出來了。一次正常的握手在分組列表裡是這樣的(範例,客戶端側抓包):
No. Time Source Destination Protocol Length Info
1 0.000000 192.168.1.20 203.0.113.10 TCP 74 51544 → 443 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM TSval=3011847 TSecr=0 WS=128
2 0.031502 203.0.113.10 192.168.1.20 TCP 74 443 → 51544 [SYN, ACK] Seq=0 Ack=1 Win=65160 Len=0 MSS=1460 SACK_PERM TSval=88123 TSecr=3011847 WS=128
3 0.031580 192.168.1.20 203.0.113.10 TCP 66 51544 → 443 [ACK] Seq=1 Ack=1 Win=64256 Len=0 TSval=3011879 TSecr=88123
Seq=0、Ack=1 是 Wireshark 換算後的相對序號,第 3 個包的 Win=64256 也是按握手時協商的視窗縮放(WS=128)換算後的值,便於閱讀。第 1 個包到第 2 個包間隔 31.5 毫秒,在客戶端側抓包時,這就是到伺服器的一次往返時間(RTT);在伺服器側抓包時要反過來看,SYN-ACK 到 ACK 的間隔才是 RTT。Wireshark 還會把 SYN 到第 3 個包 ACK 的時間記為 iRTT(欄位 tcp.analysis.initial_rtt),這條連線每個包的詳情裡都能看到,兩側抓包都可以直接參考。
連線失敗的幾種樣子。 連不上的問題,握手階段的包長什麼樣,基本就說明了原因:
| 抓到的包 | 說明 | 下一步 |
|---|---|---|
| 只有 SYN,同一個 SYN 每隔 1、2、4、8 秒重發一次(Linux 的預設節奏) | 請求被丟棄,沒有任何回應:防火牆、安全組以丟棄方式攔截,或者路由不通 | 到伺服器上抓包,看 SYN 有沒有到達 |
| SYN 之後立即收到 RST, ACK | 包到了目標主機,但連接埠沒有程式監聽;少數防火牆也會用 RST 拒絕 | 在伺服器上用 ss 查服務是否在監聽 |
SYN 之後收到 ICMP 目標不可達(顯示過濾器 icmp) |
防火牆以拒絕方式攔截,例如 iptables 的 REJECT 預設回 ICMP 連接埠不可達;也可能是沿途路由不可達 | 看 ICMP 包是誰發的、型別和程式碼是什麼 |
| 握手完成,隨後伺服器發 RST 或 FIN | 網路通,是應用主動關閉:來源不在白名單、連線數滿、協議不匹配 | 查應用日誌和存取控制 |
看重傳。 顯示過濾器 tcp.analysis.retransmission 列出所有重傳(含快速重傳),tcp.analysis.duplicate_ack 列出重複確認。過濾後看視窗底部的狀態列,例如 Displayed: 56 (0.4%),這個百分比就是重傳包占全部包的比例,可以作為粗略的重傳率。還要分清兩個標記:
- TCP Retransmission:傳送方重發了已經發過的資料,多數是等到超時(RTO)才重發,意味著丟包,而且會帶來明顯停頓;收到重複確認後立即重發的,Wireshark 標為 TCP Fast Retransmission,恢復得快得多。
- TCP Spurious Retransmission:重傳了對方其實已經確認過的資料,多見於確認包丟失或延遲,資料本身沒丟。
抓包位置會影響判斷:在傳送端抓到的重傳,說明資料或確認在抓包點之後的某處丟了;只在接收端抓、卻看到缺口和重複確認,說明包在到達之前就丟了。兩端同時抓、按序號對照,能定位到丟包發生在哪一側。
伺服器上用 tcpdump -w 抓包,再用 Wireshark 分析
伺服器上沒有 Wireshark 圖形介面,標準做法是“伺服器抓、電腦看”:
-
確認網路卡名:
ip -br link或tcpdump -D。 -
開始抓包,寫入檔案而不是列印到螢幕:
tcpdump -i eth0 -nn -s 0 -w /tmp/web-$(date +%F-%H%M).pcap 'host 198.51.100.7 and tcp port 443'
-w 把原始資料寫進 pcap 檔案,-s 0 儲存完整的包(較新的 tcpdump 預設已是完整長度,寫上更穩妥),-nn 不解析主機名和連接埠名。條件和 Wireshark 的捕獲過濾器寫法完全一樣,可以直接複製。
- 控制檔案大小。不確定問題什麼時候出現、需要長時間掛著抓時,用輪轉:
# 每個檔案約 100 MB,最多保留 10 個,寫滿後從第一個開始覆蓋
tcpdump -i eth0 -nn -w /tmp/cap.pcap -C 100 -W 10 'host 198.51.100.7'
檔案放在 /tmp 這類所有使用者都能寫的目錄:部分發行版的 tcpdump 開啟網路卡後會降權為 tcpdump 使用者執行,輪轉出的新檔案寫不進 /root 會報 Permission denied。
-
復現問題後按 Ctrl+C 停止,看最後三行統計。
packets dropped by kernel不為 0,說明核心來不及處理、有漏抓,分析時要把這個因素考慮進去,下次收緊過濾條件。 -
下載到電腦:
gzip /tmp/web-2026-12-21-1530.pcap # 在伺服器上壓縮,Wireshark 可以直接開啟 .pcap.gz
scp [email protected]:/tmp/web-2026-12-21-1530.pcap.gz . # 在自己電腦上執行
Windows 10 及以後自帶 OpenSSH 客戶端,PowerShell 裡可以直接用 scp,也可以用 WinSCP 這類圖形工具。
- 在 Wireshark 裡開啟,先看 Statistics → Capture File Properties(統計 → 捕獲檔案屬性),確認抓包的起止時間覆蓋了問題發生的時刻。pcap 裡存的是 UTC 時間戳,Wireshark 按自己電腦的時區顯示,對照伺服器日誌時注意換算;伺服器時間不準的話,先校準 NTP。
在伺服器上抓的包有兩個常見“假問題”,不要誤判:
- 包長度超過 1514 位元組。伺服器網路卡開著 TSO、GSO,發出的大資料塊在抓包點還沒被網路卡切分,Wireshark 裡會看到幾千甚至幾萬位元組的“包”,線路上實際仍是 1500 以內的幀;接收方向開著 GRO 時,多個包合併後才交給抓包程式,也會出現這種超長包。
- 校驗和錯誤。網路卡負責計算校驗和時,從本機發出的包在抓包點還沒有算好校驗和。Wireshark 預設不校驗 TCP、UDP 校驗和;如果你在首選項裡開啟了校驗,看到大量 checksum incorrect 先想到這個原因。
檔案不方便下載時,可以直接在伺服器上用 tshark(Wireshark 的命令列版本)做初步分析:
tshark -r web.pcap -q -z conv,tcp # 按 TCP 會話統計位元組數和持續時間
tshark -r web.pcap -Y 'tcp.analysis.retransmission' | wc -l # 重傳包數量
tshark -r web.pcap -q -z expert # 專家資訊彙總
tshark -r web.pcap -Y 'dns.flags.response == 1' -T fields -e frame.time_relative -e dns.qry.name -e dns.time
抓包檔案裡有完整的業務資料,可能包含客戶的 Cookie、明文密碼,分析完及時刪除,不要留在伺服器的 /tmp 裡。
用時間差定位“慢在哪一段”
“開啟網頁慢”是最常見的抓包需求。一次 HTTPS 存取可以拆成五段,每段從哪個包算到哪個包、用什麼過濾器、偏大說明什麼,見下表:
| 階段 | 從哪個包到哪個包 | 顯示過濾器 | 明顯偏大說明 |
|---|---|---|---|
| DNS 解析 | 查詢 → 應答 | dns,看應答包裡的 dns.time |
解析伺服器慢,或者丟包後超時重查 |
| TCP 建連 | SYN → SYN-ACK | tcp.flags.syn == 1 |
網路往返時間長,或 SYN 被丟後重發 |
| TLS 握手 | Client Hello → Server Hello | tls.handshake.type == 1 || tls.handshake.type == 2 |
伺服器 TLS 處理慢,或證書鏈大、遇到丟包 |
| 伺服器處理 | 請求的最後一個包 → 回應的第一個資料包 | 明文 HTTP 可參考 http.time(預設算到整個回應收完,含傳輸時間) |
應用或資料庫慢,與網路無關 |
| 資料傳輸 | 回應的第一個包 → 最後一個包 | 疊加 tcp.analysis.flags 看異常 |
有重傳、零視窗,或者頻寬不夠 |
舉個例子:一次存取總共 2.6 秒,抓包得到 DNS 應答 0.003 秒、SYN 到 SYN-ACK 0.031 秒、TLS 握手 0.065 秒,而請求發出後 2.4 秒才收到第一個回應資料包,之後的傳輸只用了 0.1 秒、沒有重傳。結論很清楚:慢在伺服器處理,網路沒問題,該去查應用日誌和慢查詢,而不是找機房換線路。反過來,如果建連階段 SYN 重發了兩次,按 Linux 1 秒、2 秒的重發間隔,建連就多花了約 3 秒,時間耗在了網路丟包上。
明文 HTTP 可以用 http.time > 1 一次篩出所有超過 1 秒才完成的請求;HTTPS 看不到請求內容,就用上面的方法,在追蹤流裡看客戶端最後一個上行資料包和伺服器第一個下行資料包之間的時間差。
在管理系統裡怎麼落地
在機房裡抓包,難點往往不在 Wireshark,而在“該在哪台機器、哪個連接埠上抓”。Toplink DCIM 的即時流量圖和網路 TOP 排行能先找出流量異常、佔用高的伺服器,交換器管理裡能直接查到這台伺服器上聯的交換器和連接埠號,以及連接埠速率和所屬 VLAN,需要在交換器側配映象或查連接埠計數時,可以在瀏覽器裡開啟交換器終端,會話全程錄影。伺服器網路出了問題、SSH 登不上去時,用 IPMI 遠端管理透過 BMC 開啟 VNC 控制檯,照樣可以在伺服器上執行 tcpdump,把包寫到本地磁碟,等網路恢復後再下載分析。
常見問題
Wireshark 抓不到發往 127.0.0.1 的包怎麼辦?
本機迴環流量不經過物理網路卡,要選專門的迴環介面:Windows 上選介面列表裡由 Npcap 提供的 Adapter for loopback traffic capture;Linux 上選 lo;macOS 上選 lo0。
pcap 和 pcapng 有什麼區別?
pcapng 是 Wireshark 現在預設的儲存格式,能在一個檔案裡記錄多個介面、註釋和名稱解析資訊;tcpdump 預設寫 pcap。Wireshark 兩種都能開啟,只認 pcap 的老工具可以用 editcap -F pcap 輸入.pcapng 輸出.pcap 轉換。
能用 Wireshark 看 HTTPS 的內容嗎?
前提是拿得到會話金鑰。在自己的電腦上設定環境變數 SSLKEYLOGFILE 指向一個檔案,再啟動 Chrome 或 Firefox,瀏覽器會把每個 TLS 會話的金鑰寫進去;在 Wireshark 的首選項 Protocols → TLS 裡把這個檔案填到 (Pre)-Master-Secret log filename,就能解開這台電腦發起的 HTTPS 流量。別人裝置上的 HTTPS 拿不到金鑰,無法解密。