Захват трафика: tcpdump для диагностики сети

Рейтинг: 48.7% · 7 голосов
Подробный курс по диагностике и производительности Linux для админов и DevOps: с чего начать, методология USE, логи (journalctl, dmesg), процессы, CPU, память и OOM, диск и IO (iostat), сеть (ss, tcpdump), системные вызовы и strace, ltrace, perf, флеймграфы, ftrace, eBPF и bpftrace, lsof, мониторинг. Разбор каждого инструмента с чтением вывода.
Ответить
Аватара пользователя
Dmitry_SRE
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Захват трафика: tcpdump для диагностики сети

Сообщение Dmitry_SRE »

Оглавление курса (47)
  1. С чего начать диагностику Linux: методология вместо паники
  2. Первые 60 секунд: экспресс-диагностика нагруженного сервера
  3. Методологии диагностики: USE, RED и здравый смысл
  4. Логи systemd через journalctl: где искать причину
  5. Где лежат логи Linux: /var/log, dmesg и rsyslog
  6. Источники правды: load average, /proc и /sys
  7. Процессы Linux: ps, pstree и состояния процессов
  8. Интерактивный мониторинг: top и htop
  9. Метрики процессов во времени: pidstat
  10. Приоритеты и ограничения: nice, ionice, cgroups
  11. Сигналы и зависшие процессы: kill, и что делать с D-state
  12. Загрузка CPU: user, system, iowait, steal и контекст-свитчи
  13. Диагностика CPU по ядрам: vmstat и mpstat
  14. Профилирование CPU: perf top и поиск пожирателя
  15. Частоты, троттлинг и NUMA: turbostat и numastat
  16. Память Linux: RSS, VSZ, page cache и миф о нехватке памяти
  17. Сколько памяти занято: free, /proc/meminfo и vmstat
  18. Поиск утечек и пожирателей памяти: smem, pmap, smaps
  19. Swap и подкачка: swapon, swappiness, когда своп - это боль
  20. OOM killer: кто и за что убил процесс
  21. Память ядра и slab: slabtop и куда уходит RAM
  22. Подсистема ввода-вывода: путь запроса от приложения до диска
  23. Диагностика диска: iostat и чтение await, %util
  24. Кто грузит диск: iotop и атрибуция io процессам
  25. Файловые системы: df, du, иноды и куда делось место
  26. Глубокая диагностика блочного слоя: blktrace и biolatency
  27. Кеш страниц и грязные данные: dirty pages, fsync, drop_caches
  28. Сетевой стек Linux: путь пакета и где возникают задержки
  29. Сокеты и соединения: ss и netstat
  30. Захват трафика: tcpdump для диагностики сети (вы здесь)
  31. Задержки и потери в сети: ping, mtr, диагностика латентности
  32. Сеть как источник проблем: nftables, conntrack, дропы
  33. Что такое системный вызов и зачем его трассировать
  34. strace: трассировка системных вызовов на практике
  35. strace в бою: почему программа висит, падает или тормозит
  36. ltrace: трассировка вызовов библиотек
  37. Накладные расходы трассировки и безопасные альтернативы
  38. perf: универсальный профайлер Linux
  39. Флеймграфы: визуализация профиля производительности
  40. Трассировка ядра: ftrace и trace-cmd
  41. eBPF: революция в наблюдаемости Linux
  42. Инструменты eBPF на практике: BCC и bpftrace
  43. lsof: открытые файлы, дескрипторы, кто держит файл и порт
  44. Разбор кейса: приложение тормозит - пошаговая диагностика
  45. Непрерывный мониторинг: sar, node_exporter, Grafana, Zabbix
  46. Диагностика в контейнерах: cgroups, лимиты, Docker и Kubernetes
  47. Карта инструментов и сквозной разбор инцидента производительности
Сетевые проблемы коварны тем, что снаружи все выглядит правильно. Конфиг вылизан, сервис слушает порт, фаервол вроде открыт, а соединение не устанавливается или рвется на ровном месте. Можно часами гадать и менять настройки наугад. А можно перестать гадать и посмотреть, что реально летает по проводу. Именно это и делает tcpdump - снифер пакетов, который показывает живой трафик на интерфейсе. Это не магия, а перехват того, что сетевая карта видит своими глазами.

В этом уроке разберем tcpdump в Linux от первого запуска до чтения вывода по полям. Будет много примеров tcpdump: как поймать конкретный хост, отфильтровать по порту, увидеть TCP-рукопожатие, поймать загадочный RST в ответе и записать дамп в файл для разбора в Wireshark. Утилита есть почти в любом дистрибутиве; если нет - ставится из пакета tcpdump (apt install tcpdump, dnf install tcpdump). На Astra Linux и RED OS все то же самое, утилита штатная. Актуально на 2026: стабильная ветка - tcpdump 4.99.x (последний релиз 4.99.6, конец 2025), ветка 5.0 еще в разработке, так что весь синтаксис ниже - это то, что у вас реально стоит в проде.

Как это работает и с чего начать в tcpdump linux

tcpdump просит ядро отдавать ему копии пакетов, проходящих через сетевой интерфейс. Технически это работает через AF_PACKET-сокет и кольцевой буфер в ядре, а отбор лишнего идет уже там, до того как пакет попадет в userspace. Поэтому почти всегда нужен root - обычный пользователь не имеет права слушать сырой трафик. Запускай через sudo.

Тонкость на 2026: вместо полного root правильнее выдать бинарю только нужные права через capabilities (CAP_NET_RAW и CAP_NET_ADMIN). Тогда tcpdump сможет ловить пакеты без полного sudo:

Код: Выделить всё

sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/tcpdump
Первое, что нужно знать - на каком интерфейсе ловить. Посмотреть список интерфейсов глазами самого tcpdump:

Код: Выделить всё

sudo tcpdump -D
Или привычным ip a / ip -br link. Дальше базовый запуск:

Код: Выделить всё

sudo tcpdump -n -i eth0
Здесь -i eth0 - слушать интерфейс eth0, а -n - НЕ резолвить адреса в имена. Флаг -n критично важен: без него tcpdump на каждый незнакомый адрес дергает DNS, тормозит и сам же генерит лишний трафик, засоряя твой же дамп (а на сломанном DNS - вообще зависает на резолве). Запомни как рефлекс: видишь tcpdump - дописывай -n. Если хочешь не резолвить еще и номера портов в имена служб, ставь -nn, тогда увидишь 443, а не https, и 53, а не domain.

Хочешь поймать любой активный интерфейс сразу - используй -i any. Удобно, когда не уверен, через какой интерфейс пойдет трафик (например, трафик контейнера может уходить через veth/docker0, а не через физический eth0). Учти: на -i any пакеты идут в режиме без точной L2-привязки, и фильтры по VLAN там работают иначе - для тонкого L2-разбора лови на конкретном интерфейсе.

Вывод бесконечный, останавливается по Ctrl+C. После остановки tcpdump печатает строку статистики вида packets captured / received by filter / dropped by kernel. Колонка dropped by kernel - первое, на что смотреть: если она не ноль, ядро не успевало отдавать пакеты и часть ты потерял (значит, фильтруй жестче или пиши в файл). Чтобы взять, скажем, только первые 20 пакетов и выйти:

Код: Выделить всё

sudo tcpdump -n -i eth0 -c 20
Флаг -c (count) - сколько пакетов поймать и завершиться. Очень спасает на нагруженном сервере, где без фильтра вывод улетает экраном в секунду.

Изображение

Фильтры BPF: host, port, src и dst - сердце tcpdump

Без фильтра ты утонешь в трафике. Сила tcpdump - в фильтрах BPF (Berkeley Packet Filter). Это маленький язык выражений, который пишут прямо в конце команды. Ядро отсеивает ненужное еще до того, как пакет дойдет до утилиты, - это и быстро, и экономит ту самую колонку dropped.

Базовые кирпичики:
  • host - трафик к адресу и от него: host 10.0.0.5
  • src / dst - только источник или только назначение: src host 10.0.0.5
  • port - по номеру порта (и TCP, и UDP): port 443
  • portrange - диапазон портов: portrange 8000-8100
  • net - целая подсеть: net 192.168.1.0/24
  • tcp / udp / icmp - по протоколу
Их соединяют через and, or, not. Пара примеров tcpdump ip и портов:

Код: Выделить всё

# весь обмен с конкретным IP
sudo tcpdump -n host 10.0.0.5

# только HTTPS-трафик к этому хосту
sudo tcpdump -n host 10.0.0.5 and port 443

# пакеты, ИДУЩИЕ на наш веб-сервер (мы - назначение)
sudo tcpdump -n dst host 10.0.0.5 and dst port 443

# вся подсеть, кроме SSH-шума (чтобы не видеть свою же сессию)
sudo tcpdump -n net 192.168.1.0/24 and not port 22
Отдельно про tcpdump udp - UDP без состояния, и тут снифер часто единственный способ понять, доходят ли пакеты вообще. Классика - проверить DNS-запросы:

Код: Выделить всё

sudo tcpdump -nn -i any udp port 53
Если запросы уходят, а ответов нет - проблема не у тебя, а дальше по пути: фаервол, резолвер, маршрут. Заметь, что современный systemd-resolved может ходить и по DNS-over-TLS на порт 853/tcp - тогда на 53/udp ты ничего не увидишь, и это не баг, а архитектура; лови тогда port 853.

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

Читаем вывод: TCP-рукопожатие, флаги и ретрансмиты

Главный навык - не запустить tcpdump, а ПРОЧИТАТЬ его вывод. Разберем строку по полям:

Код: Выделить всё

10:21:33.512345 IP 10.0.0.5.51512 > 93.184.216.34.443: Flags [S], seq 12345, win 64240, options [mss 1460,sackOK,TS val 9 ecr 0,nop,wscale 7], length 0
  • 10:21:33.512345 - время с микросекундами. По задержкам между строками видно тормоза (например, секунда тишины перед повтором).
  • IP - протокол сетевого уровня (был бы IP6 для IPv6).
  • 10.0.0.5.51512 > 93.184.216.34.443 - кто кому. Формат адрес.порт, стрелка > показывает направление. Тут наш клиент с эфемерного порта 51512 стучится на 443 (HTTPS) удаленного хоста.
  • Flags [S] - флаги TCP. Это самое полезное поле.
  • seq - номер последовательности (в свежих версиях по умолчанию относительный), win - размер окна приема, options - опции (mss, окно масштабирования wscale, метки времени TS), length - объем полезных данных в пакете.
Флаги в квадратных скобках - азбука TCP-соединения:
  • [S] - SYN, запрос на установку соединения
  • [S.] - SYN+ACK, сервер согласен (точка означает выставленный бит ACK)
  • [.] - чистый ACK, подтверждение
  • [P.] - PSH+ACK, передача данных с просьбой не буферизовать
  • [F.] - FIN+ACK, корректное закрытие половины соединения
  • [R] или [R.] - RST, грубый сброс соединения
Здоровое начало соединения - тройное рукопожатие, три строки подряд: [S] от клиента, [S.] от сервера, [.] от клиента. Видишь эту тройку - значит, до сервиса достучались на сетевом уровне, и дальше проблему ищи уже выше (TLS, приложение, аутентификация), а не в сети.

А теперь типовые диагнозы по выводу. Отбирать по флагам удобнее всего именованным синтаксисом tcp[tcpflags] - он читается человеком, в отличие от голых битовых масок.

Соединение не открывается, в ответ RST. Клиент шлет [S], а сервер тут же отвечает [R.]. Поймаем только установки и сбросы к хосту:

Код: Выделить всё

sudo tcpdump -n 'tcp[tcpflags] & (tcp-syn|tcp-rst) != 0 and host 10.0.0.5'
RST сразу после SYN почти всегда значит: порт закрыт, на нем никто не слушает, либо соединение режет фаервол через reject (а не drop). Проверяй, поднят ли сервис и слушает ли он нужный адрес: ss -tlnp. Частая ловушка - сервис слушает только 127.0.0.1, а ты стучишься на внешний IP; в ss это видно по колонке Local Address.

Клиент шлет SYN, а ответа вообще нет. Видишь только повторяющиеся [S] от клиента с растущими интервалами (примерно 1с, 2с, 4с) - это ретрансмиты SYN. Пакеты уходят в пустоту: их молча дропает фаервол (drop, а не reject) или ломается маршрут. Тут смотри уже на стороне сети и правил nftables/iptables, на маршруты (ip route get <ip>) и на MTU.

Поймать все попытки открыть соединение (чистый SYN без ACK) на сервере - проверенный синтаксис:

Код: Выделить всё

sudo tcpdump -n 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'
Эквивалент через числовую маску, который часто встречается в шпаргалках: tcp[13] & 0x12 = 0x02 ловит чистый SYN, а tcp[13] & 0x12 = 0x12 - именно SYN+ACK. Числа стоит знать, но именованные флаги надежнее и понятнее.

Чтобы увидеть содержимое пакетов, а не только заголовки, есть -A (печать в ASCII) и -X (hex + ASCII рядом). Для plaintext-протоколов это золото - видно сырой HTTP-запрос с методом, путем и заголовками:

Код: Выделить всё

sudo tcpdump -nn -A -i eth0 'tcp port 80'
Для HTTPS смысла мало - там шифр, увидишь кашу из байтов (разве что поймаешь ClientHello с именем сайта в SNI). Раньше для полного пакета добавляли -s 0 (snaplen, длина захвата; 0 - не обрезать). Актуально на 2026: современный tcpdump по умолчанию берет snaplen 262144 байта, чего хватает на целый пакет, а -s 0 теперь просто означает "использовать дефолт" и нужен лишь для совместимости со старыми версиями. Меньший snaplen, наоборот, иногда полезен: если тебе нужны только заголовки на гигабитном линке, -s 96 заметно снизит нагрузку и размер дампа.

Запись в файл и разбор в Wireshark

В консоли удобно смотреть на лету, но для серьезного разбора пиши дамп в файл формата pcap:

Код: Выделить всё

sudo tcpdump -n -i eth0 -w cap.pcap 'host 10.0.0.5 and port 443'
Флаг -w пишет сырые пакеты в файл (на экран при этом ничего не сыпется - так и должно быть, добавь -v, если хочешь видеть счетчик). Прочитать потом без сервера и без root:

Код: Выделить всё

tcpdump -n -r cap.pcap
Для долгого захвата, чтобы файл не разросся в гигабайты, используй кольцевую запись: -C режет файлы по размеру (в мегабайтах), -W задает, сколько файлов держать по кругу, -G - ротация по времени в секундах. Например, держать последние 5 файлов по 100 МБ:

Код: Выделить всё

sudo tcpdump -n -i eth0 -w cap.pcap -C 100 -W 5 'host 10.0.0.5'
А дальше открываешь cap.pcap в Wireshark - там графика, цвета, реконструкция TCP-потоков (правый клик, Follow TCP Stream), графики ввода-вывода и Expert Information, где Wireshark сам подсветит ретрансмиты, дубликаты ACK и нули окна. Идеальная схема для сервера без графики: ловишь консольным tcpdump в файл, забираешь файл к себе, копаешься в Wireshark в комфорте. К фильтру при записи всегда добавляй ограничения host/port, чтобы файл не разнесло.

Грабли, заблуждения и нагрузка
  • Забыл -n. Самая частая ошибка новичка: тормоза, лишний DNS-трафик в собственном дампе, а на сломанном резолвере - подвисание.
  • Слушаешь не тот интерфейс. Трафик идет через docker0/veth или eth1, а ты сидишь на eth0 и видишь пустоту. В сомнениях бери -i any и фильтр по хосту.
  • Фильтр без кавычек. Выражение со скобками, амперсандом и | shell разберет по-своему. Бери в одинарные кавычки.
  • Сам себя видишь. Твоя SSH-сессия - тоже трафик. Исключай ее: and not port 22, иначе утонешь в собственном эхе и можешь устроить петлю обратной связи (вывод порождает трафик, который ты же ловишь).
  • Путаешь BPF-фильтр и фильтр Wireshark. У tcpdump синтаксис захвата (capture filter, BPF): host, port, and. У Wireshark в строке поиска - другой, display-фильтр: ip.addr ==, tcp.port ==. Не мешай их.
  • Нагрузка и dropped by kernel. На гигабитном линке без фильтра tcpdump способен прилично нагрузить CPU и забить диск при записи, а ядро начнет дропать пакеты (та самая статистика на выходе). Всегда сужай фильтром, ставь -c или ротацию, при записи в файл предпочитай -w (это дешевле, чем форматировать вывод на экран).
  • Утечка секретов. Дамп с -A или полный pcap может содержать пароли, токены и куки из plaintext-трафика. Храни pcap-файлы как секреты, не клади в общий /tmp и удаляй после разбора.
Где tcpdump на 2026 уступает место. Для классической диагностики "доходит ли пакет и какие флаги" tcpdump по-прежнему инструмент номер один. Но если вопрос "почему пакет дропнулся ВНУТРИ ядра, на каком хуке, в каком namespace, каким процессом отправлен" - тут уже зрелые eBPF-инструменты: pwru (трассировка пути пакета по ядру), ptcpdump (process-aware tcpdump, показывает, какой процесс и контейнер породил пакет), а также штатный ss -tip для состояния сокетов и счетчиков ретрансмитов. tcpdump видит провод; eBPF видит, что с пакетом происходит внутри стека.

Мини-лаба: повтори руками прямо сейчас
  • Запусти sudo tcpdump -n -i any -c 20 и посмотри живой трафик. Найди в нем хотя бы одну тройку [S], [S.], [.]. На выходе глянь строку статистики - есть ли dropped by kernel.
  • В одном терминале запусти sudo tcpdump -nn -i any 'tcp port 80', в другом дай curl http://example.com. Поймай рукопожатие и добавь -A, чтобы увидеть GET-запрос и заголовки.
  • Постучись на заведомо закрытый порт: curl http://127.0.0.1:9999, параллельно слушая sudo tcpdump -n -i lo 'tcp[tcpflags] & tcp-rst != 0'. Найди RST в ответе.
  • Запиши минутный дамп в файл с -w 'host 8.8.8.8', параллельно сделав ping 8.8.8.8, открой файл через -r, а если есть Wireshark - загляни в Statistics и Follow Stream.
Контрольные вопросы
  • Зачем почти всегда нужен флаг -n (и -nn) и что он отключает?
  • Чем отличаются фильтры host, src host и dst host?
  • Какие три пакета составляют здоровое TCP-рукопожатие и как они выглядят в выводе по флагам?
  • О чем говорит RST ([R.]) сразу в ответ на SYN, и чем диагностически отличается случай, когда на SYN вообще нет ответа?
Что запомнить

tcpdump показывает реальный трафик и снимает гадание в сетевой диагностике. Рефлекс запуска: sudo tcpdump -nn -i <интерфейс> и обязательно фильтр (host, port, src/dst, tcp/udp), соединенный через and/not, в одинарных кавычках. Читай флаги: [S] и [S.] - соединение устанавливается, [R.] на SYN - порт закрыт или reject, повторяющиеся [S] без ответа - тихий drop где-то по пути. Для глубокого разбора пиши в файл через -w (с ротацией -C/-W на долгих захватах) и открывай pcap в Wireshark. Следи за dropped by kernel, фильтруй узко, убирай дампы за собой - в них бывают секреты. А когда tcpdump уперся в "что творится внутри ядра", бери eBPF-инструменты pwru и ptcpdump - это правильное продолжение на 2026.
👍4 ❤️3 🔥1 😄 🤔3
✔ Лучший ответ сформирован автоматически — cudasmith
Отдельный респект за строку статистики на выходе - у меня там всегда висели dropped by kernel, думал это норма. Сузил фильтр по host и порту, дропы ушли. Про ptcpdump и pwru вообще не знал, пойду щупать.
Перейти к ответу →
Аватара пользователя
tcplover
Сообщения: 1
Зарегистрирован: 26 май 2026, 21:51

Re: Захват трафика: tcpdump для диагностики сети

Сообщение tcplover »

Спасибо, наконец-то дошло про флаги в квадратных скобках. Всю жизнь видел эти [S.] и не понимал, а это просто SYN+ACK. Поймал свой RST на закрытом порту за минуту через tcp-rst фильтр.
👍 ❤️ 🔥 😄 🤔3
Аватара пользователя
cudasmith
Сообщения: 1
Зарегистрирован: 01 июн 2026, 03:24
Репутация: 318

Re: Захват трафика: tcpdump для диагностики сети

Сообщение cudasmith »

✔ Лучший ответ — сформирован автоматически
Отдельный респект за строку статистики на выходе - у меня там всегда висели dropped by kernel, думал это норма. Сузил фильтр по host и порту, дропы ушли. Про ptcpdump и pwru вообще не знал, пойду щупать.
👍3 ❤️1 🔥 😄 🤔
Локалхост — лучший хост.
Ответить
← Предыдущая глава
Сокеты и соединения: ss и netstat
Следующая глава →
Задержки и потери в сети: ping, mtr, диагностика латентности

Все главы курса «Диагностика и производительность Linux: логи, strace, perf и eBPF»

Поделиться темой: ✈ Telegram VK
Похожие запросы: ss как посмотреть открытые сокеты и соединенияstrace почему программа висит и тормозитЛоги и диагностика macOSкак посмотреть процессы в linux и убить зависшийНастройка сети на Macчто такое load average в linux и какое значение нормальное

Вернуться в «Диагностика и производительность Linux: логи, strace, perf и eBPF»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость