tcpdump: 20 примеров для диагностики сайта
18 мин чтения
tcpdump: 20 примеров для диагностики сайта

tcpdump: 20 примеров для диагностики сайта

Логи nginx молчат, curl висит, пользователи жалуются. Единственный честный свидетель в этот момент — трафик на сетевой карте. Двадцать рабочих команд tcpdump: от «кто ко мне стучится» до ретрансмитов, TLS-алертов, NXDOMAIN и записи с ротацией. Сверено с man tcpdump и man pcap-filter на сентябрь 2026.

tcpdump — консольный анализатор сетевого трафика: он перехватывает пакеты с сетевого интерфейса, отбирает нужные по фильтру BPF и печатает их заголовки либо сохраняет в pcap-файл. Работает в Linux, macOS и BSD, требует прав root или capability cap_net_raw; на Windows его нет — там используют встроенный pktmon или Wireshark с Npcap.

Как установить tcpdump и без чего он не запустится

На серверных дистрибутивах tcpdump обычно уже стоит, в минимальных образах и контейнерах — нет. Актуальная стабильная версия на сентябрь 2026 — tcpdump 4.99.6 (30 декабря 2025) поверх libpcap 1.10.7 (5 сентября 2026); версия 5.0 в разработке.

Система Установка Права на захват
Debian, Ubuntu apt install tcpdump sudo или setcap
RHEL, Alma, Rocky, Fedora dnf install tcpdump sudo или setcap
Alpine, контейнеры apk add tcpdump Контейнеру нужен CAP_NET_RAW
macOS предустановлен; brew install tcpdump — свежее sudo или доступ к /dev/bpf*
Windows 10/11, Server 2019+ tcpdump нет. pktmon встроен; Wireshark + Npcap даёт tshark Администратор
WSL2 apt install tcpdump внутри WSL Видит только виртуальный интерфейс WSL
# Linux: захват без sudo для конкретного бинарника
sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/tcpdump

# Windows: встроенный pktmon, от администратора
pktmon filter add -p 443
pktmon start -c --comp nics
pktmon stop
pktmon etl2pcap PktMon.etl --out capture.pcapng   # открыть в Wireshark

Ловушка в Debian и Ubuntu: после открытия интерфейса tcpdump сбрасывает привилегии до пользователя tcpdump (поведение ключа -Z, включённое при сборке). Поэтому -w /root/dump.pcap падает с «Permission denied» даже под sudo. Пишите в /var/tmp или укажите -Z root.

Ключи tcpdump, которых хватает в 95% случаев

Базовая связка — -i any -nn: все интерфейсы, без резолва имён и портов. Остальное добавляется по задаче.

Ключ Что делает
-i eth0 / -i any Интерфейс. Без ключа — первый поднятый не-loopback; any — все сразу, без promiscuous-режима
-D Список интерфейсов для захвата
-n / -nn Не резолвить адреса / адреса и порты. Без -n каждый пакет порождает DNS-запрос
-c N Выйти после N пакетов
-w файл / -r файл Записать pcap / прочитать. С -w на экран ничего не идёт, если не добавить --print
-s N Snaplen, байт на пакет. По умолчанию 262144, -s 0 — то же самое; -s 128 оставит только заголовки
-v / -vv / -vvv Подробнее: TTL, id, длина IP, контрольные суммы, детали DNS
-A / -X Нагрузка в ASCII (HTTP) / hex + ASCII (TLS, FastCGI)
-tttt / -ttt Время с датой / дельта от предыдущей строки — для замера задержек
-e MAC-адреса, ethertype и полная длина кадра
-q Короткие строки: без seq, ack и опций
-l Построчная буферизация. Обязателен перед | grep
-G сек / -W N / -C МБ Ротация по времени / лимит числа файлов / ротация по размеру
-Z user Сбросить привилегии до user после открытия интерфейса
-S / -B КиБ Абсолютные seq / размер буфера ядра, если есть «dropped by kernel»

Базовые примеры: интерфейс, хост, порт, подсеть

Первые четыре команды отвечают на вопрос «что происходит на сервере прямо сейчас» и служат заготовками для остальных фильтров.

1. Найти интерфейс и убедиться, что захват работает.

sudo tcpdump -D
sudo tcpdump -i any -nn -c 5

# пример вывода
1.eth0 [Up, Running, Connected]
2.any (Pseudo-device that captures on all interfaces) [Up, Running]
3.lo [Up, Running, Loopback]

Что видим: интерфейсы и их состояние. За облачным балансировщиком внешний адрес может жить не на том интерфейсе, что вы думаете, поэтому первая проба всегда с -i any, а дальше сужаем.

2. Фильтр по IP: всё, что связано с конкретным клиентом.

sudo tcpdump -i eth0 -nn host 203.0.113.7        # в обе стороны
sudo tcpdump -i eth0 -nn src host 203.0.113.7    # только от него

# пример вывода
12:41:03.118204 IP 203.0.113.7.51214 > 198.51.100.10.443: Flags [S], seq 3814292745, win 64240, options [mss 1460,sackOK,wscale 7], length 0
12:41:03.118251 IP 198.51.100.10.443 > 203.0.113.7.51214: Flags [S.], seq 1289473102, ack 3814292746, win 65160, options [mss 1460,sackOK,wscale 7], length 0
12:41:03.146920 IP 203.0.113.7.51214 > 198.51.100.10.443: Flags [.], ack 1, win 502, length 0

Что видим: полное рукопожатие. Флаги: S — SYN, S. — SYN-ACK (точка означает ACK), . — чистый ACK, P — PUSH, F — FIN, R — RST. Разница между первой и третьей строкой — 28,7 мс — это RTT до клиента.

3. Веб-трафик на 80 и 443, коротко.

sudo tcpdump -i eth0 -nn -q 'port 80 or port 443'

# пример вывода
12:42:10.004811 IP 203.0.113.7.51220 > 198.51.100.10.443: tcp 517
12:42:10.005390 IP 198.51.100.10.443 > 203.0.113.7.51220: tcp 0
12:42:10.011702 IP 198.51.100.10.443 > 203.0.113.7.51220: tcp 1460

Что видим: с -q остаются адреса и длина нагрузки. 517 байт от клиента на 443 — типичный размер TLS ClientHello, 1460 в ответ — сервер шлёт максимальный сегмент.

4. Подсеть /24 и кто стучится чаще всех.

sudo tcpdump -i eth0 -nn net 203.0.113.0/24
sudo tcpdump -i eth0 -nn -l -c 2000 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0' 2>/dev/null \
  | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -rn | head -5

# пример вывода
    812 203.0.113.55
     97 198.51.100.23

Что видим: из 2000 входящих SYN 812 пришли с одного адреса — агрессивный бот или клиент в цикле переподключений. Ключ -l отдаёт вывод в конвейер построчно, а не порциями.

TCP-рукопожатие: SYN без ответа, RST и ретрансмиты

Три картины ниже покрывают почти все «сайт не открывается» на уровне TCP. По curl их не различить, по tcpdump — за минуту.

5. SYN приходит, SYN-ACK не уходит.

sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-syn) != 0 and tcp[tcpflags] & (tcp-ack) == 0'

# пример вывода
09:12:40.001732 IP 203.0.113.7.40122 > 198.51.100.10.8443: Flags [S], seq 2210441193, win 64240, length 0
09:12:41.020119 IP 203.0.113.7.40122 > 198.51.100.10.8443: Flags [S], seq 2210441193, win 64240, length 0
09:12:43.064205 IP 203.0.113.7.40122 > 198.51.100.10.8443: Flags [S], seq 2210441193, win 64240, length 0

Что видим: тот же SYN с тем же seq повторяется через 1 и 2 секунды, ответа [S.] нет. Это не «никто не слушает» — тогда ядро ответило бы RST, — а DROP в файрволе или переполненный SYN-backlog. Слушателя и очередь смотрим в статье про ss и состояния TCP.

6. В ответ прилетает RST.

sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-rst) != 0'

# пример вывода
09:15:02.410077 IP 198.51.100.10.8080 > 203.0.113.7.40130: Flags [R.], seq 0, ack 2210441194, win 0, length 0
09:15:02.410120 IP 198.51.100.10.8080 > 203.0.113.7.40131: Flags [R.], seq 0, ack 3390012011, win 0, length 0

Что видим: RST с win 0 и ack = seq клиента + 1 — ответ ядра на SYN в порт, где никто не слушает; у клиента это ERR_CONNECTION_REFUSED. RST посреди установленного соединения — другая история, разобрана в статье про ERR_CONNECTION_RESET.

7. Ретрансмиты: сервер отдаёт, клиент не подтверждает.

sudo tcpdump -i eth0 -nn -ttt -S host 203.0.113.7 and port 443

# пример вывода
 00:00:00.000000 IP 198.51.100.10.443 > 203.0.113.7.51214: Flags [P.], seq 1289473103:1289474563, ack 3814293263, win 509, length 1460
 00:00:00.212418 IP 198.51.100.10.443 > 203.0.113.7.51214: Flags [P.], seq 1289473103:1289474563, ack 3814293263, win 509, length 1460
 00:00:00.428009 IP 198.51.100.10.443 > 203.0.113.7.51214: Flags [P.], seq 1289473103:1289474563, ack 3814293263, win 509, length 1460

Что видим: tcpdump не помечает ретрансмиты словом — их выдаёт одинаковый диапазон seq и растущие интервалы 0,2 → 0,4 с (минимальный RTO в Linux 200 мс, дальше удвоение). Если повторяются только сегменты по 1460 байт, а мелкие проходят — это проблема MTU на пути.

HTTP: запросы, коды ответов и время до ответа

Открытый HTTP на 80-м порту виден целиком, и это удобно для проверки того, что происходит между TLS-терминацией и приложением. Фильтр по нагрузке отбирает нужные пакеты ещё в ядре.

8. Только GET и HEAD, с заголовками.

sudo tcpdump -i any -nn -A 'tcp port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'   # "GET "
sudo tcpdump -i any -nn -A 'tcp port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48454144'   # "HEAD"

# пример вывода
14:10:22.301512 IP 203.0.113.7.52310 > 198.51.100.10.80: Flags [P.], seq 1:79, ack 1, win 502, length 78: HTTP: GET /catalog/ HTTP/1.1
GET /catalog/ HTTP/1.1
Host: example.ru
User-Agent: curl/8.5.0

Что видим: выражение (tcp[12:1] & 0xf0) >> 2 вычисляет длину TCP-заголовка, а следующие 4 байта сравниваются с ASCII-кодами «GET » (0x47 0x45 0x54 0x20); для POST — 0x504f5354. ACK и куски тел ответов в вывод не попадают.

9. Коды ответов: кто отдаёт 5xx.

sudo tcpdump -i any -nn -l -A 'tcp src port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450' | grep -a --line-buffered '^HTTP/'

# пример вывода
HTTP/1.1 200 OK
HTTP/1.1 502 Bad Gateway
HTTP/1.1 504 Gateway Time-out

Что видим: 0x48545450 — «HTTP», начало любой строки статуса. Если 502 идут с 127.0.0.1:80 на lo, а снаружи на 443 всё зелёное, виноват апстрим за nginx, а не сеть.

10. Сколько сервер думает над ответом.

sudo tcpdump -i any -nn -ttt -q 'port 80 and host 203.0.113.7'

# пример вывода
 00:00:00.000000 IP 203.0.113.7.52310 > 198.51.100.10.80: tcp 78
 00:00:00.000041 IP 198.51.100.10.80 > 203.0.113.7.52310: tcp 0
 00:00:02.814371 IP 198.51.100.10.80 > 203.0.113.7.52310: tcp 311

Что видим: ACK на запрос ушёл через 41 мкс — это ядро, сеть в порядке. Первый байт ответа — через 2,81 с, и это уже приложение: база, внешний API или очередь воркеров. Замер честнее TTFB у curl, потому что исключает сеть до клиента.

TLS: ClientHello, SNI и алерты

Содержимое HTTPS tcpdump не расшифрует и TLS-записи не декодирует, но структура рукопожатия видна по первым байтам. Этого хватает, чтобы понять, доходит ли ClientHello и чем отвечает сервер.

11. Поймать ClientHello и прочитать SNI.

# байт 0 нагрузки = 0x16 (handshake), байт 5 = 0x01 (ClientHello)
sudo tcpdump -i eth0 -nn -X 'tcp dst port 443 and tcp[((tcp[12] & 0xf0) >> 2)] = 0x16 and tcp[((tcp[12] & 0xf0) >> 2)+5] = 0x01'

# пример вывода
15:01:07.220314 IP 203.0.113.7.51230 > 198.51.100.10.443: Flags [P.], seq 1:518, ack 1, win 502, length 517
        0x0040:  1603 0102 0001 0001 fc03 03a1 9c2e 4b10  ..............K.
        0x00b0:  0000 0f00 0d00 000a 6578 616d 706c 652e  ........example.

# то же с готовым декодером
tshark -i eth0 -Y 'tls.handshake.type == 1' -T fields -e ip.src -e tls.handshake.extensions_server_name

Что видим: 16 03 01 — TLS-запись типа handshake, затем 01 — ClientHello; в ASCII-колонке читается имя хоста из расширения SNI. Фильтр опирается на фиксированную структуру записи по RFC 5246 и работает для TLS 1.3 тоже — ClientHello там не шифруется. Для регулярного разбора удобнее tshark: он отдаёт SNI одним полем.

12. TLS alert: рукопожатие оборвалось.

sudo tcpdump -i eth0 -nn -X 'tcp port 443 and tcp[((tcp[12] & 0xf0) >> 2)] = 0x15'

# пример вывода
15:02:41.907550 IP 198.51.100.10.443 > 203.0.113.7.51233: Flags [P.], seq 1:8, ack 518, win 509, length 7
        0x0034:  1503 0300 0202 28                        ......(

Что видим: 0x15 — запись alert, 02 — fatal, 28 — код 40, handshake_failure. Другие частые коды: 46 certificate_unknown, 48 unknown_ca, 112 unrecognized_name — нет сертификата под запрошенный SNI. В TLS 1.2 алерты идут открыто; в TLS 1.3 после ServerHello они зашифрованы, но 7-байтовый пакет и его отправитель всё равно видны.

DNS: запросы, NXDOMAIN и время ответа резолвера

DNS tcpdump декодирует полностью: id запроса, тип записи, ответ и коды ошибок. Это самый быстрый способ понять, тормозит ли сайт из-за резолвера.

13. Все DNS-запросы с сервера и ответы на них.

sudo tcpdump -i any -nn port 53

# пример вывода
16:20:11.512345 IP 198.51.100.10.44121 > 8.8.8.8.53: 51823+ A? api.example.ru. (32)
16:20:11.531902 IP 8.8.8.8.53 > 198.51.100.10.44121: 51823 1/0/0 A 192.0.2.44 (48)
16:20:11.532210 IP 198.51.100.10.44122 > 8.8.8.8.53: 51824+ AAAA? api.example.ru. (32)

Что видим: 51823+ — id запроса и флаг рекурсии, A? — тип, в ответе 1/0/0 — число записей в секциях answer/authority/additional. Если приложение на каждый вызов API делает A и AAAA и ждёт оба — это лишние миллисекунды на каждый запрос.

14. Ловим NXDOMAIN и SERVFAIL.

sudo tcpdump -i any -nn -l 'udp src port 53' | grep -E --line-buffered 'NXDomain|ServFail|Refused'

# пример вывода
16:22:03.114509 IP 8.8.8.8.53 > 198.51.100.10.44140: 51902 NXDomain 0/1/0 (98)
16:22:03.115877 IP 8.8.8.8.53 > 198.51.100.10.44141: 51903 NXDomain 0/1/0 (98)

Что видим: NXDomain с 0 ответов и одной записью SOA в authority. По id запроса находим имя — чаще всего опечатка в конфиге или домен, который перестали делегировать. ServFail — проблема резолвера или авторитетных серверов зоны.

15. Сколько отвечает резолвер.

sudo tcpdump -i any -nn -ttt port 53

# пример вывода
 00:00:00.000000 IP 198.51.100.10.44150 > 10.0.0.2.53: 52011+ A? cdn.example.ru. (32)
 00:00:04.998871 IP 198.51.100.10.44150 > 10.0.0.2.53: 52011+ A? cdn.example.ru. (32)
 00:00:00.019402 IP 10.0.0.2.53 > 198.51.100.10.44150: 52011 2/0/0 A 192.0.2.60, A 192.0.2.61 (64)

Что видим: первый запрос без ответа, через 5 секунд (таймаут resolv.conf по умолчанию) — повтор с тем же id, ответ на него за 19 мс. Для пользователя это 5 секунд ожидания на ровном месте: первый резолвер в списке теряет пакеты.

ICMP: ping, unreachable и «fragmentation needed»

ICMP — служебные сообщения сети о том, что пошло не так. Их часто режут файрволами, и тогда TCP ломается тихо: без сообщения о нужной фрагментации соединение зависает на больших пакетах.

16. Доходит ли ping и отвечаем ли мы.

sudo tcpdump -i eth0 -nn 'icmp[icmptype] = icmp-echo or icmp[icmptype] = icmp-echoreply'

# пример вывода
17:05:30.100211 IP 203.0.113.7 > 198.51.100.10: ICMP echo request, id 4211, seq 1, length 64
17:05:30.100240 IP 198.51.100.10 > 203.0.113.7: ICMP echo reply, id 4211, seq 1, length 64

Что видим: ответ через 29 мкс — сервер отвечает мгновенно. Если request есть, а reply нет — ICMP запрещён файрволом или sysctl icmp_echo_ignore_all; если нет даже request, пакеты режут до сервера.

17. Unreachable и need to frag.

sudo tcpdump -i eth0 -nn 'icmp[icmptype] = icmp-unreach'

# пример вывода
17:08:12.410733 IP 10.20.0.1 > 198.51.100.10: ICMP 203.0.113.7 unreachable - need to frag (mtu 1400), length 36
17:09:40.220118 IP 192.0.2.1 > 198.51.100.10: ICMP host 192.0.2.77 unreachable - admin prohibited filter, length 36

Что видим: маршрутизатор 10.20.0.1 сообщает, что до 203.0.113.7 пролезают пакеты не больше 1400 байт, а мы шлём 1500 с флагом DF. Если такое сообщение приходит — Path MTU Discovery работает и ядро само уменьшит сегменты; если его фильтруют по пути, получаем ретрансмиты из примера 7. «Admin prohibited» — чужой файрвол явно отбросил наш пакет.

Запись дампа с ротацией и разбор в tshark

Проблема, которая случается «раз в час», ловится только записью в файл с ротацией: tcpdump пишет по кругу, а вы разбираете нужный фрагмент после инцидента.

18. Писать час по 10 минут и читать в tshark.

# новый файл каждые 600 с; вместе с -G ключ -W 6 завершит запись после 6 файлов
sudo tcpdump -i eth0 -nn -s 128 -w '/var/tmp/web-%Y%m%d-%H%M.pcap' -G 600 -W 6 'port 443'
# кольцевой буфер по размеру: 10 файлов по 100 МБ, старые перезаписываются
sudo tcpdump -i eth0 -nn -s 128 -w /var/tmp/web.pcap -C 100 -W 10 'port 443'

# пример вывода при остановке
^C48213 packets captured
48302 packets received by filter
89 packets dropped by kernel

# разбор
tshark -r /var/tmp/web-20260922-1410.pcap -Y 'tcp.analysis.retransmission' | wc -l
tshark -r /var/tmp/web-20260922-1410.pcap -q -z io,stat,60

Что видим: 89 пакетов потеряло ядро — буфер не успевал, лечится -B 16384 и более узким фильтром. Snaplen 128 сохраняет заголовки Ethernet, IP и TCP с опциями, но обрезает тело: файлы в разы меньше и без персональных данных. tshark читает те же pcap и умеет то, чего нет в tcpdump: помечает ретрансмиты и считает статистику по интервалам.

Продвинутые фильтры: исключить лишнее, большие пакеты, PHP-FPM

Два приёма, без которых дамп на живом сервере не читается: убрать собственную SSH-сессию и смотреть локальный трафик между nginx и бэкендом отдельно.

19. Без своего SSH и только большие кадры.

sudo tcpdump -i eth0 -nn -e 'not port 22 and greater 1400'

# пример вывода
18:11:05.774102 52:54:00:aa:bb:cc > c0:3f:d5:11:22:33, ethertype IPv4 (0x0800), length 1514: 198.51.100.10.443 > 203.0.113.7.51214: Flags [.], seq 1:1461, ack 1, win 509, length 1460
18:11:05.774180 52:54:00:aa:bb:cc > c0:3f:d5:11:22:33, ethertype IPv4 (0x0800), length 1514: 198.51.100.10.443 > 203.0.113.7.51214: Flags [.], seq 1461:2921, ack 1, win 509, length 1460

Что видим: кадры ровно по 1514 байт — 14 Ethernet + 20 IP + 20 TCP + 1460 данных. Если именно они не подтверждаются, а пакеты меньше 1400 проходят, диагноз — MTU. Без not port 22 дамп через SSH зациклится: каждая напечатанная строка порождает пакет, который тут же печатается.

20. Что nginx отправляет в PHP-FPM.

sudo tcpdump -i lo -nn -l -A port 9000 | grep -a --line-buffered -oE '(REQUEST_URI|SCRIPT_FILENAME|HTTP_HOST)[^ ]{1,80}'

# пример вывода
HTTP_HOSTexample.ru
SCRIPT_FILENAME/var/www/example.ru/public/index.php
REQUEST_URI/catalog/?page=3

Что видим: FastCGI передаёт параметры парами с двоичными длинами вместо разделителей, поэтому имя и значение склеены, но видно, тот ли SCRIPT_FILENAME уходит в PHP. Если PHP-FPM слушает unix-сокет (listen = /run/php/php8.3-fpm.sock), tcpdump не увидит ничего: unix-сокеты не проходят через сетевой стек. Тогда либо временно переключить на 127.0.0.1:9000, либо strace -f -e trace=network на воркер.

Какой фильтр брать под конкретный симптом

Сводная таблица: жалоба → команда → что должно быть в дампе. Номера в скобках — примеры выше.

Симптом Фильтр tcpdump Что искать
Сайт «думает» и отваливается по таймауту tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0 SYN есть, SYN-ACK нет → файрвол или backlog (5)
Connection refused tcp[tcpflags] & tcp-rst != 0 RST с win 0 на SYN → никто не слушает (6)
Открывается, но большие страницы виснут -e greater 1400 / icmp-unreach Повторы сегментов 1460, нет «need to frag» (7, 17, 19)
502/504 у части запросов tcp src port 80 and tcp[...:4] = 0x48545450 Коды на lo от апстрима, паузы до ответа (9, 10)
Ошибка сертификата у части клиентов tcp[...] = 0x16 и 0x15 на 443 SNI в ClientHello, код alert (11, 12)
Первый запрос медленный, повторные быстрые -ttt port 53 Повтор запроса через 5 с, NXDomain (14, 15)
Подозрение на бота или DDoS net X/24 + счётчик SYN по src Один адрес с сотнями SYN (4)
Проблема повторяется раз в час -w ... -G 600 -W 6 -s 128 Разбор нужного файла в tshark (18)

tcpdump, tshark, Wireshark или ss: что выбрать

Это четыре инструмента под разные вопросы. tcpdump — захват на сервере, tshark и Wireshark — разбор с полным декодированием, ss — состояние сокетов без захвата вообще.

Критерий tcpdump tshark Wireshark ss
Что показывает Пакеты, заголовки Пакеты, полное декодирование То же, графически Сокеты и очереди
Где живёт Любой Linux-сервер Сервер, отдельный пакет Рабочая станция Любой Linux, iproute2
Фильтры BPF при захвате BPF + display-фильтры по полям Те же, что у tshark Свои: state, dport, dst
Ретрансмиты Глазами, по seq tcp.analysis.retransmission Expert Info ss -ti: счётчик retrans
TLS SNI Байтовый фильтр + -X Отдельное поле Декодируется Нет
Нагрузка на сервер Минимальная с -n и -w Выше: декодирует каждый пакет На сервере не запускают Ничтожная
Windows Нет; pktmon Да, с Npcap Да, с Npcap Нет; netstat -ano

Безопасность: что нельзя делать с дампами

Дамп трафика — это cookies, токены и персональные данные пользователей в открытом виде везде, где нет TLS. Правило одно: перехватывать только на своём сервере и хранить ровно столько, сколько нужно для разбора.

Четыре правила для pcap на продакшене

1. Снимать трафик только на серверах, которыми вы управляете, и только в рамках задачи. 2. По умолчанию резать нагрузку: для TCP-диагностики хватает -s 128, тела запросов туда не попадают. 3. Не пересылать pcap в мессенджеры и тикеты — в нём могут быть сессионные cookie и Authorization-заголовки; передавайте вывод tshark по нужным полям. 4. Удалять файлы после разбора и не оставлять tcpdump с -w работать «на всякий случай» неделями.

Чего tcpdump не покажет: доступность снаружи

tcpdump отвечает на вопрос «что сейчас происходит на сервере»: доходят ли пакеты и чем на них отвечает ядро. Он не отвечает на вопрос «виден ли сайт из Новосибирска» — там пакеты могут не доходить до вашей сетевой карты вовсе, их отбросит провайдер, магистральный маршрутизатор или фильтр у хостера.

Для второго вопроса нужен взгляд снаружи из нескольких точек. Проверка TCP-порта устанавливает соединение с внешних локаций и показывает, откуда рукопожатие проходит, а откуда нет — это пример 5 с другой стороны. HTTP-проверка получает страницу целиком и сравнивает код ответа и время с порогами, то есть закрывает примеры 9 и 10 без доступа к консоли.

tcpdump — когда уже сломалось, мониторинг — чтобы узнать первым

Пруфен проверяет доступность порта и HTTP-ответ сайта с интервалом от 2 минут из 13 точек мониторинга — 11 в России, а также Минск и Испания — и присылает уведомление в Email, Telegram или Макс, когда сайт перестал отвечать; если ресурс так и не поднялся, подключается голосовой звонок. Результат виден по каждой точке отдельно, поэтому к консоли с tcpdump вы приходите уже зная, с какой стороны искать. Бесплатный план — 5 проверок.

Частые вопросы

Видит ли tcpdump содержимое HTTPS?

Нет. Он видит факт рукопожатия, SNI в ClientHello, размеры и тайминги записей, коды алертов в TLS 1.2 — но не URL, заголовки и тело. Расшифровать сессию можно только в Wireshark с ключами, сохранёнными на стороне клиента через SSLKEYLOGFILE; для чужих клиентов на сервере это невозможно. Для диагностики сайта обычно и не нужно: снимайте открытый HTTP на lo между nginx и приложением, как в примерах 9 и 10.

Почему tcpdump не показывает пакеты, хотя сайт работает?

По частоте: не тот интерфейс (запустите с -i any), трафик идёт через unix-сокет или внутри контейнера в другом сетевом namespace, включён -w без --print (пакеты уходят в файл, экран пуст), и наконец забытый -n — без него tcpdump тратит секунды на резолв имён и строки появляются с задержкой. Опечатка в фильтре обычно даёт ошибку синтаксиса сразу, а вот логически пустой фильтр tcpdump молча ждёт вечно.

Как захватить трафик внутри Docker-контейнера?

С хоста, не заходя в контейнер: узнайте PID через docker inspect -f '{{.State.Pid}}' имя и выполните sudo nsenter -t PID -n tcpdump -i eth0 -nn — tcpdump хоста окажется в сетевом namespace контейнера. Второй способ — захват на хосте с -i any: трафик контейнеров проходит через veth-интерфейсы и мост docker0. Если всё же ставите tcpdump в образ, контейнеру нужен --cap-add NET_RAW.

tcpdump грузит сервер?

Фильтр BPF исполняется в ядре, поэтому отбор пакетов стоит дёшево даже на гигабитном канале. Дорого то, что после: копирование каждого пакета в пользовательское пространство, резолв имён без -n, печать с -A или -v. Практика: узкий фильтр, -nn, запись через -w вместо экрана, snaplen 96–128. Если растёт «packets dropped by kernel», увеличьте буфер ключом -B — это не добавляет нагрузки, только полноты дампа.

Была ли статья полезна?

Начните мониторинг прямо сейчас

Бесплатный тариф — до 5 проверок. 150 ₽ на баланс при регистрации.

Создать аккаунт