> Полный список статей есть в [llms.txt](https://docs.f3cloud.com/llms.txt). Markdown-версия есть у каждой страницы, достаточно добавить .md к её адресу. Эта страница в Markdown: [https://docs.f3cloud.com/ru/network/tcpdump-linux.md](https://docs.f3cloud.com/ru/network/tcpdump-linux.md).

# tcpdump в Linux – как посмотреть сетевой трафик на сервере

Как пользоваться tcpdump на Linux-сервере. Установка, выбор сетевого интерфейса, фильтры по порту, адресу и протоколу, просмотр содержимого пакетов, запись в файл для Wireshark и примеры диагностики DNS, HTTP и подключений к SSH. Проверено на Debian 12 и tcpdump 4.99.

Бывает, что приложение не может связаться с базой данных, письма не уходят, а клиент утверждает, что запросы до сервера не доходят. Логи в такой ситуации молчат, потому что программа даже не видит соединения. Тогда помогает **tcpdump**. Он показывает сетевые пакеты, которые на самом деле приходят на сервер и уходят с него, и позволяет точно ответить на вопрос, дошёл ли запрос и что на него ответили. В этой статье разберём, как tcpdump видит трафик, научимся составлять фильтры, смотреть содержимое пакетов и сохранять перехват в файл. Все примеры сняты на тестовом сервере с Debian 12.

***

## Как tcpdump видит трафик

Каждый пакет, который проходит через сетевой интерфейс сервера, ядро Linux обрабатывает само, и обычные программы получают уже готовые данные своих соединений. tcpdump работает иначе. Он просит ядро передавать ему копию каждого пакета, проходящего через выбранный интерфейс, вместе со всеми заголовками. Поэтому он видит и те пакеты, которые потом отбросит брандмауэр или которые адресованы порту, где никто не слушает. Именно это делает его незаменимым при диагностике. Если пакет есть в выводе tcpdump, значит, он дошёл до сервера, а если его там нет, проблему нужно искать раньше, в сети или у отправителя.

Копировать каждый пакет в программу накладно, а на загруженном сервере пакетов тысячи в секунду, поэтому tcpdump почти всегда запускают с **фильтром**. Фильтр записывается на специальном языке, например `port 53` или `host 1.1.1.1 and tcp`, и выполняется прямо в ядре. Ядро передаёт tcpdump только подходящие пакеты, а остальные даже не копирует. Благодаря этому tcpdump можно безопасно запускать и на рабочем сервере.

Важно понимать и ограничение. tcpdump показывает пакеты так, как они идут по сети. Если соединение зашифровано, как HTTPS или SSH, вы увидите адреса, порты, размеры и время, но не содержимое. Открытым текстом видны только незашифрованные протоколы, например обычный HTTP или DNS. Мы проверили это на тестовом сервере. Запрос к сайту по HTTP в выводе tcpdump читался целиком, вместе с адресом страницы и заголовками.

***

## 1. Установите tcpdump

В нашем образе Debian 12 tcpdump по умолчанию нет.

```bash
apt install -y tcpdump
```

Затем узнайте имя сетевого интерфейса. Это имя понадобится в каждой команде.

```bash
ip -br link
```

На наших серверах основной интерфейс называется `ens3`. Интерфейсы `lo`, `docker0` и `br-…` относятся к самому серверу и Docker. Если не уверены, какой интерфейс нужен, используйте `-i any`, тогда tcpdump будет слушать все сразу.

***

## 2. Посмотрите пакеты по порту

Начнём с DNS. Запустите tcpdump с фильтром по порту 53 и параметром `-c`, который завершит перехват после нужного числа пакетов. В соседнем окне или сразу после этого выполните `dig example.com`.

```bash
tcpdump -n -i ens3 port 53 -c 2
```

<figure><img src="https://docs.f3cloud.com/img/tcpdump-dns.png" alt="Вывод tcpdump с DNS-запросом A example.com к 1.1.1.1 и ответом с двумя адресами"><figcaption><p>Запрос к DNS-серверу и ответ с двумя IP-адресами</p></figcaption></figure>

Каждая строка это один пакет.

* **Время** с точностью до микросекунд.
* **Отправитель и получатель** в виде `адрес.порт > адрес.порт`.
* **Содержимое** в кратком виде. Для DNS это сам вопрос `A? example.com.` и ответ с адресами.

Параметр `-n` запрещает tcpdump превращать адреса в имена. Без него он будет сам делать DNS-запросы и засорять вывод, а работать медленнее.

***

## 3. Составьте фильтр

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

```bash
# Весь трафик с конкретным адресом
tcpdump -n -i ens3 host 203.0.113.10

# Только входящие соединения на порт 443
tcpdump -n -i ens3 dst port 443

# Трафик к базе данных, кроме своего SSH
tcpdump -n -i ens3 port 3306 and not port 22

# Только UDP или только ICMP, например ping
tcpdump -n -i ens3 udp
tcpdump -n -i ens3 icmp

# Новые попытки подключения к SSH, то есть пакеты SYN
tcpdump -n -i ens3 "tcp[tcpflags] == tcp-syn and dst port 22"
```

Последний фильтр полезен, чтобы увидеть, кто стучится на сервер. На тестовом сервере за четыре минуты он поймал две попытки подключения к SSH от сканеров, которые перебирают пароли.

<figure><img src="https://docs.f3cloud.com/img/tcpdump-ssh-syn.png" alt="tcpdump поймал пакеты SYN от сканеров на порт 22, адреса скрыты"><figcaption><p>Пакеты с флагом [S] это начало нового соединения, адреса скрыты</p></figcaption></figure>

> **Не смотрите собственный SSH.**
>
> Если вы подключены к серверу по SSH и запускаете tcpdump без фильтра, он будет показывать в том числе пакеты вашего же соединения, а каждая выведенная строка породит новые пакеты. Добавляйте к фильтру `and not port 22`.

***

## 4. Посмотрите содержимое пакетов

Параметр `-A` выводит содержимое пакетов как текст. Это удобно для открытых протоколов. Например, так видно HTTP-запросы к сайтам.

```bash
# Все исходящие пакеты на порт 80 с содержимым
tcpdump -n -A -i ens3 "tcp dst port 80" -c 5

# Только пакеты с запросом GET, как на скриншоте ниже
tcpdump -n -A -i ens3 'tcp dst port 80 and tcp[((tcp[12]&0xf0)>>2):4] = 0x47455420' -c 1
```

<figure><img src="https://docs.f3cloud.com/img/tcpdump-http.png" alt="tcpdump -A показывает HTTP-запрос GET с заголовками Host и User-Agent открытым текстом"><figcaption><p>По HTTP запрос и заголовки видны целиком</p></figcaption></figure>

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

***

## 5. Сохраните перехват в файл

Длинный перехват удобнее записать в файл и разобрать потом, например в программе **Wireshark** на своём компьютере.

```bash
# Записываем в файл, остановка по Ctrl+C
tcpdump -n -i ens3 port 53 -w /tmp/dns.pcap

# Читаем файл на сервере
tcpdump -n -r /tmp/dns.pcap
```

Файл `.pcap` можно скачать с сервера через SFTP или командой `scp` и открыть в Wireshark двойным щелчком. Не забудьте удалить его с сервера после разбора, ведь в перехвате может оказаться что-то конфиденциальное.

***

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

<details>

<summary>tcpdump: eth0: No such device exists</summary>

На сервере нет интерфейса с таким именем. Многие старые инструкции используют имя `eth0`, а на наших серверах основной интерфейс называется `ens3`. Посмотрите список интерфейсов командой `ip -br link` или запустите tcpdump с параметром `-i any`.

</details>

<details>

<summary>You don't have permission to perform this capture on that device</summary>

Перехватывать пакеты может только root. Запустите команду от имени `root` или через `sudo`.

</details>

<details>

<summary>tcpdump ничего не показывает</summary>

1. Проверьте, что выбран правильный интерфейс. Трафик контейнеров Docker, например, идёт через интерфейсы `docker0` и `br-…`.
2. Ослабьте фильтр. Начните с одного условия, например `port 80`, и добавляйте остальные по одному.
3. Если пакетов нет и с простым фильтром, значит, они не доходят до сервера. Проверьте маршрут, как описано в статье про [трассировку](https://docs.f3cloud.com/ru/vps/network-troubleshooting-traceroute.md), и правила брандмауэра на стороне отправителя.

</details>

***

## Наши ресурсы

**Telegram-канал:** [https://t.me/f3cloud_news](https://t.me/f3cloud_news)\
**Официальный сайт:** [https://f3cloud.com](https://f3cloud.com/ru)
