Перейти к содержимому

tcpdump и tshark: захват и анализ пакетов в CLI

При отладке сетевых проблем в Linux-инфраструктуре недостаточно ping и curl. Иногда нужно посмотреть, что реально ходит по проводу. tcpdump — стандартный инструмент для захвата пакетов из CLI. tshark — его побратим из набора Wireshark, удобный для скриптов.

Быстрый старт с tcpdump

Проверим, что пакеты идут до хоста:

tcpdump -i eth0 host 10.0.0.5

Утилита поднимает интерфейс в promiscuous mode и печатает каждую строку при прохождении пакета. По умолчанию работает с первым интерфейсом, который найдёт, но лучше указывать явно.

Для быстрого теста без DNS-резолва (чтобы не ждать timeout при отсутствии сети):

tcpdump -i eth0 -nn host 10.0.0.5

-nn запрещает резолвить и хостнеймы, и порты.

Ключевые флаги

ФлагНазначение
-i ifaceИнтерфейс
-c NЗахватить N пакетов и выйти
-nНе резолвить хостнеймы
-nnНе резолвить хостнеймы и порты
-v, -vv, -vvvУвеличивать детализацию вывода
-w fileЗаписать сырой дамп в файл (pcap)
-r fileПрочитать дамп из файла
-XПоказать hex + ASCII тело пакета
-s NСрезать каждый пакет до N байт (0 = полный)
-CРотировать выходной файл при достижении N MB

Флаги -v полезны для отладки: первый уровень показывает TTL и ID, второй — флаги и window size, третий добавляет ACK и отображает полный IP-header.

# Захватить 100 пакетов на порту 443, детализация -vv
tcpdump -i eth0 -nn -c 100 -vv port 443

BPF-фильтры

tcpdump использует Berkeley Packet Filter. Синтаксис читается слева направо.

# Только TCP на порт 80 или 443
tcpdump -i eth0 -nn tcp port 80 or port 443

# Хост как источник ИЛИ назначение
tcpdump -i eth0 -nn host 192.168.1.10

# Не показывать SSH (отсекаем шум)
tcpdump -i eth0 -nn not port 22

# TCP-пакеты с флагом SYN (начало соединения)
tcpdump -i eth0 -nn 'tcp[tcpflags] == tcp-syn'

# Пакеты больше 1000 байт
tcpdump -i eth0 -nn 'ip[2:2] > 1000'

# ICMP ping (type 8 code 0)
tcpdump -i eth0 -nn 'icmp[icmptype] == 8'

Фильтры комбинируются через and, or, not. Кавычки нужны, когда в выражении есть пробелы или спецсимволы.

Предупреждение

Не пишите в проде tcpdump -i any без ограничения по хосту или порту. Получите лавину трафика и потратите диск на ровном месте.

Запись в файл и чтение

Захват в файл — обязательная практика. Сниффер наживо выдаёт данные десятками строк в секунду; анализировать в терминале невозможно.

# Записать 10 000 пакетов в файл
tcpdump -i eth0 -nn -w /tmp/capture.pcap -c 10000

# Прочитать из файла (интерактивно)
tcpdump -r /tmp/capture.pcap

# Прочитать с фильтром при чтении
tcpdump -r /tmp/capture.pcap -nn 'tcp port 443'

Формат pcap — бинарный. Опция -C ограничивает размер файла:

tcpdump -i eth0 -nn -w /tmp/capture -C 10 -W 5

Создаст файлы /tmp/capture-0, /tmp/capture-1 … до 5 штук, каждый до 10 MB. -W — количество файлов.

tshark как tty-free альтернатива

tshark — консольная часть Wireshark. Выдаёт структурированный вывод, удобный для парсинга в скриптах:

# Установка
apt install tshark   # Debian/Ubuntu
yum install wireshark-cli   # RHEL/CentOS

# Захват с выводом в JSON (нужен Lua-плагин или python-парсер)
tshark -i eth0 -f 'host 10.0.0.5' -c 100 -T fields -e ip.src -e ip.dst -e tcp.port

-T fields -e позволяет вытащить конкретные поля из каждого пакета:

# HTTP-запросы: метод и host
tshark -i eth0 'tcp port 80' -Y http.request -T fields -e http.host -e http.request.method -e http.request.uri

Для чтения pcap-файла с tshark удобнее, чем с tcpdump:

# Показать топ-10 по размеру пакетов
tshark -r /tmp/capture.pcap -z io,phs -q

tshark не умеет в-C ротацию как tcpdump, но умеет в live-фильтры лучше (полноценный dissector Wireshark).

Чтение дампа в Wireshark

Созданный tcpdump pcap открывается в Wireshark без конвертации:

# Передать файл на локальную машину
scp user@server:/tmp/capture.pcap /tmp/

# Или поднять веб-сервер на удалённом хосте
python3 -m http.server 8080 --directory /tmp

В WiresharkApply as display filter вводите тот же BPF-синтаксис: tcp.port == 443 && ip.src == 10.0.0.1.

Подсказка

Если файл большой (>100 MB), не открывайте его целиком. Используйте tcpdump -r с предварительным фильтром, чтобы вытащить нужный срез: tcpdump -r big.pcap -nn 'host 10.0.0.5' -w small.pcap.

Типичные ошибки

  • Забыли -c — процесс висит, захватывая трафик бесконечно. Добавьте ограничение сразу.
  • Нет прав — нужен root или sudo tcpdump. В современных дистрибутивах можно выдать capabilities: setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump.
  • -w не работает с -l (line-buffering) одновременно. Если нужен прогресс — пишите в файл и читайте параллельно через tail -f.
  • Файл записался, а читается пустым — возможно, не было трафика, подходящего под фильтр. Проверьте tcpdump -i eth0 -nn без фильтра.