Бывает, что приложение не может связаться с базой данных, письма не уходят, а клиент утверждает, что запросы до сервера не доходят. Логи в такой ситуации молчат, потому что программа даже не видит соединения. Тогда помогает 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 по умолчанию нет.
apt install -y tcpdumpЗатем узнайте имя сетевого интерфейса. Это имя понадобится в каждой команде.
ip -br linkНа наших серверах основной интерфейс называется ens3. Интерфейсы lo, docker0 и br-… относятся к самому серверу и Docker. Если не уверены, какой интерфейс нужен, используйте -i any, тогда tcpdump будет слушать все сразу.
2. Посмотрите пакеты по порту
Начнём с DNS. Запустите tcpdump с фильтром по порту 53 и параметром -c, который завершит перехват после нужного числа пакетов. В соседнем окне или сразу после этого выполните dig example.com.
tcpdump -n -i ens3 port 53 -c 2
Запрос к DNS-серверу и ответ с двумя IP-адресами
Каждая строка это один пакет.
- Время с точностью до микросекунд.
- Отправитель и получатель в виде
адрес.порт > адрес.порт. - Содержимое в кратком виде. Для DNS это сам вопрос
A? example.com.и ответ с адресами.
Параметр -n запрещает tcpdump превращать адреса в имена. Без него он будет сам делать DNS-запросы и засорять вывод, а работать медленнее.
3. Составьте фильтр
Фильтры комбинируются словами and, or и not. Если в фильтре есть скобки или квадратные скобки, возьмите его в кавычки.
# Весь трафик с конкретным адресом
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 от сканеров, которые перебирают пароли.

Пакеты с флагом [S] это начало нового соединения, адреса скрыты
Не смотрите собственный SSH
Если вы подключены к серверу по SSH и запускаете tcpdump без фильтра, он будет показывать в том числе пакеты вашего же соединения, а каждая выведенная строка породит новые пакеты. Добавляйте к фильтру and not port 22.
4. Посмотрите содержимое пакетов
Параметр -A выводит содержимое пакетов как текст. Это удобно для открытых протоколов. Например, так видно HTTP-запросы к сайтам.
# Все исходящие пакеты на порт 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
По HTTP запрос и заголовки видны целиком
Для зашифрованных протоколов -A покажет бессмысленный набор символов, и это нормально. Для двоичных протоколов вместо -A удобнее -X, он показывает содержимое в шестнадцатеричном виде рядом с текстовым.
5. Сохраните перехват в файл
Длинный перехват удобнее записать в файл и разобрать потом, например в программе Wireshark на своём компьютере.
# Записываем в файл, остановка по Ctrl+C
tcpdump -n -i ens3 port 53 -w /tmp/dns.pcap
# Читаем файл на сервере
tcpdump -n -r /tmp/dns.pcapФайл .pcap можно скачать с сервера через SFTP или командой scp и открыть в Wireshark двойным щелчком. Не забудьте удалить его с сервера после разбора, ведь в перехвате может оказаться что-то конфиденциальное.
Частые вопросы
tcpdump: eth0: No such device exists
На сервере нет интерфейса с таким именем. Многие старые инструкции используют имя eth0, а на наших серверах основной интерфейс называется ens3. Посмотрите список интерфейсов командой ip -br link или запустите tcpdump с параметром -i any.
You don't have permission to perform this capture on that device
Перехватывать пакеты может только root. Запустите команду от имени root или через sudo.
tcpdump ничего не показывает
- Проверьте, что выбран правильный интерфейс. Трафик контейнеров Docker, например, идёт через интерфейсы
docker0иbr-…. - Ослабьте фильтр. Начните с одного условия, например
port 80, и добавляйте остальные по одному. - Если пакетов нет и с простым фильтром, значит, они не доходят до сервера. Проверьте маршрут, как описано в статье про трассировку, и правила брандмауэра на стороне отправителя.
Наши ресурсы
Telegram-канал: https://t.me/f3cloud_news
Официальный сайт: https://f3cloud.com