⚙️ Паровой сервер ROADIT

tcpdump: шпаргалка по флагам и фильтрам — 10 готовых команд

tcpdump — тот самый инструмент, который достаёт из сетевого тумана детали, обычно скрытые за словами «что-то с сетью». Когда сервис не подключается, DNS внезапно молчит, TCP-сессия рвётся или пакет вроде бы «уходит», но так и не приходит, сниффер превращает догадки в факты.

В этой статье соберём практическую шпаргалку: основные флаги tcpdump, синтаксис BPF-фильтров и 10 готовых команд, которые можно применять на сервере практически сразу.

Все примеры рассчитаны на Linux и классический tcpdump. Для захвата трафика обычно требуются права root или capability CAP_NET_RAW/CAP_NET_ADMIN.



⚙️ Содержание

Перед стартом: что именно делает tcpdump

У tcpdump есть две принципиально разные части:

tcpdump [опции] [выражение-фильтр]

Например:

sudo tcpdump -i eth0 -nn tcp port 443

Здесь:

  • -i eth0 — слушать интерфейс eth0;
  • -nn — не преобразовывать IP-адреса в имена и номера портов в названия сервисов;
  • tcp port 443 — BPF-фильтр, оставляющий только TCP-трафик на порт 443.

Самое важное: опции tcpdump и фильтр — не одно и то же.


Часто используемые флаги

ФлагЧто делает
-i INTERFACEвыбрать интерфейс
-Dпоказать доступные интерфейсы
-nне разрешать IP в DNS-имена
-nnне разрешать IP и номера портов
-vподробный вывод
-vvещё подробнее
-vvvмаксимально подробный вывод
-c Nостановиться после N пакетов
-s Nдлина захватываемой части пакета
-Aпоказать полезную нагрузку как ASCII
-Xпоказать payload в hex + ASCII
-w FILEзаписать захват в .pcap
-r FILEчитать ранее записанный .pcap
-tубрать timestamp из вывода
-qболее краткий вывод
-eпоказывать Ethernet-заголовок и MAC
-Sпоказывать абсолютные TCP sequence numbers

На практике хорошая отправная точка:

sudo tcpdump -i eth0 -nn

Если вы расследуете проблему на сервере, -nn почти всегда стоит включать: DNS-резолвинг во время самого расследования только добавляет шум и может породить новые DNS-запросы.


Как узнать имя интерфейса

Не угадывайте eth0. На современных системах интерфейс вполне может называться ens18, enp1s0, bond0, br0, vlan100 или ещё интереснее.

Начните с:

sudo tcpdump -D

Пример:

1.eth0
2.any
3.lo
4.br0
5.docker0

Альтернативно:

ip -br link

или:

ip -br addr

Интерфейс any особенно удобен для первичного расследования:

sudo tcpdump -i any -nn

Но есть нюанс: при работе с any информация канального уровня может отличаться от захвата на конкретном Ethernet-интерфейсе. Если вам нужны точные MAC/VLAN-детали, лучше захватывать конкретный интерфейс.


Десять готовых команд tcpdump

Команда №1. Посмотреть весь трафик интерфейса

Начнём с парового котла — захватим всё:

sudo tcpdump -i eth0 -nn

Остановить захват:

Ctrl+C

Чтобы ограничить количество пакетов:

sudo tcpdump -i eth0 -nn -c 100

Это хороший вариант, когда нужно быстро понять, вообще жив ли интерфейс и какой трафик через него проходит.

Например, если сервер должен принимать HTTP-запросы, а tcpdump показывает только исходящие пакеты, уже появляется направление для расследования.

Полезный вариант для первичной диагностики

sudo tcpdump -i any -nn -c 100

Он позволяет не гадать, через какой интерфейс действительно идёт пакет.

Команда №2. Найти трафик конкретного хоста

Допустим, приложение общается с сервером 10.10.20.15.

sudo tcpdump -i eth0 -nn host 10.10.20.15

Фильтр host ловит трафик в обоих направлениях.

Можно разделить направления:

sudo tcpdump -i eth0 -nn src host 10.10.20.15

Только пакеты, где указанный адрес является источником.

И наоборот:

sudo tcpdump -i eth0 -nn dst host 10.10.20.15

Только пакеты, направленные на этот адрес.

Несколько хостов

sudo tcpdump -i eth0 -nn 'host 10.10.20.15 or host 10.10.20.16'

Для сложных выражений лучше использовать одинарные кавычки, чтобы shell не начал интерпретировать специальные символы.

Команда №3. Смотреть конкретный порт

Например, нужно проверить HTTPS:

sudo tcpdump -i eth0 -nn port 443

Только TCP:

sudo tcpdump -i eth0 -nn tcp port 443

Только UDP:

sudo tcpdump -i eth0 -nn udp port 53

Можно ограничить направление:

sudo tcpdump -i eth0 -nn dst port 443

или:

sudo tcpdump -i eth0 -nn src port 443

Несколько портов

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

А если нужно исключить SSH, чтобы собственное подключение администратора не забивало экран:

sudo tcpdump -i eth0 -nn 'not tcp port 22'

Это особенно полезно на удалённом сервере.

Команда №4. Разобрать DNS

DNS — вечная классика сетевого паровоза.

Посмотреть DNS-запросы:

sudo tcpdump -i any -nn udp port 53

Поскольку DNS может использовать TCP:

sudo tcpdump -i any -nn 'udp port 53 or tcp port 53'

Можно смотреть запросы конкретного клиента:

sudo tcpdump -i any -nn 'host 10.10.10.50 and port 53'

А если нужен только DNS-трафик между сервером и конкретным DNS-резолвером:

sudo tcpdump -i any -nn 'host 10.10.10.1 and port 53'

Что искать

Типичная последовательность:

client → DNS server     query
DNS server → client     response

Если виден запрос, но нет ответа:

10.10.10.50.42132 > 10.10.10.1.53: DNS?

и дальше тишина — проблема уже явно находится где-то после отправки запроса: сеть, firewall, ACL, DNS-сервис или обратный путь.

Команда №5. Проверить TCP handshake

Когда говорят «порт закрыт» или «сервис недоступен», первым делом интересно увидеть TCP handshake.

Фильтр:

sudo tcpdump -i any -nn 'tcp port 443'

Нормальное установление TCP-соединения выглядит примерно так:

Client → Server   SYN
Server → Client   SYN, ACK
Client → Server   ACK

Для более точного поиска SYN-пакетов:

sudo tcpdump -i any -nn 'tcp[tcpflags] & tcp-syn != 0'

Только SYN без ACK:

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

Это уже BPF-магия.

Если видите:

client > server: Flags [S]
client > server: Flags [S]
client > server: Flags [S]

но SYN,ACK не появляется, серверный ответ не доходит до точки захвата либо сервер вообще не отвечает.

Если появляется:

server > client: Flags [R.]

то соединение было сброшено TCP RST.

А если есть полноценный handshake, проблема, скорее всего, находится выше TCP-уровня: TLS, HTTP, приложение, авторизация и т. п.

Команда №6. Найти TCP Reset

Когда соединение внезапно «умирает», полезно отдельно поискать RST.

sudo tcpdump -i any -nn 'tcp[tcpflags] & tcp-rst != 0'

Можно ограничить конкретным хостом:

sudo tcpdump -i any -nn \
  'host 10.10.20.15 and tcp[tcpflags] & tcp-rst != 0'

RST может появляться по разным причинам:

  • приложение закрыло соединение;
  • порт не слушается;
  • firewall генерирует reset;
  • промежуточное устройство вмешивается в соединение;
  • произошла ошибка состояния TCP.

Поэтому RST сам по себе не доказывает, что виноват firewall.

Нужно смотреть направление пакета и контекст всей TCP-сессии.

Команда №7. Понять, кто разговаривает с сервером

Иногда проблема формулируется просто: «На сервер внезапно летит много соединений. Кто это?»

Можно начать с:

sudo tcpdump -i eth0 -nn 'tcp dst port 8080'

Для более подробного вывода:

sudo tcpdump -i eth0 -nn -tttt 'tcp dst port 8080'

-tttt выводит timestamp в более привычном формате.

Например:

2026-09-01 17:10:01.123456 IP 10.10.10.25.49312 > 10.10.10.10.8080: Flags [S]

Сразу видно:

  • время;
  • источник;
  • исходный порт;
  • назначение;
  • порт сервиса;
  • TCP-флаги.

Для предварительной оценки количества SYN можно использовать:

sudo tcpdump -i eth0 -nn \
  'tcp dst port 8080 and tcp[tcpflags] & tcp-syn != 0'

Это уже хороший материал для дальнейшего анализа, хотя tcpdump сам по себе не является полноценным инструментом статистики.

Команда №8. Посмотреть содержимое незашифрованного протокола

Иногда заголовков недостаточно. Например, нужно посмотреть HTTP-трафик.

sudo tcpdump -i eth0 -nn -A 'tcp port 80'

-A пытается показать payload как ASCII.

Для hex + ASCII:

sudo tcpdump -i eth0 -nn -X 'tcp port 80'

Например, можно увидеть HTTP-заголовки:

GET / HTTP/1.1
Host: example.internal
User-Agent: ...

Но есть важное ограничение: Для HTTPS содержимое HTTP внутри TLS в обычном tcpdump не будет видно. Вы увидите TCP и TLS-записи, но не обычный открытый HTTP request/response.

Осторожно с -A

Не стоит использовать:

sudo tcpdump -i any -A

на загруженном production-сервере без фильтра. Поток текста может превратить терминал в паровой двигатель, работающий на угле размером с дата-центр.

sudo tcpdump -i eth0 -nn -A -c 20 'host 10.10.10.50 and tcp port 80'

Команда №9. Записать трафик в PCAP

Для серьёзного расследования лучше не пытаться анализировать всё глазами прямо в терминале. Запишите захват:

sudo tcpdump -i eth0 -nn -w incident.pcap

Остановите:

Ctrl+C

После этого файл можно анализировать в Wireshark или повторно через tcpdump. Например:

tcpdump -nn -r incident.pcap

С фильтром:

tcpdump -nn -r incident.pcap 'tcp port 443'

Или:

tcpdump -nn -r incident.pcap 'host 10.10.20.15'

Почему PCAP лучше терминала

PCAP сохраняет захваченные данные в структурированном виде. Можно:

  • вернуться к расследованию позже;
  • передать файл коллеге;
  • применить разные фильтры;
  • открыть захват в Wireshark;
  • анализировать конкретные TCP-сессии;
  • сравнивать несколько захватов.

Но помните: PCAP может содержать чувствительные данные, включая cookie, токены, содержимое незашифрованных протоколов и внутренние IP-адреса.

Команда №10. Отфильтровать сразу несколько условий

Самая мощная часть tcpdump — BPF-выражения. Допустим, нужно посмотреть HTTPS к одному серверу:

sudo tcpdump -i eth0 -nn \
  'host 10.10.20.15 and tcp port 443'

Или весь трафик хоста, кроме SSH:

sudo tcpdump -i eth0 -nn \
  'host 10.10.20.15 and not tcp port 22'

Или DNS плюс HTTPS:

sudo tcpdump -i any -nn \
  'udp port 53 or tcp port 443'

Можно строить достаточно сложные выражения:

sudo tcpdump -i any -nn \
  '(src host 10.10.10.50 or src host 10.10.10.51) and tcp port 443'

Логические операторы

Основные:

and
or
not

Также используются:

&&
||
!

Но для shell-команд безопаснее и понятнее писать фильтр в одинарных кавычках:

'tcp port 443 and not host 10.10.10.50'

BPF-фильтры: маленький язык большого котла

Синтаксис фильтра позволяет комбинировать несколько примитивов.

По протоколу

tcp
udp
icmp
arp
ip
ip6

Например:

sudo tcpdump -i eth0 -nn icmp

Поймаем ping.

По адресу

host 192.168.1.10
src host 192.168.1.10
dst host 192.168.1.10

По сети

net 192.168.1.0/24

Только источник:

src net 192.168.1.0/24

По порту

port 443
src port 12345
dst port 443

По диапазону портов

portrange 8000-8100

Например:

sudo tcpdump -i eth0 -nn 'tcp portrange 8000-8100'

Фильтрация TCP-флагов

TCP-флаги — один из самых полезных инструментов при диагностике соединений. Основные:

SYN
ACK
FIN
RST
PSH
URG
ECE
CWR

Например, все SYN:

'tcp[tcpflags] & tcp-syn != 0'

Все RST:

'tcp[tcpflags] & tcp-rst != 0'

FIN:

'tcp[tcpflags] & tcp-fin != 0'

SYN без ACK:

'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'

Это особенно полезно при расследовании:

  • connection flood;
  • проблем с firewall;
  • закрывающихся соединений;
  • странного поведения балансировщиков;
  • проблем с TCP handshake.

-s и snaplen: сколько пакета захватывать

По умолчанию tcpdump может захватывать только часть пакета, если snapshot length недостаточен для конкретной задачи. Можно задать размер явно:

sudo tcpdump -i eth0 -nn -s 0

-s 0 означает захватывать пакет целиком, насколько это поддерживается текущей версией/libpcap и позволяет интерфейс. Для анализа только заголовков полный пакет обычно не нужен. Для PCAP, который потом будет разбираться в Wireshark, часто удобно:

sudo tcpdump -i eth0 -nn -s 0 -w capture.pcap

Однако полный захват означает больше данных и, соответственно, больший файл.


-c: ограничиваем аппетит сниффера

Не всегда нужно держать захват открытым бесконечно. Например:

sudo tcpdump -i eth0 -nn -c 50 'icmp'

Получить ровно 50 ICMP-пакетов и завершиться. Это удобно для автоматизации и быстрых диагностических тестов:

sudo tcpdump -i any -nn -c 20 'host 10.10.10.50 and tcp port 443'

Особенно полезно в скриптах, где процесс должен завершиться самостоятельно.


-v, -vv, -vvv: когда нужно больше пара

Базовый вывод:

sudo tcpdump -i eth0 -nn 'udp port 53'

Подробнее:

sudo tcpdump -i eth0 -nn -v 'udp port 53'

Ещё подробнее:

sudo tcpdump -i eth0 -nn -vv 'udp port 53'

И максимально подробно:

sudo tcpdump -i eth0 -nn -vvv 'udp port 53'

Не стоит автоматически использовать -vvv. Подробность должна помогать расследованию, а не превращать вывод в иероглифы из медных шестерёнок.


-e: когда нужны MAC-адреса

Если расследуется проблема на L2, обычного IP-заголовка недостаточно. Используйте:

sudo tcpdump -i eth0 -nn -e

Можно увидеть:

MAC source → MAC destination
IP source → IP destination

Это помогает при диагностике:

  • ARP;
  • VLAN;
  • bridge;
  • проблем с виртуализацией;
  • неправильного MAC forwarding;
  • L2-коммутации.

Например:

sudo tcpdump -i eth0 -nn -e arp

Практический сценарий: «Сервис недоступен»

Представим классическую ситуацию. Приложение на 10.10.10.20 пытается подключиться к HTTPS-сервису 10.10.20.30:443, но получает timeout. Не начинайте с двадцати команд. Двигайтесь слоями.

Шаг 1. Есть ли вообще попытка соединения?

sudo tcpdump -i any -nn \
  'host 10.10.20.30 and tcp port 443'

Если ничего нет — проблема может находиться ещё до сервера или приложение вообще не делает подключения.

Шаг 2. Есть ли SYN?

sudo tcpdump -i any -nn \
  'dst host 10.10.20.30 and dst port 443 and tcp[tcpflags] & tcp-syn != 0'

Шаг 3. Приходит ли SYN-ACK?

Смотрите общий поток:

sudo tcpdump -i any -nn \
  'host 10.10.20.30 and tcp port 443'

Нормальная картина:

client → server  [S]
server → client  [S.]
client → server  [.]

Если:

client → server  [S]
client → server  [S]
client → server  [S]

и ответа нет, ищем проблему на пути или на стороне сервера.

Шаг 4.Есть ли RST?

sudo tcpdump -i any -nn \
  'host 10.10.20.30 and tcp port 443 and tcp[tcpflags] & tcp-rst != 0'

Шаг 5. Если TCP поднялся — смотрим дальше

Если handshake успешен, но приложение всё равно жалуется:

sudo tcpdump -i any -nn 'host 10.10.20.30 and tcp port 443'

Для HTTPS содержимое без дополнительных механизмов расшифровки не видно, поэтому дальше уже имеет смысл смотреть TLS, приложение, сертификаты и логи сервиса.


Практический сценарий: «Куда пропадает DNS?»

Допустим, сервер не может разрешить имя. Сначала:

sudo tcpdump -i any -nn 'port 53'

Запускаем параллельно:

getent hosts example.com

или:

dig example.com

Теперь смотрим:

client → DNS: query
DNS → client: response

Если запроса нет — приложение или системный resolver не отправляет его туда, куда вы ожидаете. Если запрос есть, а ответа нет — смотрим DNS-сервер и сеть. Если ответ приходит, но приложение всё равно жалуется — вероятно, проблема уже не в доставке DNS-пакетов.


Практический сценарий: сохранить небольшой диагностический дамп

Для коллеги или тикета не обязательно отправлять гигабайты трафика. Например:

sudo tcpdump -i any -nn -s 0 -c 500 \
  -w /tmp/diagnostic.pcap \
  'host 10.10.20.30 and tcp port 443'

Здесь:

  • -i any — все интерфейсы;
  • -nn — без DNS/service resolution;
  • -s 0 — полный snaplen;
  • -c 500 — максимум 500 пакетов;
  • -w — запись в PCAP;
  • фильтр — только нужный трафик.

После захвата:

ls -lh /tmp/diagnostic.pcap

А затем:

tcpdump -nn -r /tmp/diagnostic.pcap

Что делать с большим трафиком

Главное правило tcpdump: Фильтруйте как можно раньше.

Плохо:

sudo tcpdump -i eth0 -w huge.pcap

а потом пытаться найти среди миллионов пакетов нужный IP. Лучше:

sudo tcpdump -i eth0 -nn -w https.pcap \
  'host 10.10.20.30 and tcp port 443'

Ещё лучше, если известен конкретный сценарий:

sudo tcpdump -i eth0 -nn -c 1000 -w handshake.pcap \
  'host 10.10.20.30 and tcp[tcpflags] & tcp-syn != 0'

Чем точнее фильтр, тем меньше цифровой шлак приходится разбирать.


Важное предупреждение о безопасности

tcpdump — это не безобидный просмотрщик статистики. PCAP может содержать:

  • IP-адреса;
  • MAC-адреса;
  • DNS-запросы;
  • URL и HTTP-заголовки;
  • cookie;
  • токены;
  • содержимое незашифрованных протоколов;
  • служебную информацию инфраструктуры.

Поэтому:

sudo tcpdump -i any -w /tmp/debug.pcap

на production-сервере — операция, к которой стоит относиться так же серьёзно, как к копированию логов с чувствительными данными. Храните дампы ограниченное время и передавайте их только тем, кому они действительно нужны.


Шпаргалка: 10 команд в одном месте

ЗадачаКоманда
Весь трафикsudo tcpdump -i eth0 -nn
Конкретный хостsudo tcpdump -i eth0 -nn host 10.10.20.15
HTTPSsudo tcpdump -i eth0 -nn tcp port 443
DNSsudo tcpdump -i any -nn 'udp port 53 or tcp port 53'
TCP SYNsudo tcpdump -i any -nn 'tcp[tcpflags] & tcp-syn != 0'
TCP RSTsudo tcpdump -i any -nn 'tcp[tcpflags] & tcp-rst != 0'
HTTP payloadsudo tcpdump -i eth0 -nn -A 'tcp port 80'
Запись PCAPsudo tcpdump -i eth0 -nn -w capture.pcap
Чтение PCAPtcpdump -nn -r capture.pcap
Сложный фильтрsudo tcpdump -i eth0 -nn 'host 10.10.20.15 and not tcp port 22'

Финальная шпаргалка по мышлению

tcpdump становится действительно мощным не тогда, когда вы запомнили сто ключей, а когда научились задавать правильный вопрос.

Кто?

host / src host / dst host

Куда?

port / dst port / portrange

Какой протокол?

tcp / udp / icmp / arp

В каком направлении?

src / dst

Что исключить?

not

Какой TCP-флаг?

tcp[tcpflags]

Куда сохранить результат?

-w capture.pcap

А затем этот набор можно собрать в одно выражение:

sudo tcpdump -i eth0 -nn \
  'src host 10.10.10.50 and dst host 10.10.20.30 and tcp dst port 443'

Вот и весь принцип: не пытайтесь смотреть весь паровой котёл сразу — перекройте лишние клапаны фильтрами и оставьте только нужную трубу.



⚙️ Машинное отделение ROADIT благодарит за прочтение.
Больше команд, шпаргалок и обзоров — на roadit.ru и в нашем Телеграф-канале.
📋 Все команды


Оставьте комментарий