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

Индекс LLMS: [llms.txt](/llms.txt)

---

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

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

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

```bash
tcpdump -i eth0 host 10.0.0.5
```

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

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

```bash
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.

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

## BPF-фильтры

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

```bash
# Только 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`. Кавычки нужны, когда в выражении есть пробелы или спецсимволы.

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

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

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

```bash
# Записать 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` ограничивает размер файла:

```bash
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. Выдаёт структурированный вывод, удобный для парсинга в скриптах:

```bash
# Установка
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` позволяет вытащить конкретные поля из каждого пакета:

```bash
# 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:

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

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

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

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

```bash
# Передать файл на локальную машину
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`.

> [!TIP]
> Если файл большой (>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` без фильтра.
