Windows 封包擷取實務 — pktmon、netsh trace、Wireshark 怎麼選

· · Windows, 封包擷取, pktmon, netsh, Wireshark, 網路, 故障調查, TCP/IP

「業務應用程式的伺服器通訊一個月失敗幾次。應用程式紀錄只寫『逾時』。當時伺服器端紀錄沒有對應錯誤。不知道怎麼重現」——故障調查諮詢裡,這種形狀不斷出現。

應用程式紀錄只留下應用程式「決定要寫」的東西。你看得見結果是逾時,但連線要求(SYN)有沒有回覆、連上之後伺服器是否沉默、是不是被 RST 切斷、封包有沒有到達目的地,都活在紀錄下一層——實際走過線路的封包。若 Process Monitor 是往下一層看檔案與登錄存取的方法,封包擷取就是往下一層看通訊的方法。

應用程式紀錄下一層的封包應用程式紀錄只留下應用程式決定要寫的內容;SYN 有沒有回覆、連線後是否沉默、是否被 RST 切斷、封包有沒有到達,只存在實際走過線路的封包裡往下一層看應用程式紀錄只留下決定要寫的內容結果只剩一句逾時實際走過線路的封包SYN 沒有回覆?連線後沉默?被 RST 切斷?有到達目的地嗎?

圖 1: 紀錄只留下結果;逾時的內情只存在下一層的封包裡。

人們卡住的典型點是「客戶伺服器不能安裝 Wireshark」這個限制。變更管制或資安政策不批准為調查加裝軟體的現場並不少見。不過 Windows 已經內建兩套封包擷取工具:pktmon 與 netsh trace。用作業系統內建工具擷取,把檔案帶回自己的電腦用 Wireshark 讀——這樣分工,即使現場禁止安裝也能看到封包。

本文給中小企業 IT 人員與 Windows 應用程式開發者,整理 pktmon、netsh trace、Wireshark 的選擇方式與各自的實務步驟。迴路流量的陷阱、該在用戶端還是伺服器擷取、如何與 TLS 隱藏酬載共處、以及擷取與應用程式紀錄的對照,都以 2026 年 8 月當時的一手資料說明。

1. 先講結論

  • 「用內建工具擷取、用 Wireshark 讀」是現場的基本分工。 即使客戶伺服器不能裝軟體,pktmon 與 netsh trace 已內建於 Windows。把擷取紀錄轉成 pcapng,在自己機器的 Wireshark 分析。12
  • pktmon 是 Windows 10 / Windows Server 2019 以後內建的封包擷取工具。 用法是註冊篩選器、開始、停止、轉換四步,獨特之處是能看到網路堆疊哪個元件丟了封包(丟棄原因)。34
  • netsh trace 是較舊的內建工具,能把一組 ETW 提供者當成「情境」一次啟用。 除了封包,也留下 Windows 元件內部事件,加上 persistent=yes 擷取就能撐過重開機。56
  • 兩套工具都寫 ETL,Wireshark 不能直接開啟。 pktmon 用 pktmon etl2pcap 轉 pcapng,netsh trace 用 Microsoft 開源的 etl2pcapng。12
  • Microsoft 自己指向「先 pktmon,不夠再用 netsh trace,協定分析用 Wireshark」。 本文分工遵循這項官方建議。7
  • 預設 pktmon 只記錄每個封包的前 128 位元組。 若打算在 Wireshark 讀酬載,開始時別忘了 --pkt-size 0(記錄整個封包)。8
  • 打到 localhost 的流量不會出現在一般擷取。 它不經過 NIC。Wireshark 用 Npcap 的迴路介面卡,內建工具用 pktmon 的堆疊內擷取。9
  • 即使 TLS 藏起酬載,仍能知道很多事。 連線建立、TLS 交握成敗、RST、哪一邊沉默,加密狀態下仍可見。經 SSLKEYLOGFILE 解密是僅限開發環境的手法。10
  • 擷取檔就是通訊本身。 預設它可能含認證資訊與個人資料,把最小必要擷取與交出前縮小範圍寫進程序。

2. 三套擷取工具與怎麼選

先用一張表看三套工具的角色。

  pktmon netsh trace Wireshark
取得方式 Windows 10 / Windows Server 2019 以後內建3 Windows 早已內建(pktmon 之前的系統也能用) 需另外安裝
主要角色 封包擷取、丟棄偵測、計數器 封包擷取 + Windows 元件的 ETW 事件 分析擷取資料(真正目的地)
輸出格式 ETL(用 etl2pcap 轉 pcapng)1 ETL+.cab(用 etl2pcapng 轉 pcapng)62 pcapng
獨特之處 堆疊內丟棄位置與原因4 依情境綁定提供者、跨重開機擷取5 顯示篩選器、TCP 分析、統計、GUI
權限 系統管理員 系統管理員 擷取需相當於系統管理員(只分析則不必)

一句話,pktmon 與 netsh trace 是「擷取」工具,Wireshark 是「讀」的工具。Wireshark 也能擷取,但不能裝的地方就用不了。反過來說,也能把內建工具的 ETL 轉成文字來讀,但沒有顯示篩選器與 TCP 分析地盯著看很痛苦。「現場用內建工具擷取,轉成 pcapng,在自己機器的 Wireshark 讀」是受限現場的最短路徑。

用內建工具擷取、用 Wireshark 讀現場用 pktmon 或 netsh trace 擷取 ETL,各自用轉換工具轉成 pcapng,再在自己機器的 Wireshark 分析pktmon etl2pcapetl2pcapngpktmon(內建)ETL 檔netsh trace(內建)ETL+.cabpcapng在自己機器的 Wireshark 分析

圖 2: 現場用內建工具擷取 ETL,轉成 pcapng,在自己機器的 Wireshark 讀。

Microsoft 的封包遺失調查指南也是這個形狀:先用 pktmon 擷取並隔離原因,不夠再進到 netsh trace start scenario=InternetClient 這類元件層追蹤,協定行為用 Wireshark 分析。7

要讀懂封包實際顯示什麼,先有 Ethernet、IP、TCP、應用程式資料層層堆疊的圖像也有幫助。層次解剖見「把OSI參考模型看得明明白白」。

3. pktmon 實務 — 篩選、開始、停止、轉換

pktmon 的基本流程是四步。在提升權限的終端機執行。

:: 1. 先註冊篩選器以縮小目標(伺服器 192.168.10.20 的 TCP 8443)
pktmon filter add App8443 -i 192.168.10.20 -t tcp -p 8443
pktmon filter list

:: 2. 開始擷取。記錄完整封包,在 1GB 環形緩衝區中覆寫
pktmon start --capture --pkt-size 0 --file-name C:\temp\app-timeout.etl --file-size 1024 --log-mode circular

:: 3. 重現故障。等待期間可用 counters 查看流量與丟棄
pktmon counters --drop-reason

:: 4. 停止,再轉為 Wireshark 用的 pcapng
pktmon stop
pktmon etl2pcap C:\temp\app-timeout.etl --out C:\temp\app-timeout.pcapng

:: 5. 清理已註冊的篩選器(篩選器會一直保留到你明確刪除)。
::    注意:filter remove 不能指定名稱;它會刪除「全部」已註冊篩選器。
::    若機器上可能還留著另一次調查的篩選器,先用 pktmon filter list 確認
pktmon filter remove
pktmon 基本步驟用篩選器縮小目標、開始擷取、重現故障、停止、用 etl2pcap 轉成 pcapng,最後移除已註冊的篩選器1. 用 filter add 縮小目標2. 用 start --capture 開始擷取3. 重現故障用 counters 看流量與丟棄4. 停止用 etl2pcap 轉成 pcapng5. 用 filter remove 清理

圖 3: pktmon 從註冊篩選器開始,接著擷取、停止、轉換,最後明確移除篩選器。

要記住的重點:

  • 開始擷取前先註冊篩選器。 Microsoft 文件也強烈建議開始前套用篩選器,因為擷取全部流量太吵。篩選器可指定 IP 位址、連接埠、MAC 位址、協定、VLAN ID 等,最多註冊 32 個。多個篩選器是 OR:封包符合其中任一就會被記錄。3
  • pktmon 篩選器不區分來源與目的地。 -i 192.168.10.20 代表「這個位址是來源或目的地的封包」。方向稍後用轉換後的 Wireshark 顯示篩選器縮小。3
  • 預設封包大小是 128 位元組。 分析標頭夠用,但若還要應用程式資料,用 --pkt-size 0 記錄整個封包。8
  • 紀錄預設是 circular(環形緩衝)模式,預設大小 512MB。 可用 --file-size 改上限,--log-mode real-time 即時印到畫面且不建立紀錄檔。先用即時模式確認真的看得到關心的流量,再設正式擷取,就能避開空拍。8
pktmon 篩選器如何生效多個已註冊篩選器以 OR 比對記錄,指定位址不區分來源與目的地,方向稍後用轉換後的 Wireshark 顯示篩選器縮小篩選器 1符合任一就記錄篩選器 2篩選器 3(最多 32)寫入擷取紀錄(OR)不區分來源與目的地轉換後在 Wireshark 縮小方向

圖 4: 多個篩選器以 OR 運作,主機是來源還是目的地在轉換後用 Wireshark 縮小。

3.1. 只有 pktmon 做得到的事 — 看到封包在哪裡被丟棄

pktmon 相對 Wireshark 的獨特價值是 它不是在單一 NIC 擷取,而是在網路堆疊內多個點擷取封包,並能回報在哪裡、為什麼被丟棄(dropped)。因為看得到封包到達哪個元件、在哪裡消失,「MTU 不符」或「VLAN 篩選」這類丟棄原因不必盲搜就能接到原因。4

pktmon 在堆疊內多個點擷取pktmon 不是在單一 NIC 而是在網路堆疊內多個點擷取封包,因此能連同原因回報封包到達哪個元件、在哪裡被丟棄封包在點 1 擷取在點 2 擷取在點 3 被丟棄回報丟棄位置與原因例如 MTU 不符或 VLAN 篩選

圖 5: 在堆疊內多個點擷取,就能知道封包走到哪、在哪裡被丟,並附上原因。

  • pktmon list 顯示可監視的網路元件(NIC、協定堆疊、篩選驅動程式等)及其 ID。
  • pktmon counters --drop-reason 列出各元件通過/丟棄計數與最近一次丟棄原因。分析紀錄前當第一刀很方便。11
  • pktmon etl2txt 轉成文字時,被丟棄的封包會帶著 drop 與 dropReason 輸出。3

「作業系統裡有東西在到達應用程式前就把這包丟掉」這種懷疑,只盯 Wireshark 無法了結。這個能力例如在隔離防火牆因缺少輸入規則而丟包的案例時有幫助(「Windows 防火牆與業務應用程式」)。

有一點要注意。pktmon 在堆疊多個點記錄同一個封包,原樣轉成 pcapng 可能讓同一封包出現不止一次。pcapng 不攜帶「哪個元件擷取了這包」,所以在 Wireshark 讀時,標準作法是用 --component-id 選一個點轉換,或用 --drop-only 把丟棄單獨放到另一個檔。1

為什麼轉成 pcapng 後同一封包可能出現兩次pktmon 在堆疊多個點記錄同一封包,pcapng 不保留哪個元件擷取,因此可能出現重複;標準作法是用 component-id 縮小擷取點,或用 drop-only 檔只放丟棄後再轉換同一封包在多個點被記錄原樣轉成 pcapng擷取點資訊沒有帶過去同一封包出現不止一次用 --component-id 縮小點用 --drop-only 另存檔

圖 6: 擷取點資訊不會帶進 pcapng,所以標準作法是轉換前先縮小擷取點。

4. netsh trace 實務 — 情境、ETL、撐過重開機的擷取

netsh trace 是比 pktmon 更早進入 Windows 的追蹤機制。特色是 能以「情境」一次啟用與該問題相關的整組 ETW 提供者6

:: List available scenarios and inspect the providers in a scenario
netsh trace show scenarios
netsh trace show scenario netconnection

:: Start the capture. Packet capture included, 1GB circular buffer
netsh trace start scenario=netconnection capture=yes tracefile=C:\temp\nettrace.etl maxSize=1024 filemode=circular

:: Reproduce the incident, then stop (the merge takes a little time)
netsh trace stop
  • 加上 capture=yes 啟用封包擷取,並用 ipv4.address=192.168.10.20 這類擷取篩選器縮小目標。篩選器清單在 netsh trace show capturefilterHelp6
  • 停止時除了 ETL 還會產生 .cab。.cab 含介面卡設定與作業系統組建等系統資訊,可兼作環境蒐集。6
  • 同一時間只能跑一個追蹤工作階段。開始另一次擷取前,用 netsh trace show status 確認沒有殘留工作階段。6
  • 加上 persistent=yes,工作階段就能撐過重開機。 「重開機後一瞬間通訊失敗」或「啟動時服務連線失敗」——這種來不及用手啟動的故障,是 netsh trace 獨有的地盤。5
擷取 netsh trace 情境以情境啟動會啟用一組 ETW 提供者,capture=yes 也會擷取封包,停止後產生 ETL 檔與 .cab 檔capture=yes以情境啟動啟用提供者集合封包也會被擷取重現故障停止ETL 檔.cab(系統資訊)

圖 7: 以情境啟動會啟用一組提供者,停止後產生 ETL 與 .cab。

4.1. 讓 ETL 能在 Wireshark 讀 — etl2pcapng

netsh trace 的 ETL 不能直接在 Wireshark 開啟。Microsoft 在 GitHub 公開的開源工具 etl2pcapng,會把以 netsh trace start capture=yes 擷取的 ETL 裡的封包轉成 pcapng。2

etl2pcapng.exe C:\temp\nettrace.etl C:\temp\nettrace.pcapng

轉換時 etl2pcapng 會把每個封包相關的處理程序 ID 寫成封包註解。能在 Wireshark 看到「這是哪個處理程序的流量」,同一台伺服器上多個應用程式在通訊時很有幫助。2

ETW 事件那一側(情境提供者記下的 Windows 內部事件)不會轉進 pcapng。若也要事件,用 netsh trace convert input=C:\temp\nettrace.etl 轉成文字等,或在 Windows Performance Analyzer 開啟 ETL。57

讀 netsh trace ETL 分成兩條路ETL 裡的封包用 etl2pcapng 轉成 pcapng 在 Wireshark 讀;ETW 事件不轉成 pcapng,因此用 netsh trace convert 或 Windows Performance Analyzer 讀etl2pcapngnetsh trace ETL封包ETW 事件轉成 pcapng在 Wireshark 讀處理程序 ID 留在註解不轉成 pcapng用 convert 或 WPA 讀

圖 8: ETL 裡的封包轉成 pcapng 來讀;ETW 事件用另一種方式讀。

5. 在 Wireshark 讀的第一步 — 顯示篩選器與 TCP 分析

打開 pcapng 後,先用顯示篩選器切掉雜訊。常用的列在表裡。1213

顯示篩選器 意義
ip.addr == 192.168.10.20 這個 IP 是來源或目的地的封包
tcp.port == 8443 涉及這個 TCP 連接埠的封包
dns 只看 DNS 查詢與回應
tcp.flags.syn == 1 && tcp.flags.ack == 0 只看連線 SYN
tcp.flags.reset == 1 只看 RST(強制切斷)
tcp.analysis.retransmission Wireshark 判斷為重傳的封包
tcp.analysis.zero_window 接收視窗 0(接收端不能再收)
tcp.analysis.flags 偵測到某種問題的所有封包

tcp.analysis.* 是 Wireshark 追蹤 TCP 序號後貼上的分析旗標。重傳、重複 ACK、亂序、ZeroWindow 等會被機械地抓出,所以 讀檔的標準起手是先輸入 tcp.analysis.flags,列出「看起來有問題」的地方13

逾時調查時,依序找下列形狀。

  1. 三次交握完成了嗎? SYN → SYN/ACK → ACK 三個封包都在嗎?SYN 重複且沒有回覆,就是沒到達對端,或在中途被默默丟掉(典型防火牆模式)。
  2. 哪一邊送出 RST? 對 SYN 立刻 RST 代表目的連接埠沒人在聽;連線建立後的 RST 代表一邊強制切斷。RST 的來源 IP 就是「誰切斷」的直接證據。
  3. 重傳是否持續? 同一區段反覆重傳,代表 確認(ACK)沒回到傳送端。出去的資料丟了還是回來的 ACK 丟了,單側擷取無法了結(所以下一章「兩邊擷取」很重要)。重傳與逾時在「TCP 重送讓工業相機通訊卡幾秒時」有更深入說明。
  4. 有沒有 ZeroWindow? 那是接收應用程式沒從通訊端讀取、接收緩衝區滿了的跡象。該懷疑的是接收應用程式的設計(「TCP 中「Send 單位=Receive 單位」的誤解」),而不是網路。
逾時調查要找的形狀順序確認三次交握是否完成、RST 是否存在及其來源、重傳是否持續,再看 ZeroWindow,對原因做第一標記SYN 有回覆嗎?從未到達(典型防火牆)有 RST 嗎?RST 來源切斷了它重傳持續嗎?ACK 沒回來有 ZeroWindow 嗎?接收端沒在讀

圖 9: 依序找交握、RST、重傳、ZeroWindow,就能縮小下一步要看的地方。

逐包讀之前,先用統計功能抓住全貌也有幫助。[Statistics] → [Conversations] 是「哪一對 IP/連接埠、從何時到何時、多少量」的清單,可先找出關心的通訊再只篩那一條。[Statistics] → [I/O Graph] 是隨時間變化的流量圖,「從這個時間起有一邊沉默」這種形狀會跳出來。對關心的 TCP 通訊按右鍵選 [Follow] → [TCP Stream],就能把該連線的往來當明文通讀。

先用統計抓住圖像,再縮小到一條通訊在 Conversations 列出哪些通訊何時走了多少,從 I/O Graph 抓住沉默區間,篩到關心的通訊,再當 TCP 串流通讀用統計抓住全貌Conversations 的通訊清單在 I/O Graph 看流量篩到關心的通訊沉默區間變得可見當 TCP 串流通讀

圖 10: 逐包讀之前,先用統計抓住圖像,縮小到關心的通訊,再通讀。

6. 迴路陷阱 — 打到 localhost 的流量從不經過 NIC

調查同一台電腦上應用程式之間的通訊——例如業務應用程式連到 localhost:8080 的中間服務——卻卡在「Wireshark 什麼都沒有」,是經典陷阱。

原因很清楚。打到 localhost(127.0.0.1)的流量不會經過實體 NIC,而是在作業系統內部迴路路徑折返。 以實體介面卡為目標的一般擷取因此從頭就看不到。9

為什麼打到 localhost 的流量不出現在擷取打到 localhost 的流量不經過實體 NIC,在作業系統內部迴路路徑折返,因此以實體介面卡為目標的一般擷取看不到外部localhost應用程式網路堆疊實體 NIC一般擷取看得到在作業系統內折返一般擷取沒有Npcap 迴路 或 pktmon

圖 11: 打到 localhost 的流量在 NIC 前折返,實體介面卡擷取看不到。

應對有兩種。

  • 用 Wireshark 擷取時:把擷取目標選成 Npcap 的 「Adapter for loopback traffic capture」。Windows 版 Wireshark 安裝程式(3.0 以後)內含 Npcap,已安裝 Wireshark 就不必再多做。9
  • 用內建工具擷取時:pktmon 不是在 NIC 外側,而是在網路堆疊內多個點擷取4,所以也能觀察迴路流量。為求確定,設正式等待重現之前,先在該機器用 pktmon start -c -m real-time 即時顯示確認關心的迴路流量真的看得到。

也要小心兩種混淆。

  • 「localhost」可能解析成 IPv6 ::1。 應用程式連到 IPv6 ::1,調查者只看 127.0.0.1(IPv4),就誤判「沒有流量」。把顯示篩選器拉到兩邊,例如 ip.addr == 127.0.0.1 || ipv6.addr == ::1,或把應用程式目的地設成明確位址。9
  • 打到自己真實 IP 的流量也不會上線。 同一台電腦從 192.168.10.5 連到 192.168.10.5 時,目的地是真實 IP,作業系統仍在內部折返。「指定了真實 IP,就一定經過 NIC」並沒有保證。
localhost 解析成 IPv6 時的混淆應用程式的 localhost 可能解析成 IPv6 ::1,調查者只看 127.0.0.1 會誤判沒有流量,因此把顯示篩選器拉到兩個位址,或把目的地確認成明確位址應用程式連到 localhost實際解析成 ::1(IPv6)調查者只看 127.0.0.1畫面上什麼都沒有把篩選器拉到兩個位址把目的地設成明確位址

圖 12: 小心 localhost 解析成 ::1、只看 127.0.0.1 就以為「沒有流量」的混淆。

7. 在哪裡擷取 — 單側、雙側與時鐘同步

擷取的價值由「在哪裡擷取」決定。經驗規則如下。

擷取位置 能知道什麼 何時適合
只在用戶端 你送出什麼、回來什麼 先抓全貌。不能碰伺服器時
只在伺服器 要求是否到達、是否送出回應 用戶端很多,或無法指定一台時
兩邊同時 路徑上哪裡丟了封包、哪一邊沉默 需要釐清責任邊界時

單側擷取只告訴你「從我這個位置看到的事實」。用戶端持續重傳,分不出是送出的封包在路徑上消失,還是到了伺服器而回覆消失。兩邊擷取並排起來,就能釐清「用戶端送了/伺服器從沒收到」——哪一邊沉默。 需要釐清責任邊界(應用程式、作業系統、網路裝置或對端)時,值得一開始就安排雙側擷取。

單側與雙側擷取能告訴你什麼單側擷取無法分辨是出去的封包消失還是回來的回覆消失;兩邊擷取並排起來,才能釐清哪一邊沉默在單側擷取自己這一側的事實出去還是回來?在兩邊擷取並排起來哪一邊沉默需要時鐘同步

圖 13: 單側只顯示你看到的事實;兩邊並排,責任邊界才第一次能釐清。

7.1. 對照的前提是時鐘同步

要把兩邊擷取並排,兩台機器的時鐘必須一致。開始擷取前,檢查並記錄時鐘偏差。

:: Check time-sync status (sync source, last sync time)
w32tm /query /status

:: Measure the offset against the peer server (5 samples)
w32tm /stripchart /computer:sv-app01 /dataonly /samples:5

w32tm /stripchart 顯示你與對端電腦的時間偏差,並排擷取時可作為「伺服器時鐘快了 +0.8 秒」這類校正的依據。14 偏差很大的環境,先修好時間同步再擷取,最後反而比較短。

對照前檢查時鐘偏差的步驟用 w32tm 確認自己的時間同步狀態,用 stripchart 測量並記錄與對端伺服器的偏差,對照時作為校正依據;偏差大就先修好同步再擷取用 query 確認同步狀態用 stripchart 測量偏差記錄偏差對照時校正的依據偏差大就先修好同步

圖 14: 擷取前測量並記錄時鐘偏差,並排時作為校正依據。

7.2. 「不知道何時會發生」時 — 環形緩衝

重現條件不明的故障,基本作法是讓環形緩衝一直跑,故障發生時再停。

  • pktmon:預設就是 circular 模式。用 --file-size 設上限(MB);較舊的封包會被覆寫。8
  • netsh trace:指定為 maxSize=1024 filemode=circular5
  • Wireshark:在 [Capture] → [Options] → [Output] 可設定「多個檔案 + 環形緩衝」。依檔案大小或時間輪替,只保留最新 N 個檔,因此能在磁碟用量上限下長跑。15

無論哪一種,都要與現場人員約定:故障發生時,「先記下時間,然後」再停止擷取。環形緩衝等越久就越抹掉過去,從發生到停止的路徑一長,關心的區間就被覆寫。

用環形緩衝擷取等待重現條件不明的故障就讓環形緩衝一直跑,故障發生時記下時間並立刻停止;停晚了,較舊的封包被覆寫,關心的區間就消失開始環形緩衝擷取讓它跑著等故障發生記下時間立刻停止較舊的封包被覆寫停晚會抹掉關心的區間

圖 15: 環形緩衝等越久就越抹掉過去,記下時間後立刻停止。

8. TLS 藏起酬載的問題 — 仍然看得到什麼

現在多數業務流量是 TLS(HTTPS)。人們容易覺得「加密了擷取就沒意義」,但 逾時調查想知道的大多數,讓加密維持原樣仍看得見

  • TCP 連線是否建立(三次交握)
  • TLS 交握走到哪——ClientHello 有沒有 ServerHello 回來、交握中是否被 RST 或 alert 切斷
  • ClientHello 上的目的地主機名稱(SNI),以及協商的 TLS 版本
  • 連線起來後哪一邊停止傳送。沉默的位置、重傳、RST,或乾淨關閉(FIN)

也就是隔離「連不上」、「中途斷掉」、「沒有回應回來」,幾乎不需要解密酬載。加密失去的是「他們說了什麼」;「誰在何時沉默」仍在。

TLS 擷取能看到與看不到的加密只藏起應用程式資料酬載;TCP 連線建立、TLS 交握成敗、SNI 與 TLS 版本、RST、哪一邊沉默,讓加密維持原樣仍看得見TLS 流量擷取看得見看不見TCP 連線建立TLS 結果與 SNIRST/誰沉默應用程式資料酬載

圖 16: 加密只失去酬載;通訊骨架讓 TLS 維持原樣仍可讀。

仍需要酬載時,Wireshark 可用 SSLKEYLOGFILE 環境變數寫出的工作階段金鑰解密 TLS。支援限於 Firefox、Chrome、以 Chromium 為基礎的 Edge、OpenSSL 系列程式庫等部分實作;Windows 內建 SChannel(使用 WinHTTP 或 WinINET 的應用程式)不支援這個機制10 「工作階段金鑰寫到檔案」代表拿到該檔的人能解密整段通訊,這不是正式環境手法;請當成開發環境的重現與除錯

SSLKEYLOGFILE 解密的運作與限制經 SSLKEYLOGFILE 寫出的工作階段金鑰可讓 Wireshark 解密 TLS,但只有 Firefox、Chrome 系列等部分實作支援,SChannel 不支援;拿到金鑰檔的人就能解密通訊,因此當成僅限開發環境的手法設定 SSLKEYLOGFILE寫出工作階段金鑰在 Wireshark 讀持有金鑰者可解密僅限開發僅部分 TLS 堆疊SChannel:不支援

圖 17: 寫出工作階段金鑰就能解密,但支援的實作有限,金鑰的性質也讓它只能當開發環境手法。

流量經過內部 Proxy 時,擷取裡出現的目的地是 Proxy 伺服器,TLS 走在 CONNECT 隧道裡。應用程式到底朝哪個 Proxy 去,這個先決問題整理在同日的搭配文章「企業 Proxy 與 Windows 應用程式 — 釐清 WinINET、WinHTTP、.NET 的 Proxy 解析」。

9. 與應用程式紀錄對照 — 把時間放在同一軸

單靠擷取很少得出結論。實務上決定性的一步是 把應用程式紀錄的一行與封包的一趟往返放在同一時間軸

步驟如下。

  1. 從應用程式紀錄找出故障時間(例如 10:23:41 的逾時例外)。若逾時值是 30 秒,開始應在 10:23:11 附近。
  2. 把 Wireshark 的時間顯示改成 [View] → [Time Display Format] → [Date and Time of Day],再用顯示篩選器縮小區間(也能用時間篩選,例如 frame.time >= "2026-08-20 10:23:00" && frame.time <= "2026-08-20 10:24:00")。
  3. 在該區間依第 5 章順序確認(交握 → RST → 重傳 → ZeroWindow)。若能對到「紀錄逾時時間的 30 秒前送出 SYN,之後只有 SYN 重傳」,紀錄裡的「逾時」就換成觀察「在這個擷取點,完全沒有回覆回來」(SYN 沒到達對端,還是回來的 SYN/ACK 在回程遺失,單靠這個擷取點無法釐清。要釐清就在伺服器擷取並排起來)。
  4. 一定要校正擷取時間與紀錄時間的偏差(第 7.1 節量到的時鐘偏差,以及紀錄的時區標記)。幾秒的對照誤差會把錯的通訊釘成元兇。
把應用程式紀錄與封包並排的步驟從應用程式紀錄找出故障時間,用逾時值反推開始時間,在 Wireshark 用顯示篩選器縮小區間,依序確認形狀,校正時鐘偏差,放在同一時間軸1. 從紀錄找出故障時間用逾時值反推開始2. 用顯示篩選器縮小區間3. 依第 5 章順序確認形狀4. 校正時鐘偏差紀錄的一句話變成觀察

圖 18: 從紀錄時間縮小區間,確認形狀,校正時鐘偏差,放在同一軸。

把調查結果交給第三者(廠商、電信業者、客戶網路人員)時,交出前用篩選器切掉雜訊既是禮貌也是安全措施。在 Wireshark 用顯示篩選器縮小到關心的通訊,再用 [File] → [Export Specified Packets] 儲存「只含顯示的封包」,就得到只要該範圍的小 pcapng。

最後是處理注意。擷取檔就是通訊本身。 可能含明文協定的認證資訊、HTTP Cookie 與 API 金鑰、郵件或報表內容、個人資料。下列三點請與擷取程序成套決定。

  • 最小必要擷取:用擷取前篩選器(第 3、4 章)縮小目標,時間窗盡量短。不要在客戶環境「先全部擷取再說」
  • 交出前縮小:只匯出關心的通訊,不要帶無關的第三者流量。若仍有敏感部分,與對方約定遮罩或另途
  • 保存與刪除:決定擷取檔放哪、放多久、何時刪除,調查結束就刪
交出擷取檔前要決定的三件事擷取就是通訊本身,因此與擷取程序成套決定:用擷取前篩選器與時間窗縮到最小、交出前只抽出關心的通訊以免帶入無關流量、決定保存位置與期間並在調查後刪除擷取 = 流量擷取最小範圍先抽出目標設定保存並刪除篩選並匯出

圖 19: 把最小擷取、交出前縮小、保存與刪除與擷取程序成套決定。

10. 總結

  • 應用程式紀錄「逾時」的下一層,是實際走過線路的封包事實。SYN 沒有回覆、被 RST 切斷、重傳持續、或出現 ZeroWindow,會改變下一步要看的地方。
  • 即使現場不能安裝 Wireshark,也能用 Windows 內建的 pktmon 與 netsh trace 擷取。用內建工具擷取、用自己機器的 Wireshark 讀——這個分工是基本型。
  • pktmon 是四步:註冊篩選器 → pktmon start --capturepktmon stoppktmon etl2pcap。預設截成 128 位元組,要酬載別忘了 --pkt-size 0。看到丟棄位置與原因是只有 pktmon 才有的長處。
  • netsh trace 把一組 ETW 提供者當情境擷取,加上 persistent=yes 就能撐過重開機。用 etl2pcapng 把 ETL 轉成 pcapng 來讀。
  • 在 Wireshark 從 tcp.analysis.flags 開始,依序找交握、RST、重傳、ZeroWindow。先用 Conversations 與 I/O Graph 抓住圖像再縮小會更快。
  • 打到 localhost 的流量不經過 NIC,一般方法擷取不到。用 Npcap 的迴路介面卡或 pktmon 的堆疊內擷取。
  • 兩邊擷取並排,「哪一邊沉默」就能釐清。前提是時鐘同步(w32tm)。重現條件不明的故障,用環形緩衝等待。
  • 即使在 TLS 下,通訊骨架仍可見。把解密(SSLKEYLOGFILE)當成僅限開發環境的手法,把擷取檔本身當機密:把最小擷取、縮小範圍、刪除寫進作業。

封包擷取常被當成「網路專家的工具」,實務上它是 只有與應用程式紀錄並排才開始有意義的應用程式側調查工具。下次調查停在「逾時」一句話時,去看下一層。

相關文章

相關諮詢領域

小村軟體有限公司承接「業務應用程式通訊偶爾失敗、找不到原因」、「只想隔離出只在客戶環境發生的連線錯誤」這類源自通訊的故障調查。擷取設計(在哪裡、擷取什麼、擷取多少)、Wireshark 分析、與應用程式紀錄對照、以及應用程式側修正,我們當成一連串工作處理。

參考連結

  1. Microsoft Learn, pktmon etl2pcap. 說明把 pktmon ETL 紀錄轉成 pcapng 以便在 Wireshark 等工具分析;pcapng 會失去丟棄資訊與堆疊內擷取點資訊,因此轉換前應先用 –drop-only 或 –component-id 縮小。  2 3 4

  2. GitHub, microsoft/etl2pcapng. 說明 etl2pcapng 是 Microsoft 的開源工具,把以 netsh trace start capture=yes 等擷取的 ETL 檔內封包轉成 pcapng,保留介面資訊並把處理程序 ID 寫成封包註解。  2 3 4 5

  3. Microsoft Learn, Pktmon command formatting. 說明 pktmon.exe 可用於 Windows 10 與 Windows Server 2019(版本 1809)以後;快速開始步驟為註冊篩選器 → 開始 → 重現 → 檢查計數器 → 停止並轉換;篩選器最多 32 個、以 OR 結合、不區分來源與目的地;文字輸出中被丟棄的封包帶有 dropReason。  2 3 4 5

  4. Microsoft Learn, Packet Monitor (Pktmon). 說明 Packet Monitor 是 Windows 內建的跨元件診斷工具;在網路堆疊內多個點擷取封包以視覺化路徑;在支援的元件以丟棄原因(MTU Mismatch、Filtered VLAN 等)回報丟棄;並提供各點的封包計數器。  2 3 4

  5. Microsoft Learn, netsh trace. 說明 netsh trace start 的參數,如 scenario、capture、tracefile、maxSize、fileMode(circular 作為環形緩衝)、persistent(跨重開機維持工作階段),以及用 netsh trace convert 把 ETL 轉成文字等。  2 3 4 5

  6. Microsoft Learn, Using Netsh to manage traces. 說明情境是為疑難排解預先定義的提供者集合;用 netsh trace show scenarios / show scenario 檢查;同一時間只能跑一個追蹤工作階段;capture=yes 時的 ipv4.address 等封包篩選器;停止會產生 ETL 與含系統資訊的 .cab。  2 3 4 5 6

  7. Microsoft Learn, Diagnose packet loss. 說明官方調查程序:先用 pktmon 擷取追蹤並檢查本機丟棄原因與統計,結合 Wireshark 的協定層分析,不夠再進到 netsh trace 情境的元件層追蹤。  2 3

  8. Microsoft Learn, pktmon start. 說明用 –capture 開始擷取;–pkt-size 預設 128 位元組、0 記錄整個封包;–file-name 與 –file-size(預設 512MB);以及 –log-mode 值(circular、multi-file、real-time、memory),circular 為預設。  2 3 4

  9. Wireshark Wiki, CaptureSetup/Loopback. 說明在 Windows 以實體 NIC 為目標的一般擷取無法擷取打到 127.0.0.1 的迴路流量;Npcap 的「Adapter for loopback traffic capture」使迴路擷取成為可能;Wireshark 3.0 以後的 Windows 安裝程式內含 Npcap。  2 3 4

  10. Wireshark Wiki, TLS. 說明 Wireshark 可用 SSLKEYLOGFILE 環境變數寫出的工作階段金鑰解密 TLS;支援涵蓋 Firefox、Chrome、以 Chromium 為基礎的 Edge、OpenSSL 系列程式庫等;Microsoft SChannel 不支援這個機制。  2

  11. Microsoft Learn, pktmon counters. 說明 pktmon counters 顯示各監視元件的通過與丟棄計數;–drop-reason 顯示各丟棄計數最近一次丟棄原因;以及用 –live 即時更新。 

  12. Wireshark, Building Display Filter Expressions (Wireshark User’s Guide). 說明顯示篩選器語法、ip.addr 與 tcp.port 等欄位指定、比較運算子,以及用 and/or/not 組合。 

  13. Wireshark, TCP Analysis (Wireshark User’s Guide). 說明 Wireshark TCP 分析旗標清單(tcp.analysis.retransmission、tcp.analysis.duplicate_ack、tcp.analysis.out_of_order、tcp.analysis.zero_window 等)與各旗標被指定的條件。  2

  14. Microsoft Learn, Windows Time service tools and settings. 說明 w32tm 是設定、監視與疑難排解 W32Time 的建議命令列工具,以及 w32tm /stripchart 顯示你與對端電腦的時間偏差(/dataonly、/samples 等選項)。 

  15. Wireshark, Capture files and file modes (Wireshark User’s Guide). 說明擷取檔輸出模式(單一檔、多檔、環形緩衝),以及環形緩衝只保留最新資料以便限制磁碟用量。 

共用相同標籤的最新文章。能以相近的主題延伸理解。

與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。

本文連結到以下服務頁面,歡迎從最接近的入口查看。

常見問題

整理諮詢這個主題時常見的問題。

客戶伺服器不能安裝 Wireshark 時,要怎麼擷取封包?
用 Windows 內建的 pktmon 或 netsh trace,不必再裝軟體就能擷取。pktmon 在提升權限的終端機註冊篩選器,用 pktmon start --capture 開始擷取,再用 pktmon stop 停止。得到的 ETL 可用 pktmon etl2pcap 轉成 pcapng,分析帶回自己電腦的 Wireshark 即可。「用內建工具擷取、用 Wireshark 讀」是安裝受限現場的基本分工。
該用 pktmon 還是 netsh trace?
作業系統有 pktmon(Windows 10 / Windows Server 2019 以後)就先用 pktmon。指令單純,能看到網路堆疊哪個元件丟了封包(丟棄原因),pcapng 轉換也自成一體。netsh trace 較適合在沒有 pktmon 的舊系統擷取、要把 Windows 元件的 ETW 事件當情境一次收集、或要用 persistent=yes 讓擷取撐過重開機時。Microsoft 自己的疑難排解資料也指向這個順序:先 pktmon,不夠再用 netsh trace。
為什麼打到 localhost(127.0.0.1)的流量在 Wireshark 看不到?
打到 localhost 的流量不會經過實體 NIC,而是在作業系統內部迴路路徑折返。以實體介面卡為目標的一般擷取因此從頭就看不到。在 Wireshark 選 Npcap 的「Adapter for loopback traffic capture」就能擷取迴路流量。pktmon 在網路堆疊內擷取,所以也能觀察迴路流量。另一個常見混淆是「localhost」解析成 IPv6 的 ::1,只盯著 127.0.0.1 的畫面就什麼都沒有——請明確指定位址來確認。
封包擷取能看到 HTTPS(TLS)通訊的內容嗎?
應用程式資料的酬載已加密,看不到。但 TCP 連線與切斷、TLS 交握成敗、RST 切斷、哪一邊停止回應這些「通訊骨架」即使加密仍可見,多數逾時調查可以讓 TLS 維持加密繼續做。若需要酬載,可用 SSLKEYLOGFILE 解密,但只有 Firefox、Chrome 系列等部分 TLS 實作支援;Windows 內建 SChannel 不支援。這會把金鑰材料寫出檔案,請當成僅限開發環境的選項。
把擷取檔寄給外部支援窗口安全嗎?
原樣寄出很危險。擷取檔就是通訊本身,可能含明文協定的認證資訊、Cookie、API 金鑰與個人資料。先在擷取時用篩選器與時間窗縮到最小必要,交出前再用 Wireshark 顯示篩選器只抽出目標通訊並匯出。剩下的敏感部分,先與對方約定處理方式(遮罩或另途交付)再寄。擷取檔要保存多久、何時刪除,也請事先決定。

作者檔案

本文作者的個人檔案頁面。

Go Komura

小村軟體有限公司 代表

以 Windows 軟體開發、技術諮詢與故障調查為中心,在難以重現的故障調查與既有資產仍在運作的專案上具有優勢。

回到部落格一覽