更新紀錄(僅初版,2026年08月20日 發布)
- 初次發布
引用本文(DOI(已登錄存檔): 10.5281/zenodo.22176165)
以下 DOI 指向先前登錄的存檔,內容可能與目前正文不同。引用目前正文時,請使用本頁網址。
Go Komura(2026)。〈Windows 封包擷取實務 ── pktmon、netsh trace、Wireshark 怎麼分工〉。小村軟體有限公司。 https://comcomponent.com/zh-TW/blog/windows-packet-capture-pktmon-netsh-wireshark/
- DOI(已登錄存檔)
- 10.5281/zenodo.22176165
- DOI(上次登錄版本)
- 10.5281/zenodo.22176166
「業務應用程式的通訊每個月會失敗幾次。紀錄裡只寫著『逾時』。伺服器端也沒有錯誤,重現條件同樣不明。」——這是通訊故障調查中經常遇到的狀況。
這時想知道的是,究竟是連不上,還是連上之後回應停了。同樣是逾時,接下來該查的地方並不相同。
應用程式紀錄留下的,只有應用程式「決定要寫」的東西。單憑「逾時」這個結果,無法分辨是 SYN 沒有得到回應、是連線建立後伺服器沉默了,還是被 RST 切斷。
去查紀錄下一層、實際流過線路的封包,就是封包擷取。Process Monitor 是從下一層看檔案與登錄檔的存取,封包擷取則是從下一層看通訊。想確認封包是否真的送達目的地時,第 7 章談的雙邊擷取就很重要。
flowchart TB
accTitle: 應用程式紀錄下一層的封包
accDescr: 說明應用程式紀錄只留下決定要寫的內容,結果只有逾時一句;SYN 是否沒有回應、連線建立後是否沉默、是否被 RST 切斷、究竟有沒有送達,只留在實際流過線路的封包裡
log["應用程式紀錄"] --> dec["只留下決定要寫的內容"]
dec --> to["結果只有「逾時」一句"]
to -->|往下一層看| pkt["實際流過線路的封包"]
pkt --> q1["SYN 沒有回應?"]
pkt --> q2["建立後沉默?"]
pkt --> q3["被 RST 切斷?"]
pkt --> q4["送達目的地了嗎?"]
圖 1: 紀錄裡留下的只有結果,逾時的內情只存在下一層的封包裡。
遇到「客戶伺服器不能安裝 Wireshark」的情況,也不必放棄擷取。就算變更管理或資安政策不允許加裝軟體,Windows 本身仍備有 pktmon 與 netsh trace 這兩種內建的擷取手段。
基本是這樣的分工:在現場用內建工具擷取,帶回手邊用 Wireshark 讀。把擷取與分析當成兩件不同的工作來想,即使現場有安裝限制也能把調查推進下去。
本文以中小企業的資訊人員與 Windows 應用程式開發者為對象,整理 pktmon、netsh trace、Wireshark 的取捨與各自的實務步驟。從迴路流量的陷阱、該在用戶端還是伺服器端擷取的判斷、如何面對 TLS 看不到內容的問題,一直到與應用程式紀錄的比對,都依 2026 年 8 月時點的一手資料說明。
從遇到的問題往下讀
| 遇到的問題 | 首先要確認什麼 | 閱讀章節 |
|---|---|---|
| 客戶伺服器不能安裝 Wireshark | 用內建工具擷取、帶回手邊分析的分工 | 工具怎麼選、pktmon 的步驟 |
| 想擷取重新開機直後的通訊 | netsh trace 的情境與持續擷取 | netsh trace 的步驟 |
| 擷取到了,卻不知道該從哪裡讀起 | 顯示篩選器與 TCP 的四個確認點 | 在 Wireshark 怎麼讀 |
| 送往 localhost 的通訊看不到 | 擷取的介面卡,以及 IPv4 與 IPv6 的混淆 | 迴路流量 |
| 看得到重送,卻不知道封包在哪裡消失 | 雙邊擷取與時間差的記錄 | 擷取位置與時間同步 |
| 不知道什麼時候會發生 | 先定好容量的環形緩衝區,以及發生後的停止步驟 | 長時間擷取 |
| 想調查 TLS 通訊/想把擷取檔交出去 | 不解密就知道得了的範圍,以及機密資訊的處理 | TLS 怎麼看、與紀錄比對並交付 |
第一次讀的人,請先掌握第 2 章選工具、第 3 到 4 章擷取、第 5 章閱讀這條主線。第 6 到 8 章是擷取條件與觀測範圍的注意事項,第 9 章則是結合應用程式紀錄下結論的步驟。
1. 先講結論
擷取與分析可以交給不同的工具
在現場用 pktmon 或 netsh trace 擷取,轉成 pcapng 後帶回手邊用 Wireshark 分析。兩者的輸出都是 ETL,原樣是無法用 Wireshark 開啟的。pktmon 用 pktmon etl2pcap,netsh trace 用 Microsoft 開發的開源工具 etl2pcapng。12
工具的選擇順序是先 pktmon,不夠再用 netsh trace,通訊協定的分析交給 Wireshark。Microsoft 的調查指南也是這樣安排的。3
擷取前先決定要留下的資訊與觀測的位置
pktmon 從 Windows 10 / Windows Server 2019 起內建,用註冊篩選器→開始→停止→轉換這四個步驟就能使用。能看出封包在堆疊的哪一處被丟棄,以及丟棄原因,是它獨有的長處。不過,預設留下的只有開頭 128 位元組。要連內容一起讀,就在開始時指定 --pkt-size 0。456
netsh trace 是更早就存在的內建工具。它以情境把一組 ETW 提供者綁在一起,能同時擷取封包與 Windows 內部的事件。要讓擷取跨過重新開機則使用 persistent=yes。78
送往 localhost 的封包不經過實體 NIC,因此不會出現在以實體介面卡為對象的擷取裡。請改用 Npcap 的迴路介面卡,或 pktmon 的堆疊內擷取。9
把讀得出的事實與檔案的處理分開考慮
即使 TLS 讓內容看不到,連線是否建立、TLS 交握的成敗、RST、以及是哪一邊沉默,都還是查得出來。用 SSLKEYLOGFILE 解密則是僅限開發環境的手段。10
另一方面,擷取檔裡裝的就是通訊內容本身。請以可能含有認證資訊與個人資料為前提,把對象與期間壓到最小,並把交給外部之前的篩選也納入擷取步驟。
圖中實線表示始終成立的關係,虛線表示附帶條件的關係(成立條件寫在詳細頁面中各關係的說明中)。關係的完整清單(共 21 條,附依據與可信度)以及主要概念的定義,彙整在知識地圖詳細頁面(日文)。資料:JSON-LD / Turtle
2. 封包擷取的三種工具與取捨
選擇的標準是「現場能裝進什麼」以及「除了封包還想留下什麼」。先比較三種工具的角色。
| pktmon | netsh trace | Wireshark | |
|---|---|---|---|
| 取得方式 | Windows 10 / Windows Server 2019 以後內建4 | Windows 長期內建(pktmon 出現之前的作業系統也能用) | 需要另外安裝 |
| 主要角色 | 封包擷取、丟棄偵測、計數器 | 封包擷取 + Windows 元件的 ETW 事件擷取 | 分析擷取到的資料(真正的主角) |
| 輸出格式 | ETL(用 etl2pcap 轉成 pcapng)1 | ETL+.cab(用 etl2pcapng 轉成 pcapng)82 | pcapng |
| 獨有的長處 | 看得出堆疊內的丟棄位置與丟棄原因5 | 以情境為單位綁定提供者、跨重新開機擷取7 | 顯示篩選器、TCP 分析、統計、GUI |
| 權限 | 系統管理員權限 | 系統管理員權限 | 擷取需要等同系統管理員(只做分析則不必) |
把 pktmon 與 netsh trace 分配到「擷取」、Wireshark 分配到「閱讀」的角色來想,會比較容易理清。Wireshark 本身也有擷取功能,但在不能安裝的現場就用不上。
把內建工具的 ETL 轉成文字來讀也辦得到。不過比起沒有顯示篩選器與 TCP 分析、只能用肉眼看,轉成 pcapng 再用 Wireshark 分析,調查會順利得多。
flowchart TB
accTitle: 擷取交給內建工具,閱讀交給 Wireshark
accDescr: 說明現場用 pktmon 或 netsh trace 擷取 ETL,各自用對應的轉換工具轉成 pcapng,再帶回手邊用 Wireshark 分析的分工
pk["pktmon(內建)"] --> etla["ETL 檔"]
ns["netsh trace(內建)"] --> etlb["ETL+.cab"]
etla -->|pktmon etl2pcap| pcap["pcapng"]
etlb -->|etl2pcapng| pcap
pcap --> ws["帶回手邊用 Wireshark 分析"]
圖 2: 現場用內建工具擷取 ETL,轉成 pcapng,再帶回手邊用 Wireshark 讀。
Microsoft 的封包遺失調查指南也是同樣的架構:先用 pktmon 擷取並釐清原因,若還不夠就進到 netsh trace start scenario=InternetClient 這類元件層級的追蹤,通訊協定的行為則交給 Wireshark 分析。3
另外,要讀懂封包上照出了什麼,腦中先有 Ethernet、IP、TCP、應用程式資料層層堆疊的圖像,理解會快得多。分層的解剖在「把OSI參考模型看得明明白白」有圖解。
3. pktmon 實務 ── 篩選器→開始→停止→轉換
擷取的基本是註冊篩選器→開始→停止→轉換這四個步驟。結束之後還要把篩選器清乾淨。以下都在系統管理員權限的終端機執行。
開始前請先確認既有的篩選器,以及結束後的清理方式。最後那行 pktmon filter remove 不是指定名稱刪除的操作,它會把已註冊的篩選器全部刪掉。在與其他調查共用的環境,請先用 pktmon filter list 確認。
:: 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. 重現現象。等待期間可以用計數器確認流量與丟棄
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
flowchart TB
accTitle: pktmon 的基本步驟
accDescr: 說明先用註冊篩選器縮小對象再開始擷取,重現現象後停止,用 etl2pcap 轉成 pcapng,最後刪除註冊過的篩選器這一連串流程
fa["1. 用 filter add 縮小對象"] --> st["2. 用 start --capture 開始擷取"]
st --> re["3. 重現現象"]
re -.-> ct["用 counters 確認流量與丟棄"]
re --> sp["4. 用 stop 停止"]
sp --> cv["用 etl2pcap 轉成 pcapng"]
cv --> rm["5. 用 filter remove 清理"]
圖 3: pktmon 從註冊篩選器開始,擷取、停止、轉換之後,再明確清掉篩選器。
執行指令之前先把下面四點決定好,可以減少重採的次數。
擷取前要確認的事項
縮小對象:多個篩選器是 OR 條件
篩選器要在開始擷取之前註冊。Microsoft 的文件也認為擷取全部流量雜訊太多,強烈建議在開始前先套用篩選器。篩選器可以用 IP 位址、連接埠、MAC 位址、通訊協定、VLAN ID 等指定,最多能註冊 32 個。多個篩選器之間是「符合任何一個就記錄」的 OR 條件。4
縮小方向:不區分來源與目的地
pktmon 的篩選器不區分來源與目的地。-i 192.168.10.20 的意思是「這個位址為來源或目的地的封包」。方向的篩選,要在轉換之後用 Wireshark 的顯示篩選器處理。4
決定記錄範圍:只要標頭,還是整個封包
預設的封包大小是 128 位元組。只分析標頭的話這樣就夠,但要連應用程式資料一起讀,就用 --pkt-size 0 記錄整個封包。6
決定容量:環形緩衝區與即時顯示
紀錄預設是 circular(環形緩衝區)模式,預設大小 512MB。除了可以用 --file-size 改上限,改成 --log-mode real-time 就會即時顯示在畫面上,而且不會產生紀錄檔。先用即時顯示確認「想看的通訊確實看得到」,再布置正式的擷取,就能避免白忙一場。6
flowchart TB
accTitle: pktmon 篩選器的作用方式
accDescr: 說明註冊的多個篩選器以符合任何一個就記錄的 OR 條件運作,指定的位址不區分來源與目的地,因此方向的篩選要在轉換後用 Wireshark 的顯示篩選器處理
f1["篩選器 1"] --> orc["符合任一個就記錄"]
f2["篩選器 2"] --> orc
f3["篩選器 3(最多 32 個)"] --> orc
orc --> rec["寫入擷取紀錄(OR 條件)"]
rec -.-> nodir["不區分來源與目的地"]
nodir -.-> ws["方向在轉換後用 Wireshark 縮小"]
圖 4: 多個篩選器以 OR 條件運作,來源還是目的地這個方向問題,在轉換後用 Wireshark 縮小。
3.1. pktmon 才有的長處 ── 看得出封包在哪裡被丟掉
pktmon 和 Wireshark 不同的獨有價值在於,它不是在 NIC 的單一位置,而是在網路堆疊內的多個位置擷取封包,並能回報封包被丟棄(drop)的位置與原因。因為看得出封包抵達了哪個元件、又在哪裡消失,就能從「MTU 不一致」「VLAN 篩選」這類丟棄原因直接接到原因,不必逐一窮舉。5
flowchart TB
accTitle: pktmon 在堆疊內的多個位置擷取
accDescr: 說明 pktmon 不是在 NIC 的單一位置而是在網路堆疊內的多個位置擷取封包,因此能連同原因回報封包抵達了哪個元件、又在哪裡被丟棄
pin["封包"] --> p1["在位置 1 擷取"]
p1 --> p2["在位置 2 擷取"]
p2 --> p3["在位置 3 被丟棄"]
p3 -.-> rz["回報丟棄位置與丟棄原因"]
rz -.-> ex["例如 MTU 不一致或 VLAN 篩選"]
圖 5: 因為在堆疊內的多個位置擷取,所以能連同原因知道封包走到哪、又在哪裡被丟掉。
先看計數器,必要時再用文字紀錄確認
- 用
pktmon list可以確認會被監視的網路元件(NIC、通訊協定堆疊、篩選驅動程式等)清單與 ID。 - 用
pktmon counters --drop-reason可以列出各元件的通過/丟棄計數器,以及最近一次的丟棄原因。在分析紀錄之前拿來做第一輪釐清很方便。11 - 用
pktmon etl2txt轉成文字後,被丟棄的封包會帶著drop與 dropReason(丟棄原因)輸出。4
「會不會在送到應用程式之前,就被作業系統的某處丟掉了」這種懷疑,光盯著 Wireshark 是無法了結的。例如要釐清因輸入規則不完整而被防火牆擋掉的情況(「Windows 防火牆與業務應用程式」),這個功能就很有效。
交給 Wireshark 之前,先縮小擷取位置
pktmon 會在堆疊內的多個位置記錄同一個封包。就這樣轉成 pcapng 時,同一個封包可能會重複出現。因為 pcapng 不會承接「是在哪個元件擷取的」這項資訊。
如果目的是用 Wireshark 閱讀,就用 pktmon etl2pcap 的 --component-id 把位置縮小之後再轉換。也可以用 --drop-only 把丟棄的封包單獨放到另一個檔案。1
flowchart TB
accTitle: 轉成 pcapng 後同一個封包重複出現的原因
accDescr: 說明 pktmon 會在堆疊內的多個位置記錄同一個封包,而 pcapng 不會承接是在哪個元件擷取的資訊,因此可能重複出現;標準作法是用 component-id 縮小位置,或用 drop-only 把丟棄單獨放到另一個檔案再轉換
same["同一個封包在多個位置被記錄"] --> conv["就這樣轉成 pcapng"]
conv --> lost["擷取位置的資訊沒有被承接"]
lost --> dup["同一個封包重複出現"]
dup --> c1["用 --component-id 縮小位置"]
dup --> c2["用 --drop-only 另存一個檔案"]
圖 6: 擷取位置的資訊不會被帶進 pcapng,所以標準作法是先縮小位置再轉換。
4. netsh trace 實務 ── 情境與 ETL,跨重新開機的擷取
netsh trace 是比 pktmon 更早就內建於 Windows 的追蹤擷取機制。它的特徵是能以「情境」為單位,一次啟用與該問題相關的整組 ETW 提供者。8
:: 確認可用的情境,以及情境中包含哪些提供者
netsh trace show scenarios
netsh trace show scenario netconnection
:: 開始擷取。含封包擷取,1GB 的循環緩衝區
netsh trace start scenario=netconnection capture=yes tracefile=C:\temp\nettrace.etl maxSize=1024 filemode=circular
:: 重現現象之後停止(合併處理會花一點時間)
netsh trace stop
用 netsh trace 時要決定的擷取條件
要連封包一起留下就加上 capture=yes
加上 capture=yes 就會啟用封包擷取,並能用 ipv4.address=192.168.10.20 這類擷取篩選器縮小對象。篩選器的清單可以用 netsh trace show capturefilterHelp 確認。8
除了 ETL,還會留下 .cab 裡的環境資訊
停止之後,除了 ETL 檔還會產生 .cab 檔。.cab 裡含有介面卡設定與作業系統組建等系統資訊,可以順便完成環境資訊的蒐集。8
開始前先確認既有的工作階段
追蹤工作階段同時只能執行一個。開始另一次擷取之前,請用 netsh trace show status 確認沒有一直跑著沒停的工作階段。8
重新開機直後才發生的現象要用 persistent=yes
加上 persistent=yes,工作階段就能跨過重新開機繼續保留。像「重新開機直後只有一瞬間通訊失敗」「開機時服務連線失敗」這種來不及用手動開始擷取的現象,正是 netsh trace 獨有的舞台。7
flowchart TB
accTitle: netsh trace 的情境擷取
accDescr: 說明指定情境開始後會一次啟用整組 ETW 提供者,加上 capture=yes 連封包也會擷取,停止之後會產生 ETL 檔與 .cab 檔的流程
sc["指定情境開始"] --> pv["啟用整組提供者"]
sc -->|capture=yes| pc["連封包也擷取"]
pv --> re["重現現象"]
pc --> re
re --> sp["用 stop 停止"]
sp --> etl["ETL 檔"]
sp --> cab[".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
封包與 Windows 內部的事件,讀法不一樣
另外,ETW 事件那一側(情境提供者記錄下來的 Windows 內部事件)不會被轉成 pcapng。若連事件也想讀,就用 netsh trace convert input=C:\temp\nettrace.etl 轉成文字等格式,或用 Windows Performance Analyzer 之類的工具開啟。73
flowchart TB
accTitle: netsh trace 的 ETL 讀法分成兩條路
accDescr: 說明 ETL 裡的封包用 etl2pcapng 轉成 pcapng 再用 Wireshark 讀,而 ETW 事件不會被轉成 pcapng,因此要用 netsh trace convert 或 Windows Performance Analyzer 來讀
etl["netsh trace 的 ETL"] --> pk["封包"]
etl --> ev["ETW 事件"]
pk -->|etl2pcapng| pc["轉成 pcapng"]
pc --> ws["用 Wireshark 讀"]
pc -.-> pid["處理程序 ID 留在註解裡"]
ev -.-> no["不會被轉成 pcapng"]
no --> alt["用 convert 或 WPA 讀"]
圖 8: ETL 當中的封包轉成 pcapng 來讀,ETW 事件則用別的方式讀。
5. 在 Wireshark 閱讀的入門 ── 顯示篩選器與 TCP 分析
分析依照縮小對象→確認 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
把逾時拆成四個確認點
用 tcp.analysis.flags 抓到方向之後,依下列順序確認。特別是重送,它只是「沒有收到 ACK」這項觀測,重點在於不要只憑單邊就斷定是去程還是回程遺失。
1. 連線建立了嗎:SYN、SYN/ACK、ACK
三向交握有沒有完成。SYN→SYN/ACK→ACK 這三發是否齊全。如果一直重複送 SYN 卻沒有回應,代表沒有送到對方,或是在途中被默默丟棄(防火牆的典型樣態)。
2. 是否被強制切斷:RST 的時間點與來源
RST 是從哪一邊飛過來的。對 SYN 立刻回 RST,代表目的連接埠沒有任何程式在接聽;連線建立之後才出現的 RST,代表其中一邊強制切斷了連線。RST 的來源 IP 就是「誰切斷的」的直接證據。
3. ACK 有沒有回來:重送是否持續
重送是不是一直持續。同一個區段反覆重送,是傳送端沒有收到確認回應(ACK)的訊號。究竟是去程的資料遺失,還是回程的 ACK 遺失,單邊的擷取無法確定(正因如此,下一章的「兩邊都擷取」才有效)。重送與逾時的深入探討,在「TCP 重送導致工業相機通訊停頓的原因與釐清方法」有詳細說明。
4. 接收端是不是塞住了:ZeroWindow
有沒有出現 ZeroWindow。這是接收端應用程式沒有從通訊端讀走資料、接收緩衝區已經滿了的訊號。它是讓人懷疑接收端應用程式的設計(「TCP 中「Send 單位=Receive 單位」的誤解」)而不是網路的依據。
flowchart TB
accTitle: 逾時調查中尋找形狀的順序
accDescr: 說明依三向交握是否完成、有無 RST 及其來源、重送是否持續、ZeroWindow 的順序確認,藉此對原因抓出方向的流程
hs{"SYN 有回應嗎?"} -->|否| ng["疑似沒送到就被丟棄(防火牆的典型)"]
hs -->|是| rs{"有飛出 RST 嗎?"}
rs -->|是| who["RST 的來源就是切斷的一方"]
rs -->|否| rt{"重送持續中嗎?"}
rt -->|是| ack["沒有收到 ACK 的訊號"]
rt -->|否| zw{"有出現 ZeroWindow 嗎?"}
zw -->|是| app["接收端應用程式沒在讀的訊號"]
圖 9: 依交握、RST、重送、ZeroWindow 的順序找形狀,就能縮小接下來要查的地方。
通訊量大的時候,先用統計綜覽再讀
在逐一閱讀封包之前,先用統計找出目標對話與時段,也是有效的作法。
| 功能 | 要看什麼 | 下一步操作 |
|---|---|---|
| [統計]→[對話(Conversations)] | 哪一組 IP 配對、連接埠配對,從何時到何時,講了多少 | 只篩出目標對話 |
| [統計]→[輸入輸出圖(I/O Graph)] | 時間軸上的流量。「從這個時刻起只有單一方向沒了聲音」之類的變化 | 縮小要調查的時段 |
| 在對話上按右鍵→[追蹤]→[TCP 串流] | 該連線的往來內容 | 把明文的往來從頭讀到尾。TLS 看不到內容時的處理方式見第 8 章 |
flowchart TB
accTitle: 先用統計綜覽再縮小到目標對話
accDescr: 說明先用 Conversations 一覽哪些通訊在什麼時候講了多少以鎖定目標對話,用 I/O Graph 掌握沒了聲音的時段,再篩出目標對話並用 TCP 串流從頭讀到尾的流程
ov["用統計綜覽整體"] --> cv["用 Conversations 列出對話"]
ov --> io["用輸入輸出圖看流量"]
cv --> flt["只篩出目標對話"]
io -.-> mute["看得出沒了聲音的時刻"]
flt --> fs["用 TCP 串流從頭讀到尾"]
圖 10: 在逐一閱讀封包之前先用統計綜覽,縮小到目標對話再從頭讀到尾。
6. 迴路流量的陷阱 ── 送往 localhost 的封包不經過 NIC
想調查同一台電腦內應用程式之間的通訊 ── 例如業務應用程式連到 localhost:8080 的中介服務 ── 卻卡在「Wireshark 什麼都沒出現」,是經典的陷阱。
原因很清楚。因為送往 localhost(127.0.0.1)的通訊不會經過實體 NIC,而是在作業系統內部的迴路路徑折返。以實體介面卡為對象的一般擷取,從一開始就不會出現它。9
flowchart TB
accTitle: 送往 localhost 的通訊不出現在擷取裡的原因
accDescr: 說明送往 localhost 的通訊不經過實體 NIC,而是在作業系統內部的迴路路徑折返,因此不會出現在以實體介面卡為對象的一般擷取裡
app["應用程式"] --> stack["網路堆疊"]
stack -->|送往外部| nic["實體 NIC"]
nic --> seen["出現在一般擷取裡"]
stack -->|送往 localhost| lo["在作業系統內部折返"]
lo -.-> miss["不會出現在一般擷取裡"]
lo -.-> alt["用 Npcap 迴路或 pktmon 擷取"]
圖 11: 送往 localhost 的封包在 NIC 之前就折返,所以實體介面卡的擷取從一開始就看不到。
讓擷取方式配合迴路路徑
對策有兩種。
- 用 Wireshark 擷取時:把擷取對象選成 Npcap 提供的「Adapter for loopback traffic capture」。Windows 版 Wireshark(3.0 以後)的安裝程式內含 Npcap,所以已經裝了 Wireshark 的環境不必再多做什麼。9
- 用內建工具擷取時:pktmon 不是在 NIC 的外側,而是在網路堆疊內部的多個位置擷取5,所以也能用來觀察迴路流量。想求保險的話,在布置正式的重現等待之前,先用
pktmon start -c -m real-time的即時顯示,在該環境確認目標的迴路流量確實看得到。
在位址的指定上,也有兩處容易搞混
localhost 指的不一定是 127.0.0.1
「localhost」有可能被解析成 IPv6 的 ::1。應用程式連的是 IPv6 的 ::1,調查的一方卻只看 127.0.0.1(IPv4),於是誤判成「沒有通訊」。顯示篩選器要像 ip.addr == 127.0.0.1 || ipv6.addr == ::1 這樣兩邊都張,或是把應用程式的連線目標設定成明確的位址。9
就算指定自己的實體 IP,也不一定會經過實體 NIC
送往自己實體 IP 的通訊,也不會跑到線路上。同一台電腦從 192.168.10.5 連到 192.168.10.5 時,即使目的地是實體 IP,作業系統仍然在內部折返。請記住「指定了實體 IP 就應該會經過 NIC」並沒有保證。
flowchart TB
accTitle: localhost 被解析成 IPv6 造成的混淆
accDescr: 說明應用程式的 localhost 可能被解析成 IPv6 的 ::1 而完成連線,調查的一方只看 127.0.0.1 就會誤判成沒有通訊,因此要把顯示篩選器張到兩邊,或把連線目標以位址明確指定後再確認
app["應用程式連到 localhost"] --> v6["實際被解析成 ::1(IPv6)"]
look["調查的一方只看 127.0.0.1"] --> none["畫面上什麼都沒出現"]
v6 --> none
none --> fix1["把篩選器張到兩個位址"]
none --> fix2["把連線目標以位址明確指定"]
圖 12: 小心 localhost 被解析成 ::1,只看 127.0.0.1 就誤判成「沒有通訊」的混淆。
7. 在哪裡擷取 ── 單邊、雙邊,以及時間同步
單邊能得到的,是從那個擷取點看到的事實。要先看整體樣貌,還是要確認通訊是在去程還是回程消失,決定了擷取位置的選擇。
| 擷取位置 | 知道得了什麼 | 適合的情況 |
|---|---|---|
| 只在用戶端 | 自己送出了什麼、回來了什麼 | 先掌握整體樣貌。碰不到伺服器時 |
| 只在伺服器端 | 要求是否送到、是否送出了回應 | 用戶端很多、無法鎖定特定一台時 |
| 兩邊同時 | 封包在路徑的哪裡消失、是哪一邊沉默 | 想確定責任分界時 |
就算在用戶端看到重送一直持續,只有單邊也分不出下面兩種情況。
- 送出的封包在抵達伺服器之前就消失了。
- 封包送到了伺服器,但回應在回程消失了。
兩邊都擷取再比對,就能像「用戶端送出了、伺服器沒有收到」這樣,確定是哪一邊沉默。想確定責任分界(應用程式、作業系統、網路裝置、對方)的場合,一開始就把雙邊擷取安排好。
flowchart TB
accTitle: 單邊擷取與雙邊擷取各自知道得了什麼
accDescr: 說明單邊的擷取分不出是去程的封包消失還是回程的回應消失,兩邊都擷取再比對才能確定是哪一邊沉默
one["只在單邊擷取"] --> fact["只有從自己位置看到的事實"]
fact --> und["分不出是去程消失還是回程消失"]
both["兩邊同時擷取"] --> mt["比對"]
mt --> fix["確定是哪一邊沉默"]
mt -.-> pre["前提是兩台機器的時間同步"]
圖 13: 單邊只知道得了看到的事實,兩邊比對之後責任分界才第一次得以確定。
7.1. 比對的前提是時間同步
要比對兩邊的擷取,兩台機器的時鐘必須一致。開始擷取之前,先確認並記錄時間的偏差。
:: 確認時間同步的狀態(同步來源、最後一次同步時間)
w32tm /query /status
:: 實測與對方伺服器的時間差(5 個取樣)
w32tm /stripchart /computer:sv-app01 /dataonly /samples:5
w32tm /stripchart 是顯示自己與對方電腦時間位移的指令,比對時可以作為「伺服器端的時間偏了 +0.8 秒」這種校正的依據。14 偏差很大的環境,先把時間同步修好再擷取,結果反而比較快。
flowchart TB
accTitle: 比對之前確認時間差的步驟
accDescr: 說明先用 w32tm 確認自己的時間同步狀態,再用 stripchart 實測並記錄與對方伺服器的時間差,比對時把該偏差當作校正依據的流程,以及偏差很大的環境要先修好時間同步再擷取
st["用 query 確認同步狀態"] --> mc["用 stripchart 實測時間差"]
mc --> rc["把偏差記錄下來"]
rc --> use["比對時作為校正的依據"]
mc -.-> big["偏差很大就先修好同步"]
圖 14: 在擷取之前實測並記錄時間差,比對時當作校正的依據。
7.2.「不知道何時會發生」就用環形緩衝區
重現條件不明的現象,基本作法是讓環形緩衝區一直擷取著,等發生了再停止。
- pktmon:預設就是 circular 模式。用
--file-size指定上限(MB),會從舊的封包開始覆寫。6 - netsh trace:像
maxSize=1024 filemode=circular這樣指定。7 - Wireshark:在[擷取]→[選項]→[輸出]可以設定「多個檔案 + 環形緩衝區」。依檔案大小或時間輪替,只保留最新的 N 個檔案,因此能在磁碟用量有上限的狀態下長時間跑。15
不只是容量,連發生後怎麼停也要先決定
無論用哪一種,都請和現場人員講好這個作法:現象一發生,「先記下發生時間」再停止擷取。環形緩衝區等得越久,過去的內容就被抹掉越多,從發生到停止的步驟一長,關鍵的那一段就會被覆寫掉。
flowchart TB
accTitle: 用環形緩衝區守株待兔的作法
accDescr: 說明重現條件不明的現象要讓環形緩衝區一直擷取著等待,現象發生後先記下發生時間再迅速停止,以及停得太晚就會從舊的封包開始被覆寫、關鍵的那一段會消失
st["開始環形緩衝區擷取"] --> wt["一直擷取著等待"]
wt --> ev["現象發生"]
ev --> memo["記下發生時間"]
memo --> sp["迅速停止"]
wt -.-> ow["從舊的封包開始覆寫"]
ow -.-> late["停得太晚關鍵的那一段就消失"]
圖 15: 環形緩衝區等得越久過去就被抹掉越多,記下發生時間後就迅速停止。
8. TLS 讓內容看不到的問題 ── 看不到也知道得了的事
解密之前,先確認通訊的骨架
現在的業務通訊大多是 TLS(HTTPS)。常有人覺得「都加密了,擷取也是白費工夫」,但逾時調查想知道的事情,大半在維持加密的狀態下仍然知道得了。
- TCP 連線是否建立(三向交握)
- TLS 交握進行到哪一步 ── ClientHello 之後有沒有回 ServerHello、交握途中是否被 RST 或 alert 切斷
- ClientHello 上帶的連線目標主機名稱(SNI),以及協商出來的 TLS 版本
- 建立之後是哪一邊停止傳送。沒有回應的位置、重送、RST,還是正常關閉(FIN)
也就是說,要釐清「連不上」「中途斷掉」「沒有回應」,幾乎不需要解密內容。因為加密失去的是「說了什麼」,而「誰在什麼時候沉默」仍然留著。
flowchart TB
accTitle: TLS 擷取看得到與看不到的東西
accDescr: 說明加密後看不到的只有應用程式資料的內容,而 TCP 連線的建立、TLS 交握的成敗、SNI 與 TLS 版本、RST 以及是哪一邊沉默,在維持加密的狀態下仍然知道得了
tls["TLS 通訊的擷取"] --> vis["看得到的東西"]
tls --> hid["看不到的東西"]
vis --> v1["TCP 連線的建立"]
vis --> v2["TLS 成敗與 SNI"]
vis --> v3["RST 與哪一邊沉默"]
hid --> h1["應用程式資料的內容"]
圖 16: 加密失去的只有內容,通訊的骨架在 TLS 狀態下仍然讀得出來。
只有確實需要內容時,才去確認能不能解密
即使如此還是需要內容時,Wireshark 具備用 SSLKEYLOGFILE 環境變數寫出的工作階段金鑰解密 TLS 的機制。不過支援的只有 Firefox、Chrome、以 Chromium 為基礎的 Edge 等瀏覽器,以及 OpenSSL 系列的程式庫等部分實作,Windows 內建的 SChannel(使用 WinHTTP 或 WinINET 的應用程式)並不支援這個機制。10 工作階段金鑰會被寫出到檔案,等於拿到那個檔案的人就能把通訊全部解密,因此就性質而言,應該把它定位成不是正式環境使用的手段,而是開發環境的重現與偵錯用。
flowchart TB
accTitle: SSLKEYLOGFILE 解密的機制與限制
accDescr: 說明用 SSLKEYLOGFILE 寫出的工作階段金鑰可以讓 Wireshark 解密 TLS,但支援的只有 Firefox 與 Chrome 系列等部分實作而 SChannel 不支援,而且拿到金鑰檔的人就能解密通訊,因此是僅限開發環境的手段
env["設定 SSLKEYLOGFILE"] --> key["把工作階段金鑰寫出到檔案"]
key --> ws["用 Wireshark 解密後閱讀"]
key -.-> risk["持有金鑰的人可以全部解密"]
risk -.-> dev["定位成僅限開發環境"]
env -.-> sup["支援的只有部分 TLS 實作"]
sup -.-> sch["SChannel 不支援"]
圖 17: 寫出工作階段金鑰就能解密,但支援的實作有限,金鑰的性質也讓它只能是僅限開發環境的手段。
另外,經由企業內部 Proxy 的通訊,擷取上照出的目的地會變成 Proxy 伺服器,TLS 則走在 CONNECT 通道裡面。至於應用程式究竟會朝哪個 Proxy 去這個更前面的問題,整理在同日發布的姊妹文章「企業內部 Proxy 與 Windows 應用程式 ── 整理 WinINET、WinHTTP、.NET 的 Proxy 解析」。
9. 與應用程式紀錄的比對 ── 把時間排在同一條軸上
光靠擷取本身就能得出結論的情況,其實不多。實務上的關鍵,是把應用程式紀錄的一行與封包的一次往返,排在同一條時間軸上。
把紀錄的一行換成封包上的觀測事實
先從例外出現的時間,往回找出開始通訊的區間。
步驟 1:從例外時間與逾時值找出開始時間
從應用程式紀錄鎖定現象發生的時間(例如 10:23:41 出現逾時例外)。若逾時值是 30 秒,開始應該在 10:23:11 前後。
步驟 2:把 Wireshark 切成日期時間顯示,縮到對應區間
把 Wireshark 的時間顯示切換成[檢視]→[時間顯示格式]→[日期與時間],再用顯示篩選器縮小到對應區間(也能用時間篩選,例如 frame.time >= "2026-08-20 10:23:00" && frame.time <= "2026-08-20 10:24:00")。
步驟 3:確認交握、RST、重送、ZeroWindow
在該區間依第 5 章的順序(交握→RST→重送→ZeroWindow)確認。如果能比對到「紀錄的逾時時間往前 30 秒送出 SYN,之後只有 SYN 的重送」,紀錄裡的「逾時」就換成了「在這個擷取點完全沒有回應回來」這項觀測事實(至於是 SYN 沒送到對方,還是回應的 SYN/ACK 在回程遺失,光靠這個擷取點無法確定。想確定就要和伺服器端的擷取比對)。
步驟 4:校正時間差與時區
擷取的時間與紀錄的時間之間的偏差(7.1 節量到的時間差,以及紀錄的時區標記)一定要校正。比對誤差只要有幾秒,就會把別的通訊當成元兇。
flowchart TB
accTitle: 應用程式紀錄與封包的比對步驟
accDescr: 說明從應用程式紀錄鎖定現象發生的時間,用逾時值反推開始時間,在 Wireshark 縮小到對應區間並依序確認形狀,再校正時間偏差排到同一條時間軸上的步驟
lg["1. 用紀錄鎖定現象的時間"] --> rev["用逾時值反推開始時間"]
rev --> flt["2. 用顯示篩選器縮小對應區間"]
flt --> chk["3. 依第 5 章的順序確認形狀"]
chk --> adj["4. 校正時間的偏差"]
adj --> done["紀錄的一句話變成觀測事實"]
圖 18: 從紀錄的時間縮小區間,確認形狀,校正時間差,排到同一條軸上。
交給第三方之前,只取出必要的對話
把調查結果交給第三方(廠商、電信業者、客戶的網路人員)時,先用篩選器削掉雜訊再交出去既是禮貌,也是安全措施。在 Wireshark 用顯示篩選器只留下目標對話,再用[檔案]→[匯出指定封包]儲存「只有顯示中的封包」,就能做出只含必要範圍的小 pcapng。
從擷取之前就先決定機密資訊的保存與刪除
擷取檔裡裝的就是通訊內容本身。可能含有明文通訊協定的認證資訊、HTTP 的 Cookie 與 API 金鑰、郵件或報表的內容,以及個人資料。下列三點請和擷取步驟成套決定好。
- 最小必要的擷取:用擷取前的篩選器(第 3、4 章)縮小對象,期間也壓到最短。不要在客戶環境「先全部擷取再說」
- 交出前的篩選:只匯出目標對話,不要夾帶無關第三方的通訊。若仍留有機密部分,就與收件方約定遮蔽或改用其他方式
- 保存與刪除:決定擷取檔的存放位置、期限與刪除方式,調查完成後就刪掉
flowchart TB
accTitle: 交出擷取檔之前要決定的三件事
accDescr: 說明擷取檔裡裝的就是通訊內容本身,因此要用擷取前的篩選器與期間縮到最小必要、交出前只抽出目標對話以免夾帶無關通訊、並決定存放位置與期限在調查完成後刪除,這三點要和擷取步驟成套決定
cap["擷取檔裡裝的就是通訊內容"] --> p1["擷取壓到最小必要"]
cap --> p2["交出前只抽出目標"]
cap --> p3["決定保存期限並刪除"]
p2 -.-> exp["用顯示篩選器縮小後匯出"]
圖 19: 最小限度的擷取、交出前的篩選、保存與刪除這三點,要和擷取步驟成套決定。
10. 總結
- 應用程式紀錄「逾時」的下一層,有實際流過線路的封包這項事實。是 SYN 沒有回應、是被 RST 切斷、是重送一直持續,還是 ZeroWindow,接下來要查的地方都不一樣。
- 即使是不能安裝 Wireshark 的現場,也能用 Windows 內建的 pktmon 與 netsh trace 擷取。擷取交給內建工具、閱讀交給手邊的 Wireshark,這個分工就是基本形。
- pktmon 是註冊篩選器→
pktmon start --capture→pktmon stop→pktmon etl2pcap四個步驟。預設會截到 128 位元組,要連內容一起讀就別忘了--pkt-size 0。看得出丟棄位置與原因,是只有 pktmon 才有的長處。 - netsh trace 能以情境把一組 ETW 提供者綁起來擷取,加上
persistent=yes就能跨過重新開機。ETL 用 etl2pcapng 轉成 pcapng 再讀。 - 在 Wireshark 從
tcp.analysis.flags開始讀,依交握、RST、重送、ZeroWindow 的順序找形狀。先用 Conversations 與 I/O Graph 綜覽再縮小會比較快。 - 送往 localhost 的封包不經過 NIC,一般方法擷取不到。請用 Npcap 的迴路介面卡,或 pktmon 的堆疊內擷取。
- 兩邊都擷取再比對,「是哪一邊沉默」就能確定。它的前提是時間同步(w32tm)。重現條件不明的現象,就用環形緩衝區守株待兔。
- 即使在 TLS 下,通訊的骨架仍然看得到。請把解密(SSLKEYLOGFILE)定位成僅限開發環境的手段,並把擷取檔本身當成機密,把最小擷取、篩選、刪除都納入作業流程。
封包擷取常被當成「網路專家的工具」,但實際上它是只有和應用程式紀錄比對才開始產生意義的、應用程式端的調查工具。下次調查停在「逾時」一句話時,請去看它的下一層。
相關文章
- TCP 重送導致工業相機通訊停頓的原因與釐清方法
- TCP 中「Send 單位=Receive 單位」的誤解 ── 把 TCP 視為位元組串流來設計接收邏輯
- 把OSI參考模型看得明明白白 ── 解剖一個HTTP請求的七層結構
- Process Monitor(ProcMon)實戰指南 ── 在10分鐘內找出「設定未被讀取」「ACCESS DENIED」的原因
- Windows 防火牆與業務應用程式 ── 受信規則要在安裝程式中登錄
- 企業內部 Proxy 與 Windows 應用程式 ── 整理 WinINET、WinHTTP、.NET 的 Proxy 解析
相關諮詢領域
小村軟體有限公司承接「業務應用程式的通訊偶爾失敗,卻找不到原因」「想釐清只在客戶環境發生的連線錯誤」這類以通訊為起點的問題調查。從封包擷取的設計(在哪裡、擷取什麼、擷取多少),到 Wireshark 的分析、與應用程式紀錄的比對,以及應用程式端的修正,我們當成一連串的工作處理。
參考連結
-
Microsoft Learn, pktmon etl2pcap. 說明把 pktmon 的 ETL 紀錄轉成可用 Wireshark 等工具分析的 pcapng 格式;pcapng 格式會失去丟棄資訊與堆疊內擷取位置的資訊,因此應先用 –drop-only 或 –component-id 縮小之後再轉換。 ↩ ↩2 ↩3
-
GitHub, microsoft/etl2pcapng. 說明它是把以 netsh trace start capture=yes 等擷取的 ETL 檔內封包轉成 pcapng 格式的 Microsoft 開源工具,會保留介面資訊,並把處理程序 ID 寫成封包註解。 ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Diagnose packet loss. 說明官方的調查步驟:封包遺失的調查先用 pktmon 擷取追蹤,確認本機的丟棄原因與統計,再結合 Wireshark 的通訊協定層級分析,若仍不足才進到 netsh trace 情境的元件層級追蹤。 ↩ ↩2 ↩3
-
Microsoft Learn, Pktmon command formatting. 說明 pktmon.exe 可用於 Windows 10 與 Windows Server 2019(版本 1809)以後;快速開始的步驟為註冊篩選器→開始→重現→確認計數器→停止並轉換;篩選器最多 32 個、以 OR 結合且不區分來源與目的地;文字輸出中被丟棄的封包會帶有 dropReason。 ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Packet Monitor (Pktmon). 說明 Packet Monitor 是 Windows 內建的跨元件診斷工具;在網路堆疊內的多個位置擷取封包以視覺化封包的路徑;在支援的元件上帶著丟棄原因(MTU Mismatch、Filtered VLAN 等)回報丟棄;並提供各位置的封包計數器。 ↩ ↩2 ↩3 ↩4
-
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
-
Microsoft Learn, netsh trace. 說明 netsh trace start 的 scenario、capture、tracefile、maxSize、fileMode(circular 作為環形緩衝區運作)、persistent(跨重新開機維持工作階段)等參數,以及用 netsh trace convert 把 ETL 轉成文字等格式。 ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Using Netsh to manage traces. 說明情境是為疑難排解預先定義的提供者集合;用 netsh trace show scenarios / show scenario 確認;追蹤工作階段同時只能執行一個;capture=yes 時的封包篩選器(ipv4.address 等);停止時會產生 ETL 與含系統資訊的 .cab。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Wireshark Wiki, CaptureSetup/Loopback. 說明在 Windows 上以實體 NIC 為對象的一般擷取無法擷取送往 127.0.0.1 的迴路流量;用 Npcap 的「Adapter for loopback traffic capture」可以進行迴路擷取;Wireshark 3.0 以後的 Windows 安裝程式內含 Npcap。 ↩ ↩2 ↩3 ↩4
-
Wireshark Wiki, TLS. 說明可用 SSLKEYLOGFILE 環境變數寫出的工作階段金鑰在 Wireshark 解密 TLS;支援的是 Firefox、Chrome、以 Chromium 為基礎的 Edge、OpenSSL 系列程式庫等;而 Microsoft 的 SChannel 不支援這個機制。 ↩ ↩2
-
Microsoft Learn, pktmon counters. 說明 pktmon counters 會顯示各監視對象元件的通過與丟棄計數器;–drop-reason 可顯示各丟棄計數器最近一次的丟棄原因;以及用 –live 即時更新。 ↩
-
Wireshark, Building Display Filter Expressions (Wireshark User’s Guide). 說明顯示篩選器的語法、ip.addr 與 tcp.port 等欄位的指定、比較運算子,以及用 and/or/not 組合。 ↩
-
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
-
Microsoft Learn, Windows Time service tools and settings. 說明 w32tm 是用於 W32Time 的設定、監視與疑難排解的建議命令列工具,以及 w32tm /stripchart 會顯示自己與對方電腦的時間位移(/dataonly、/samples 等選項)。 ↩
-
Wireshark, Capture files and file modes (Wireshark User’s Guide). 說明擷取檔的輸出模式(單一檔案、多個檔案、環形緩衝區),以及環形緩衝區只保留最新的資料,能為磁碟用量設定上限。 ↩
相關文章
共用相同標籤的最新文章。能以相近的主題延伸理解。
Windows 名稱解析的順序 ── hosts、DNS 快取、LLMNR/mDNS 與 DoH
「解析不了名稱」「只有部分電腦連不上」,結果取決於回答的是 hosts、DNS 快取、DNS 伺服器還是 LLMNR/mDNS。本文從機制上整理 Windows 名稱解析的順序與 DoH 改變了什麼,並說明逐層釐清的步驟。
把OSI參考模型看得明明白白 ── 解剖一個HTTP請求的七層結構
不靠死記硬背來理解OSI參考模型,而是看真實的東西。本文用C#組出一個承載HTTP GET請求的Ethernet訊框並加以解剖,透過十六進位傾印和Wireshark確認L2〜L7如何以位元組序列的形式一層層物理地嵌套在一起。文章從實務角度整理各層與.NET API(Http...
Time Travel Debugging ── 把長期運轉中無法重現的問題「錄下來」再倒回去
一個月才出現一次的問題,當機傾印只拍得到結果。本文說明如何用 WinDbg 的 Time Travel Debugging(TTD) 錄下執行並倒回,涵蓋 TTD.exe 的錄製設計、環形緩衝區、TTD.Calls 查詢,以及和傾印的分工。
從睡眠恢復就壞掉的應用程式 ── 電源事件的機制,以及耐得住恢復的業務應用程式寫法
打開筆電,業務應用程式的連線卻斷了──原因是設計從未把睡眠算進去。本文依一次資訊整理 WM_POWERBROADCAST 的通知流程、Modern Standby 的行為、斷線/重連設計、睡眠抑制,以及調查指令。
DllMain 與載入器鎖定 ── 「DLL 初始化時什麼都別做」真正的理由
為什麼不能在 DllMain 裡呼叫 LoadLibrary 或與其他執行緒同步?本文依據一次資料,從序列化所有 DLL 通知的載入器鎖定機制,一路說明到死結成立的典型情境、延遲初始化等正確設計,以及無回應的調查步驟。
相關主題
與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。
Windows 技術主題
彙整 KomuraSoft LLC 關於 Windows 開發、故障調查與既有資產活用文章的主題中心。
故障調查 & 長期運行故障
整理間歇性故障、通訊診斷、長期運行當機、失敗路徑測試基礎的主題頁面。
與本主題相關的服務
本文連結到以下服務頁面,歡迎從最接近的入口查看。
Windows 應用程式開發
支援包含常駐處理、設備連動、運作日誌與可維護結構的 Windows 桌面應用程式。
故障調查 & 根本原因分析
調查難以重現的故障、長時間執行後的問題、記憶體洩漏、通訊停滯等棘手的正式環境問題。
常見問題
整理諮詢這個主題時常見的問題。
- 客戶伺服器不能安裝 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 的顯示篩選器只抽出目標通訊並匯出。剩下的內容則與收件方商量,先決定機密部分的處理方式(遮蔽、改用其他方式提供)再交付。擷取檔的保存期限與刪除,也建議事先決定好。