Захват пакетов в Windows на практике — как выбрать между pktmon, netsh trace и Wireshark
· Go Komura · Windows, Захват пакетов, pktmon, netsh, Wireshark, Сеть, Диагностика, TCP/IP
«Серверная связь бизнес-приложения несколько раз в месяц срывается. В журнале приложения только “timeout”. В журнале на стороне сервера в это время нет соответствующей ошибки. Неизвестно, как воспроизвести» — в консультациях по расследованию дефектов такая форма встречается постоянно.
Журнал приложения хранит только то, что приложение «решило записать». Видно, что результат — timeout, но был ли SYN без ответа, установилось ли соединение и сервер замолчал, оборвали ли RST или пакет вообще дошёл до назначения, живёт на слой ниже журнала — в пакетах, которые реально прошли по проводу. Если Process Monitor — способ смотреть на слой ниже доступ к файлам и реестру, захват пакетов — способ смотреть на слой ниже сам разговор.
flowchart TB
accTitle: Пакеты на слой ниже журнала приложения
accDescr: Журнал приложения хранит только то, что приложение решило записать; был ли SYN без ответа, замолчал ли узел после connect, оборвал ли RST или пакет дошёл — живёт только в пакетах, реально прошедших по проводу
log["Журнал приложения"] --> dec["Остаётся только то, что решили записать"]
dec --> to["Результат — timeout одним словом"]
to -->|смотреть на слой ниже| pkt["Пакеты, реально прошедшие по проводу"]
pkt --> q1["Нет ответа на SYN?"]
pkt --> q2["Тишина после connect?"]
pkt --> q3["Оборвано RST?"]
pkt --> q4["Дошло ли до назначения?"]
Рис. 1: Журнал хранит только результат; разбор timeout живёт только в пакетах на слой ниже.
Типичное место, где застревают, — ограничение «на сервере заказчика нельзя поставить Wireshark». Площадки, где контроль изменений или политика безопасности не утвердят лишнее ПО для расследования, не редкость. Однако Windows уже поставляет два средства захвата пакетов: pktmon и netsh trace. Захватить штатными средствами ОС, унести файл на свой ПК и прочитать в Wireshark — при таком разделении пакеты видны и на площадке с запретом установок.
Статья рассчитана на ИТ-сотрудников малого и среднего бизнеса и разработчиков приложений Windows. Она выстраивает выбор между pktmon, netsh trace и Wireshark и практическую процедуру каждого. Ловушки loopback-трафика, решение, захватывать на клиенте или на сервере, как жить с тем, что TLS прячет нагрузку, и сопоставление захвата с журналом приложения разобраны по первоисточникам на август 2026 года.
1. Сначала вывод
- «Захватывать штатным инструментом, читать в Wireshark» — базовая схема на площадке. Даже если на сервере заказчика нельзя ставить ПО, pktmon и netsh trace уже в Windows. Переведите захваченный журнал в pcapng и разбирайте в Wireshark на своей машине.12
- pktmon — штатный захват пакетов в Windows 10 / Windows Server 2019 и новее. Им пользуются в четыре шага — зарегистрировать фильтр, запустить, остановить, преобразовать — и его особая сила в том, что видно, какой компонент сетевого стека отбросил пакет (причина drop).34
- netsh trace — более старое штатное средство; оно может включить набор ETW-провайдеров как «сценарий». Кроме пакетов оно хранит события внутри компонентов Windows, а с persistent=yes захват переживает перезагрузку.56
- Оба пишут ETL, который Wireshark как есть не открывает. В pcapng переводят
pktmon etl2pcapдля pktmon и открытый etl2pcapng Microsoft для netsh trace.12 - Сам Microsoft указывает «сначала pktmon, затем netsh trace, если этого мало, и Wireshark для разбора протокола». Разделение в статье следует этой официальной рекомендации.7
- По умолчанию pktmon записывает только первые 128 байт каждого пакета. Если собираетесь читать нагрузку в Wireshark, при старте не забудьте
--pkt-size 0(записать весь пакет).8 - Трафик на localhost не появляется в обычном захвате. Он не проходит через NIC. В Wireshark используйте loopback-адаптер Npcap, со штатными средствами — захват внутри стека pktmon.9
- Даже когда TLS прячет нагрузку, узнать можно многое. Установка соединения, успех рукопожатия TLS, RST и какая сторона замолчала видны и в шифре. Расшифровка через SSLKEYLOGFILE — приём только для среды разработки.10
- Захват содержит саму связь. Исходите из того, что там могут быть учётные данные и персональные сведения, и встройте в процедуру минимально нужный захват и сужение перед передачей.
2. Три средства захвата и как выбирать
Сначала одна таблица ролей трёх средств.
| pktmon | netsh trace | Wireshark | |
|---|---|---|---|
| Как получить | Встроен в Windows 10 / Windows Server 2019 и новее3 | Давно встроен в Windows (работает и на ОС до pktmon) | Нужна отдельная установка |
| Главная роль | Захват пакетов, обнаружение drop, счётчики | Захват пакетов + ETW-события компонентов Windows | Разбор захваченных данных (настоящее назначение) |
| Формат вывода | ETL (перевод в pcapng через etl2pcap)1 | ETL+.cab (перевод в pcapng через etl2pcapng)62 | pcapng |
| Особая сила | Место и причина drop внутри стека4 | Связка провайдеров по сценарию, захват через перезагрузки5 | Фильтры отображения, разбор TCP, статистика, GUI |
| Права | Администратор | Администратор | Эквивалент администратора для захвата (для одного разбора не нужны) |
Одним предложением: pktmon и netsh trace — средства «захвата», Wireshark — средство «чтения». Wireshark тоже умеет захватывать, но там, где его нельзя поставить, этим не воспользоваться. Обратно, ETL штатных средств можно перевести в текст и читать, но смотреть без фильтра отображения и разбора TCP — мука. «На площадке захватить штатным средством, перевести в pcapng и читать в Wireshark на своей машине» — самый короткий путь на ограниченной площадке.
flowchart TB
accTitle: Захватывать штатным средством, читать в Wireshark
accDescr: На площадке захватывают ETL через pktmon или netsh trace, каждый переводят в 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.7
Чтобы читать, что пакет на самом деле показывает, полезно иметь картину слоёв — Ethernet, IP, TCP, прикладные данные. Анатомия слоёв разобрана в «По-настоящему разобраться в модели OSI».
3. pktmon на практике — фильтр, старт, стоп, преобразование
Базовый поток pktmon — четыре шага. Выполняйте их в повышенном терминале.
:: 1. Сначала зарегистрировать фильтр, чтобы сузить цель (TCP 8443 на сервере 192.168.10.20)
pktmon filter add App8443 -i 192.168.10.20 -t tcp -p 8443
pktmon filter list
:: 2. Начать захват. Записывать целые пакеты, перезаписывать в кольцевом буфере 1 ГБ
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. Остановить, затем преобразовать в pcapng для Wireshark
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: Сузить цель фильтром, запустить захват, воспроизвести инцидент, остановить, перевести в pcapng через etl2pcap и в конце снять зарегистрированный фильтр
fa["1. Сузить цель через filter add"] --> st["2. Запустить захват start --capture"]
st --> re["3. Воспроизвести инцидент"]
re -.-> ct["Проверить объём и drop через counters"]
re --> sp["4. Остановить"]
sp --> cv["Перевести в pcapng через etl2pcap"]
cv --> rm["5. Убрать через filter remove"]
Рис. 3: pktmon начинается с регистрации фильтра, затем захват, стоп и преобразование, а фильтр в конце снимают явно.
На что обратить внимание:
- Регистрируйте фильтры до старта захвата. Документация Microsoft тоже настоятельно рекомендует применить фильтр до старта: захват всего трафика слишком шумный. Фильтры задают IP-адрес, порт, MAC, протокол, VLAN ID и т. д., зарегистрировать можно до 32. Несколько фильтров — это ИЛИ: пакет пишется, если совпал с любым.3
- Фильтр pktmon не различает источник и назначение.
-i 192.168.10.20значит «пакеты, где этот адрес — источник или назначение». Направление сужают позже фильтром отображения Wireshark после преобразования.3 - Размер пакета по умолчанию — 128 байт. Этого хватает для разбора заголовков, но если нужны и прикладные данные, пишите весь пакет через
--pkt-size 0.8 - Журнал по умолчанию в режиме circular (кольцевой буфер), размер по умолчанию 512 МБ. Потолок меняют
--file-size, а--log-mode real-timeпечатает на экран в реальном времени и файл журнала не создаёт. Сначала в реальном времени убедитесь, что нужный трафик реально виден, затем ставьте боевой захват — так избежите пустой съёмки.8
flowchart TB
accTitle: Как срабатывают фильтры pktmon
accDescr: Несколько зарегистрированных фильтров пишут по совпадению ИЛИ, указанный адрес не различает источник и назначение, направление сужают позже фильтром отображения Wireshark после преобразования
f1["Фильтр 1"] --> orc["Писать, если совпал любой"]
f2["Фильтр 2"] --> orc
f3["Фильтр 3 (до 32)"] --> orc
orc --> rec["Записано в журнал захвата (ИЛИ)"]
rec -.-> nodir["Источник и назначение не различаются"]
nodir -.-> ws["Сузить направление в Wireshark после преобразования"]
Рис. 4: Несколько фильтров работают как ИЛИ, а является ли узел источником или назначением сужают в Wireshark после преобразования.
3.1. Что умеет только pktmon — видеть, где пакет отбросили
Отличие pktmon от Wireshark в том, что он снимает пакет в нескольких точках внутри сетевого стека, а не на одной NIC, и может сообщить, где и почему его отбросили (dropped). Раз видно, до какого компонента пакет дошёл и где исчез, причины drop вроде «несовпадение MTU» или «фильтр VLAN» выводят к причине без слепого перебора.4
flowchart TB
accTitle: pktmon снимает в нескольких точках стека
accDescr: pktmon снимает пакет в нескольких точках сетевого стека, а не на одной NIC, поэтому может сообщить с причиной, до какого компонента пакет дошёл и где его отбросили
pin["Пакет"] --> p1["Снят в точке 1"]
p1 --> p2["Снят в точке 2"]
p2 --> p3["Отброшен в точке 3"]
p3 -.-> rz["Сообщает место и причину drop"]
rz -.-> ex["напр. несовпадение MTU или фильтр VLAN"]
Рис. 5: Съёмка в нескольких точках стека показывает, как далеко дошёл пакет и где его отбросили, с причиной.
pktmon listпоказывает сетевые компоненты, которые можно наблюдать (NIC, стеки протоколов, фильтр-драйверы и т. д.), и их ID.pktmon counters --drop-reasonперечисляет счётчики прохождения/drop по компонентам и последнюю причину drop. Удобно как первый срез до разбора журнала.11- Перевод в текст через
pktmon etl2txtвыдаёт отброшенные пакеты сdropи dropReason.3
Подозрение, что «что-то в ОС отбрасывает это до приложения», одним Wireshark не закрыть. Эта возможность помогает, например, отделить случай, когда файрвол отбрасывает из‑за отсутствия входящего правила («Брандмауэр Windows и бизнес-приложения»).
Оговорка. pktmon пишет один и тот же пакет в нескольких точках стека, поэтому перевод как есть в pcapng может показать один пакет больше одного раза. pcapng не несёт «какой компонент это снял», поэтому при чтении в Wireshark стандартный ход — преобразовать с --component-id, выбрав одну точку (или вынести drop отдельно файлом --drop-only).1
flowchart TB
accTitle: Почему один пакет может появиться дважды после перевода в pcapng
accDescr: pktmon пишет один пакет в нескольких точках стека, pcapng не хранит, какой компонент снял, поэтому возможны дубли; стандартный ход — преобразовать после сужения точки через component-id или вынести drop в отдельный 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 — механизм трассировки, который в Windows дольше, чем pktmon. Его черта: как «сценарий» он может разом включить весь набор 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 capturefilterHelp.6 - Остановка даёт .cab помимо ETL. В .cab — системные сведения вроде конфигурации адаптеров и сборки ОС, то есть это ещё и сбор среды.6
- Одновременно может идти только одна сессия трассировки. Перед новым захватом проверьте
netsh trace show status, что не осталась старая сессия.6 - Добавьте
persistent=yes— и сессия переживёт перезагрузку. Снимать «связь на миг падает сразу после перезагрузки» или «подключение службы при старте срывается» — инциденты, которые вручную не успеть запустить, — уникальная область netsh trace.5
flowchart TB
accTitle: Захват сценария netsh trace
accDescr: Старт со сценарием включает набор ETW-провайдеров, capture=yes ещё и захватывает пакеты, остановка даёт файл ETL и файл .cab
sc["Старт со сценарием"] --> pv["Включить набор провайдеров"]
sc -->|capture=yes| pc["Пакеты тоже захватываются"]
pv --> re["Воспроизвести инцидент"]
pc --> re
re --> sp["Остановить"]
sp --> etl["Файл ETL"]
sp --> cab[".cab (системные сведения)"]
Рис. 7: Старт со сценарием включает набор провайдеров, остановка даёт ETL и .cab.
4.1. Сделать ETL читаемым в Wireshark — etl2pcapng
ETL netsh trace в Wireshark как есть не открыть. etl2pcapng, открытое средство Microsoft на GitHub, переводит в pcapng пакеты из ETL, снятого через netsh trace start capture=yes.2
etl2pcapng.exe C:\temp\nettrace.etl C:\temp\nettrace.pcapng
При преобразовании etl2pcapng пишет идентификатор процесса, связанный с каждым пакетом, как комментарий пакета. Видеть в Wireshark «чей это процесс» помогает, когда на одном сервере говорят несколько приложений.2
Сторона ETW-событий (внутренние события Windows, которые записали провайдеры сценария) в pcapng не переводится. Если нужны и события, переведите в текст через netsh trace convert input=C:\temp\nettrace.etl или откройте ETL в Windows Performance Analyzer.57
flowchart TB
accTitle: Чтение ETL netsh trace расходится на два пути
accDescr: Пакеты в ETL переводят в pcapng через etl2pcapng и читают в Wireshark; ETW-события в pcapng не переводятся, их читают через netsh trace convert или Windows Performance Analyzer
etl["ETL netsh trace"] --> 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
Открыв 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
В расследовании timeout ищите следующие формы по порядку.
- Завершилось ли трёхстороннее рукопожатие? Есть ли все три пакета SYN → SYN/ACK → ACK? Если SYN повторяется без ответа, он не дошёл до узла или был тихо отброшен по пути (типичный рисунок файрвола).
- Какая сторона послала RST? Немедленный RST на SYN значит, на порту назначения никто не слушает; RST после установленного соединения значит, одна сторона принудительно оборвала. Исходный IP RST — прямое доказательство «кто оборвал».
- Продолжаются ли ретрансмиссии? Повторная ретрансмиссия того же сегмента — знак, что подтверждение (ACK) не возвращается отправителю. Пропали исходящие данные или возвращающийся ACK, с одностороннего захвата не закрыть (поэтому в следующей главе важен «захват с обеих сторон»). Ретрансмиссии и timeout глубже разобраны в «Почему TCP-ретрансмиссии останавливают связь с промышленной камерой».
- Есть ли ZeroWindow? Это знак, что принимающее приложение не читает из сокета и буфер приёма полон. Основание подозревать устройство принимающего приложения («Заблуждение, что TCP отдаёт данные через Receive такими же порциями»), а не сеть.
flowchart TB
accTitle: Порядок форм в расследовании timeout
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 в этом порядке сужает, куда смотреть дальше.
Прежде чем читать пакеты по одному, полезно взять общую картину статистикой. [Statistics] → [Conversations] — список «какая пара IP / портов говорила, с какого по какое время, сколько», чтобы найти нужный разговор и отфильтровать только его. [Statistics] → [I/O Graph] — график объёма во времени; формы вроде «с этого момента одно направление замолчало» сразу видны. Правый щелчок по нужному TCP-разговору и [Follow] → [TCP Stream] позволяет прочитать обмен этого соединения как открытый текст.
flowchart TB
accTitle: Взять картину статистикой, затем сузить до разговора
accDescr: Перечислить, какие разговоры когда и сколько шли, в Conversations, взять интервал тишины с I/O Graph, отфильтровать нужный разговор и прочитать его как TCP-поток
ov["Взять общую картину статистикой"] --> cv["Список разговоров в Conversations"]
ov --> io["Видеть объём на I/O Graph"]
cv --> flt["Отфильтровать нужный разговор"]
io -.-> mute["Интервал тишины становится видимым"]
flt --> fs["Прочитать как TCP-поток"]
Рис. 10: Прежде чем читать пакет за пакетом, возьмите картину статистикой, сузьте до нужного разговора и прочитайте его целиком.
6. Ловушка loopback — трафик на localhost никогда не проходит через NIC
Пытаться расследовать связь между приложениями на одном ПК — например, бизнес-приложение подключается к промежуточному сервису на localhost:8080 — и застревать на «в Wireshark ничего нет» — классическая ловушка.
Причина ясна. Трафик на localhost (127.0.0.1) никогда не проходит через физическую NIC; он разворачивается на внутреннем пути loopback ОС. Обычный захват с физической платы его поэтому не видит.9
flowchart TB
accTitle: Почему трафик на localhost не виден в захвате
accDescr: Трафик на localhost никогда не проходит через физическую NIC и разворачивается на внутреннем пути loopback ОС, поэтому не появляется в обычном захвате с физической платы
app["Приложение"] --> stack["Сетевой стек"]
stack -->|внешний| nic["Физическая NIC"]
nic --> seen["Видно в обычном захвате"]
stack -->|localhost| lo["Разворот внутри ОС"]
lo -.-> miss["Нет в обычном захвате"]
lo -.-> alt["Loopback Npcap или pktmon"]
Рис. 11: Трафик на localhost разворачивается до NIC, захват с физической платы его не видит.
Есть два способа.
- При захвате в Wireshark: Выберите «Adapter for loopback traffic capture» Npcap как цель захвата. Установщик Windows Wireshark (3.0 и новее) несёт Npcap, поэтому если Wireshark уже стоит, ничего дополнительно делать не нужно.9
- При захвате штатными средствами: pktmon снимает в нескольких точках внутри сетевого стека, а не снаружи NIC4, поэтому тоже видит loopback. Чтобы быть уверенным, до боевого ожидания воспроизведения подтвердите на этой машине режимом реального времени
pktmon start -c -m real-time, что нужный loopback реально виден.
Следите и за двумя путаницами.
- «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» не гарантировано.
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. Предпосылка сопоставления — синхронизация часов
Чтобы выровнять захваты с обеих сторон, часы обеих машин должны совпадать. Перед стартом захвата проверьте и запишите смещение часов.
:: 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 В среде с большим смещением короче сначала починить синхронизацию времени, а потом захватывать.
flowchart TB
accTitle: Процедура проверки смещения часов перед сопоставлением
accDescr: Подтвердить свой статус синхронизации через w32tm, измерить и записать смещение к серверу-партнёру через stripchart, использовать это смещение как основание правки при выравнивании, а при большом смещении сначала починить синхронизацию и затем захватывать
st["Проверить статус sync через query"] --> mc["Измерить смещение через stripchart"]
mc --> rc["Записать смещение"]
rc --> use["Основание правки в момент сопоставления"]
mc -.-> big["Если смещение велико, сначала починить sync"]
Рис. 14: Измерьте и запишите смещение часов до захвата и используйте его как основание правки при выравнивании.
7.2. Для «неизвестно, когда случится» — кольцевой буфер
Для инцидента с неизвестными условиями воспроизведения базовый ход — оставить кольцевой буфер и остановить его, когда инцидент случится.
- pktmon: По умолчанию режим circular. Потолок (МБ) задают
--file-size; старые пакеты перезаписываются.8 - netsh trace: Указывают как
maxSize=1024 filemode=circular.5 - Wireshark: В [Capture] → [Options] → [Output] можно настроить «несколько файлов + кольцевой буфер». Он крутится по размеру файла или времени и хранит только последние N файлов, поэтому можно долго работать с потолком диска.15
В любом случае договоритесь с человеком на площадке: когда инцидент случится, «сначала записать время, потом» остановить захват. Кольцевой буфер стирает прошлое, чем дольше ждёте: если путь от события до стопа длинен, нужный интервал перезапишется.
flowchart TB
accTitle: Ожидание с захватом в кольцевом буфере
accDescr: При неизвестных условиях воспроизведения оставить кольцевой буфер, а когда инцидент случится, записать время и быстро остановить; поздний стоп перезаписывает старые пакеты и нужный интервал исчезает
st["Запустить захват в кольцевом буфере"] --> wt["Оставить работать и ждать"]
wt --> ev["Инцидент случается"]
ev --> memo["Записать время"]
memo --> sp["Быстро остановить"]
wt -.-> ow["Старые пакеты перезаписываются"]
ow -.-> late["Поздний стоп стирает нужный интервал"]
Рис. 15: Кольцевой буфер стирает прошлое, чем дольше ждёте, поэтому записав время, останавливайте быстро.
8. Проблема, что TLS прячет нагрузку — что всё равно видно
Большая часть делового трафика сегодня — TLS (HTTPS). Легко подумать «если зашифровано, захват бесполезен», но большая часть того, что нужно в расследовании timeout, видна при оставленном шифре.
- Установилось ли TCP-соединение (трёхстороннее рукопожатие)
- До куда дошло рукопожатие TLS — вернулся ли ServerHello на ClientHello, оборвали ли RST или alert во время рукопожатия
- Имя узла назначения в ClientHello (SNI) и согласованная версия TLS
- После подъёма соединения какая сторона перестала слать. Место тишины, ретрансмиссии, RST или чистый close (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 может расшифровать TLS ключами сессии, выписанными через переменную окружения SSLKEYLOGFILE. Поддержка ограничена некоторыми реализациями вроде Firefox, Chrome, Edge на Chromium и библиотек семейства OpenSSL; штатный SChannel Windows (приложения на 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: Выписывание ключей сессии может расшифровать, но поддерживаемые реализации ограничены, а природа ключа делает это приёмом только для среды разработки.
Когда трафик идёт через внутренний прокси, назначение в захвате — прокси-сервер, а TLS течёт внутри туннеля CONNECT. Предварительный вопрос, к какому прокси вообще идёт приложение, разобран в парной статье того же дня «Корпоративные прокси и приложения Windows — разбор разрешения прокси в WinINET, WinHTTP и .NET».
9. Сопоставление с журналом приложения — время на одну ось
Один захват редко даёт вывод. Решающий ход на практике — положить одну строку журнала приложения и один оборот пакетов на одну ось времени.
Процедура такая.
- Определите время инцидента из журнала приложения (например, исключение timeout в 10:23:41). Если значение timeout — 30 секунд, старт должен быть около 10:23:11.
- Переключите отображение времени 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"). - В этом интервале подтвердите порядок главы 5 (рукопожатие → RST → ретрансмиссия → ZeroWindow). Если удаётся выровнять до «за 30 секунд до времени timeout в журнале ушёл SYN, дальше только ретрансмиссии SYN», «timeout» журнала сменяется наблюдением «в этой точке захвата ответа не вернулось вовсе» (дошёл ли SYN до узла или пропал возвращающийся SYN/ACK на обратном пути, с одной этой точки захвата не закрыть. Чтобы закрыть, захватите на сервере и выровняйте).
- Всегда правьте смещение между временем захвата и временем журнала (смещение часов из раздела 7.1 и обозначение часового пояса журнала). Несколько секунд ошибки сопоставления пригвоздят не тот разговор как виновника.
flowchart TB
accTitle: Процедура выравнивания журнала приложения и пакетов
accDescr: Определить время инцидента из журнала приложения, отсчитать старт от значения timeout, сузить интервал в Wireshark фильтром отображения, подтвердить формы по порядку, поправить смещение часов и положить на одну ось времени
lg["1. Определить время инцидента из журнала"] --> rev["Отсчитать старт от значения timeout"]
rev --> flt["2. Сузить интервал фильтром отображения"]
flt --> chk["3. Подтвердить формы в порядке главы 5"]
chk --> adj["4. Поправить смещение часов"]
adj --> done["Одно слово журнала становится наблюдением"]
Рис. 18: Сузьте интервал от времени журнала, подтвердите форму, поправьте смещение часов и положите на одну ось.
Когда отдаёте результаты расследования третьей стороне (вендору, оператору, сетевикам заказчика), срезать шум фильтром до передачи — и вежливость, и мера безопасности. В Wireshark сузьте до нужного разговора фильтром отображения и сохраните «только отображённые пакеты» через [File] → [Export Specified Packets] — получите маленький pcapng только нужного диапазона.
Наконец, осторожность обращения. Файл захвата содержит саму связь. Там могут быть учётные данные открытых протоколов, HTTP-cookie и ключи API, содержимое почты или отчётов и персональные данные. Решите следующие три пункта комплектом с процедурой захвата.
- Минимально нужный захват: Сузьте цель фильтрами до захвата (главы 3 и 4) и держите окно времени как можно короче. Не делайте «просто захватить всё» на среде заказчика
- Сузить до передачи: Экспортируйте только нужный разговор; не включайте чужой посторонний трафик. Если остались чувствительные части, договоритесь с получателем о маскировании или другом пути
- Хранение и удаление: Решите, где лежат файлы захвата, сколько и когда удаляются, и удалите после окончания расследования
flowchart TB
accTitle: Три решения до передачи файла захвата
accDescr: Захват содержит саму связь, поэтому решите комплектом с процедурой захвата, что сузите до минимума фильтрами до захвата и окном времени, до передачи извлечёте только нужный разговор чтобы посторонний трафик не вошёл, и зададите место и срок хранения и удалите после расследования
cap["Захват = трафик"] --> p1["Захватывать минимум"]
cap --> p2["Сначала извлечь цель"]
cap --> p3["Задать хранение, удалить"]
p2 -.-> exp["Фильтровать и экспортировать"]
Рис. 19: Решите минимальный захват, сужение до передачи, хранение и удаление комплектом с процедурой захвата.
10. Итог
- На слой ниже «timeout» журнала приложения лежит факт пакетов, реально прошедших по проводу. Не было ли ответа на SYN, оборвал ли RST, продолжались ли ретрансмиссии или появился ZeroWindow — меняет, куда смотреть дальше.
- Даже на площадке, где нельзя поставить Wireshark, можно захватывать штатными pktmon и netsh trace. Захватывать штатным средством, читать в Wireshark на своей машине — эта схема и есть базовая форма.
- pktmon — четыре шага: зарегистрировать фильтр →
pktmon start --capture→pktmon stop→pktmon etl2pcap. По умолчанию обрезка до 128 байт, если нужна нагрузка, не забудьте--pkt-size 0. Видеть место и причину drop — сила только pktmon. - netsh trace захватывает набор ETW-провайдеров сценарием, и с
persistent=yesможет пережить перезагрузку. ETL переводят в pcapng через etl2pcapng, чтобы читать. - В Wireshark начинайте с
tcp.analysis.flagsи ищите рукопожатие, RST, ретрансмиссию и ZeroWindow в этом порядке. Быстрее, если сначала взять картину через Conversations и I/O Graph, затем сузить. - Трафик на localhost не проходит через NIC, обычным способом его не захватить. Используйте loopback-адаптер Npcap или захват внутри стека pktmon.
- Захват с обеих сторон и выравнивание закрывает «какая сторона замолчала». Предпосылка — синхронизация часов (w32tm). Для инцидента с неизвестными условиями воспроизведения ждите кольцевым буфером.
- Даже под TLS скелет разговора виден. Расшифровку (SSLKEYLOGFILE) считайте приёмом только для среды разработки, а сам файл захвата — конфиденциальным: встройте минимальный захват, сужение и удаление в работу.
Захват пакетов часто считают «инструментом сетевого специалиста», но на практике это средство расследования со стороны приложения, которое начинает что-то значить, только когда его выравнивают с журналом приложения. В следующий раз, когда расследование остановится на одном слове «timeout», идите смотреть на слой ниже.
Похожие статьи
- Почему TCP-ретрансмиссии останавливают связь с промышленной камерой, и как это диагностировать
- Заблуждение, что TCP отдаёт данные через Receive такими же порциями, какими их отправили через Send — как проектировать приём, работая с байтовым потоком
- По-настоящему разобраться в модели OSI — препарируем один HTTP-запрос на семь уровней
- Практическое руководство по Process Monitor (ProcMon) — как за 10 минут выяснить, почему «настройки не читаются» или возникает ACCESS DENIED
- Брандмауэр Windows и бизнес-приложения — регистрировать входящие правила из установщика
- Корпоративные прокси и приложения Windows — разбор разрешения прокси в WinINET, WinHTTP и .NET
Смежные области консультирования
KomuraSoft LLC берёт расследования дефектов связи вроде «связь бизнес-приложения время от времени срывается, причину не находим» и «хотим отделить ошибку соединения, которая бывает только на среде заказчика». Проектирование захвата (где, что и сколько снимать), разбор в Wireshark, сопоставление с журналом приложения и правку на стороне приложения мы ведём как одну непрерывную работу.
- Разработка Windows-приложений
- Исследование дефектов и анализ первопричин
- Техническая консультация и ревью проекта
- Связаться с нами
Справочные ссылки
-
Microsoft Learn, pktmon etl2pcap. О переводе журналов ETL pktmon в pcapng для разбора в Wireshark и подобных средствах, и о том, что сведения об отбросе и точке съёмки внутри стека в pcapng теряются, поэтому сначала сужают через –drop-only или –component-id, затем преобразуют. ↩ ↩2 ↩3 ↩4
-
GitHub, microsoft/etl2pcapng. О том, что etl2pcapng — открытое средство Microsoft, которое переводит в pcapng пакеты из файла ETL, снятого через netsh trace start capture=yes и подобное, сохраняя сведения об интерфейсе и записывая ID процесса как комментарий пакета. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Pktmon command formatting. О том, что pktmon.exe доступен в Windows 10 и Windows Server 2019 (версия 1809) и новее; быстрый старт: регистрация фильтра → старт → воспроизведение → проверка счётчиков → стоп и преобразование; фильтров не больше 32, они объединяются по ИЛИ и не различают источник и назначение; отброшенные пакеты в текстовом выводе несут dropReason. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Packet Monitor (Pktmon). О том, что Packet Monitor — штатное межкомпонентное диагностическое средство Windows; что снимает пакеты в нескольких точках сетевого стека, чтобы визуализировать путь пакета; что сообщает об отбросах на поддерживаемых компонентах с причиной drop (MTU Mismatch, Filtered VLAN и т. д.); и что даёт счётчики пакетов по точкам. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, netsh trace. О параметрах netsh trace start вроде scenario, capture, tracefile, maxSize, fileMode (circular работает как кольцевой буфер) и persistent (держать сессию через перезагрузку), и о переводе ETL в текст и подобное через netsh trace convert. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Using Netsh to manage traces. О том, что сценарий — заранее заданный набор провайдеров для диагностики; о просмотре через netsh trace show scenarios / show scenario; о том, что одновременно может идти только одна сессия трассировки; о фильтрах пакетов вроде ipv4.address при capture=yes; и о том, что остановка даёт ETL и .cab с системными сведениями. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Microsoft Learn, Diagnose packet loss. Об официальной процедуре расследования: сначала снять трассировку через pktmon и проверить локальные причины drop и статистику, сочетать это с разбором на уровне протокола в Wireshark, а если мало — перейти к трассировке уровня компонентов сценарием netsh trace. ↩ ↩2 ↩3
-
Microsoft Learn, pktmon start. О старте захвата через –capture; о том, что –pkt-size по умолчанию 128 байт, а 0 пишет весь пакет; о –file-name и –file-size (по умолчанию 512 МБ); и о значениях –log-mode (circular, multi-file, real-time, memory), где circular — умолчание. ↩ ↩2 ↩3 ↩4
-
Wireshark Wiki, CaptureSetup/Loopback. О том, что обычный захват с физической NIC в Windows не может снять loopback-трафик на 127.0.0.1; что «Adapter for loopback traffic capture» Npcap делает захват loopback возможным; и что Npcap входит в установщик Windows начиная с Wireshark 3.0. ↩ ↩2 ↩3 ↩4
-
Wireshark Wiki, TLS. О том, что Wireshark может расшифровать TLS ключами сессии, выписанными через переменную окружения SSLKEYLOGFILE; что поддержка покрывает Firefox, Chrome, Edge на Chromium, библиотеки семейства OpenSSL и подобные; и что Microsoft SChannel этот механизм не поддерживает. ↩ ↩2
-
Microsoft Learn, pktmon counters. О том, что pktmon counters показывает счётчики прохождения и drop по наблюдаемым компонентам; что –drop-reason показывает последнюю причину отброса каждого счётчика drop; и о живом обновлении через –live. ↩
-
Wireshark, Building Display Filter Expressions (Wireshark User’s Guide). О синтаксисе фильтров отображения, задании полей вроде ip.addr и tcp.port, операторах сравнения и сочетании через and/or/not. ↩
-
Wireshark, TCP Analysis (Wireshark User’s Guide). О списке флагов разбора TCP Wireshark (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). О режимах вывода файла захвата (один файл, несколько файлов, кольцевой буфер) и о том, что кольцевой буфер хранит только самые свежие данные, чтобы поставить потолок использования диска. ↩
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
OneDrive «Файлы по запросу» и бизнес-приложения — какие допущения ломают заполнители и как с этим жить
CSV с рабочего стола не открывается, или импорт падает с «файл не найден» — причина может быть в Known Folder Move и «Файлах по запросу» ...
Корпоративный прокси и приложения Windows — разбор разрешения прокси в WinINET, WinHTTP и .NET
Браузер проходит, а деловое приложение не пересекает корпоративный прокси. Причина обычно в расхождении того, какие настройки прокси чита...
Как читать коды ошибок Windows — трёхслойная структура Win32, HRESULT и NTSTATUS
Когда появляется 0x80004005, разберите его до поиска. Статья о трёх слоях Win32, HRESULT и NTSTATUS, главном шаблоне 0x8007xxxx и поиске ...
По-настоящему разобраться в модели OSI — препарируем один HTTP-запрос на семь уровней
Разбираем модель OSI не через зубрёжку, а на реальном примере. На C# мы собираем и препарируем Ethernet-кадр, несущий один HTTP GET-запро...
Глубины виртуализации Windows (часть 3) — виртуальные машины, которые загружаются за секунды: почему WSL2, Windows Sandbox и контейнеры такие лёгкие
Почему WSL2 и Windows Sandbox стартуют за секунды и ощущаются такими лёгкими? Статья разбирает механизмы — от динамического базового обра...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Разработка приложений для Windows
Бизнес-приложения, интеграция оборудования и средства связи — от требований до разработки.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Как захватить пакеты на сервере заказчика, куда нельзя поставить Wireshark?
- Используйте штатные средства Windows — pktmon или netsh trace: дополнительное ПО ставить не нужно. В pktmon в повышенном терминале регистрируют фильтр, запускают захват командой pktmon start --capture и останавливают pktmon stop. Полученный ETL переводят в pcapng через pktmon etl2pcap, а разбор делают в Wireshark на своей машине. «Захватывать штатным инструментом, читать в Wireshark» — базовая схема на площадках с запретом установок.
- Что выбрать: pktmon или netsh trace?
- Если в ОС есть pktmon (Windows 10 / Windows Server 2019 и новее), начинайте с pktmon. Команды простые, видно, какой компонент сетевого стека отбросил пакет (причина drop), а перевод в pcapng самодостаточен. netsh trace лучше, когда захватываете на старой ОС без pktmon, когда нужно собрать ETW-события компонентов Windows сценарием или когда захват должен пережить перезагрузку с persistent=yes. Материалы Microsoft по диагностике тоже указывают этот порядок: сначала pktmon, затем netsh trace, если этого мало.
- Почему трафик на localhost (127.0.0.1) не виден в Wireshark?
- Трафик на localhost никогда не проходит через физическую NIC: он разворачивается на внутреннем пути loopback ОС. Обычный захват с физической платы его поэтому не видит. В Wireshark выберите «Adapter for loopback traffic capture» Npcap — и loopback можно захватить. pktmon снимает внутри сетевого стека, поэтому тоже видит loopback. Ещё путаница: «localhost» резолвится в IPv6 ::1, и экран, настроенный на 127.0.0.1, пуст — проверяйте, явно указав адрес.
- Можно ли в дампе пакетов увидеть содержимое HTTPS (TLS)?
- Полезная нагрузка прикладных данных зашифрована и не видна. «Скелет» разговора — установка и разрыв TCP, успех рукопожатия TLS, обрыв RST, какая сторона перестала отвечать — виден и в шифре, поэтому большинство расследований timeout идёт с нерасшифрованным TLS. Если нужна нагрузка, есть расшифровка через SSLKEYLOGFILE, но её поддерживают лишь некоторые реализации TLS вроде Firefox и семейства Chrome; штатный SChannel Windows не поддерживается. Механизм выписывает ключевой материал, считайте его опцией только для среды разработки.
- Безопасно ли отправлять файл захвата внешней поддержке?
- Отправлять как есть опасно. Захват содержит саму связь и может включать учётные данные открытых протоколов, cookie, ключи API и персональные данные. Сначала на этапе захвата сузьте фильтр и окно времени до необходимого минимума, а перед передачей извлеките только целевой разговор фильтром отображения Wireshark и экспортируйте его. По тому, что останется, заранее договоритесь с получателем, как обрабатывать чувствительные части (маскирование или другая доставка). Заранее решите, сколько хранить файлы захвата и когда их удалять.
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.