MAATRIX / Блог / Разбор VPN-трафика через tcpdump

Разбор VPN-трафика через tcpdump

MAATRIX

wg show говорит, что handshake свежий, systemctl status openvpn — что сервис активен, а трафик всё равно ведёт себя странно: то ли идёт через туннель, то ли в обход, то ли не идёт вообще. Демоны врут редко, но показывают только своё состояние, а не то, что на самом деле происходит с пакетами. tcpdump смотрит глубже — прямо на интерфейс, — и превращает гадание в чтение фактов: вот пакет пришёл, вот ушёл, вот здесь он расшифрован, а здесь потерян.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Зачем tcpdump, если есть wg show и systemctl status

Утилиты состояния VPN отвечают на вопрос «жив ли туннель», но не на вопрос «идёт ли через него мой трафик». Между этими вопросами — пропасть, в которой живёт добрая половина VPN-проблем: split tunneling настроен не так, приложение ходит напрямую в обход туннеля, DNS резолвится не через тот интерфейс, или пакеты доходят до сервера, но не возвращаются обратно.

tcpdump — стандартная утилита захвата пакетов, есть почти в любом Linux-дистрибутиве (sudo apt install tcpdump на Debian/Ubuntu, sudo dnf install tcpdump на RHEL-семействе). Она не интерпретирует состояние протокола, а просто показывает, что реально проходит через сетевой интерфейс, байт за байтом. Для диагностики VPN это ключевое отличие: wg show может сообщать «handshake 5 секунд назад», пока внутри туннеля не проходит ни одного пакета с данными — а tcpdump -i wg0 покажет это сразу, потому что там просто ничего не появится.

Работать с tcpdump нужно от root или через sudo:

sudo tcpdump -i wg0 -nn

Флаг -nn отключает резолвинг имён хостов и портов (без него tcpdump делает обратный DNS-запрос на каждый IP и подставляет имена сервисов вместо номеров портов) — для диагностики это лишний шум и задержка, лучше видеть голые цифры.

Ловим трафик на wg0 и tun0: базовые команды

WireGuard создаёт интерфейс wg0 (имя настраивается, но по умолчанию именно такое), OpenVPN — tun0 для routed-режима или tap0 для мостового. Список всех интерфейсов на сервере:

ip -brief link show

Базовый захват на интерфейсе туннеля:

sudo tcpdump -i wg0 -nn
# или
sudo tcpdump -i tun0 -nn

Запустите эту команду и с другого терминала пропингуйте что-нибудь через туннель (ping -c 3 8.8.8.8 с клиента) — в выводе появятся строки вида:

14:22:01.104532 IP 10.0.0.2 > 8.8.8.8: ICMP echo request, id 5123, seq 1, length 64
14:22:01.128991 IP 8.8.8.8 > 10.0.0.2: ICMP echo reply, id 5123, seq 1, length 64

Это уже расшифрованный пакет — на интерфейсе wg0/tun0 ядро отдаёт tcpdump данные после снятия шифрования (на выходе) или до его наложения (на входе). Полезные флаги для точечной диагностики:

sudo tcpdump -i wg0 -nn -c 20              # остановиться после 20 пакетов
sudo tcpdump -i wg0 -nn icmp               # только ICMP (пинги)
sudo tcpdump -i wg0 -nn host 8.8.8.8       # только трафик к/от конкретного адреса
sudo tcpdump -i wg0 -nn -v                 # подробнее: TTL, флаги, длина
sudo tcpdump -i wg0 -nn -w /tmp/wg0.pcap   # сохранить дамп в файл для Wireshark

Если на wg0 или tun0 вообще ничего не появляется, пока вы генерируете трафик на клиенте — это уже диагноз: проблема раньше интерфейса туннеля — в маршрутизации на клиенте, в firewall, который режет трафик молча, или сам туннель не поднят.

Арендуйте сервер под свои задачи!

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Как отличить туннелированный трафик от обычного в дампе

Главный трюк разбора VPN-трафика — смотреть на двух интерфейсах одновременно: на интерфейсе туннеля (wg0/tun0) и на внешнем интерфейсе, через который туннель выходит наружу (обычно eth0, ens3 или похожее имя). Откройте два терминала (или два окна tmux/screen) и запустите в них разные захваты:

# терминал 1 — что видно "снаружи", на внешнем интерфейсе
sudo tcpdump -i eth0 -nn udp port 51820

# терминал 2 — что видно "внутри" туннеля
sudo tcpdump -i wg0 -nn

На eth0 вы увидите только зашифрованные UDP-пакеты между внешними IP клиента и сервера, без опознаваемой структуры внутри (для WireGuard это сделано специально, чтобы дамп выглядел как случайный шум и не давал DPI зацепок). На wg0 в этот же момент появятся уже расшифрованные IP-пакеты с внутренними адресами туннеля и реальным содержимым — ICMP, TCP SYN, DNS-запросы. Разница между этими двумя дампами и есть визуальное доказательство того, что шифрование и расшифровка реально происходят.

Быстро понять, какой интерфейс операционная система выберет для конкретного адреса, можно ещё до захвата пакетов:

ip route get 8.8.8.8

Если в выводе wg0 или tun0 — трафик к этому адресу пойдёт через туннель; если eth0/wlan0 — в обход. Это самый быстрый способ поймать сломанный split tunneling: приложение «должно» ходить через VPN, а ip route get честно показывает, что маршрут ведёт мимо.

Для WireGuard есть ещё один диагностический приём: посмотреть на первый байт полезной нагрузки UDP-пакета на внешнем интерфейсе через -X (вывод в hex и ASCII):

sudo tcpdump -i eth0 -nn -X udp port 51820 -c 5

Протокол WireGuard кодирует тип сообщения первым байтом полезной нагрузки: 01 — инициация handshake, 02 — ответ на handshake, 03 — cookie reply, 04 — пакет с данными. Если в первые секунды видны 01 и 02, а дальше идут пакеты с 04 — handshake состоялся, туннель в рабочем режиме. Если после 01 ответ 02 не появляется — сервер не смог ответить на инициацию: неверный публичный ключ, недоступен endpoint или блокирует firewall.

Пакеты уходят в туннель, но ответа нет — типичный сценарий

Самая частая жалоба звучит так: «клиент подключён, но интернета нет» или «пингую внутренний сервер — тишина». tcpdump разбирает это по шагам, если запускать захват сразу с двух сторон туннеля.

На клиенте запустите ping и захват на интерфейсе туннеля одновременно:

sudo tcpdump -i wg0 -nn icmp &
ping -c 5 10.0.0.1

Если ICMP echo request виден в дампе клиента — пакет ушёл в туннель штатно. Дальше переходите на сервер и смотрите тот же интерфейс:

sudo tcpdump -i wg0 -nn icmp

Возможны три картины:

  • Пакет виден на сервере, ответа нет. Проблема после расшифровки — не включён net.ipv4.ip_forward, нет правила NAT/MASQUERADE, либо firewall режет исходящий трафик на внешнем интерфейсе. Проверьте счётчики: sudo iptables -t nat -L POSTROUTING -n -v или sudo nft list ruleset | grep masquerade — растут ли они при повторном пинге.
  • Пакет не дошёл до wg0/tun0, хотя на eth0 сервера виден зашифрованный UDP от клиента. Расшифровка не удалась или пакет отброшен на уровне туннеля — неверный AllowedIPs (у WireGuard пакет с несовпадающим внутренним IP отбрасывается молча, без записи в лог), рассинхронизация ключей, либо у OpenVPN не прошла аутентификация сертификата.
  • Пакет не появился даже на eth0 сервера. Проблема раньше уровня VPN — не доходит физически: неверный маршрут у клиента, firewall провайдера, NAT перед сервером блокирует нужный порт.

Отдельно проверьте фрагментацию — частая причина «туннель работает, но сайты грузятся через раз». Признак в дампе — повторные пересылки одного TCP-сегмента или ICMP-пакеты типа 3 code 4 (fragmentation needed but DF set):

sudo tcpdump -i wg0 -nn -v icmp

Если такие сообщения регулярно появляются — снаружи туннеля MTU меньше, чем ожидает внутренний трафик (типично при вложенных туннелях, PPPoE у провайдера или мобильных сетях). Стоит проверить MTU интерфейса и при необходимости снизить его в конфиге (например, MTU = 1420 вместо стандартных 1500) — точное значение зависит от конкретной сети, универсального числа нет.

WireGuard и OpenVPN в дампах: на что смотреть в каждом

Оба протокола инкапсулируют трафик, но выглядят в tcpdump по-разному — и это стоит знать заранее, чтобы не искать несуществующие признаки.

WireGuard (wg0)OpenVPN (tun0/tap0)
Транспорт по умолчаниюUDP, порт 51820UDP 1194 или TCP (часто маскируют под 443)
Структура на внешнем интерфейсеФиксированный формат, тип сообщения в первом байте (0104)Опкод и session ID в заголовке пакета; в TCP-режиме поверх видна структура TCP-потока
Видимость handshake в дампеДва коротких UDP-пакета (инициация/ответ) перед потоком данныхTLS-подобный обмен при первом подключении, если не включён tls-crypt
Похож на что «снаружи»Случайный шум, специально без сигнатурВ UDP-режиме тоже маскируется под шум; в TCP-режиме на порт 443 похож на HTTPS-сессию
Интерфейс для захватаwg0 (имя можно менять в конфиге)tun0 (routed) или tap0 (bridged)

Если вы не знаете заранее, каким протоколом и портом пользуется OpenVPN-сервер, быстрее всего выяснить это через tcpdump на этапе подключения клиента:

sudo tcpdump -i eth0 -nn udp port 1194 or tcp port 443

Пакет сработает по одному из этих правил в момент, когда клиент инициирует соединение — так вы сразу увидите, какой транспорт реально используется, не заглядывая в конфиг.

Важный нюанс: если на сервере включён tls-crypt (в современных конфигах OpenVPN это дефолт для безопасности), даже начальный handshake уже зашифрован дополнительным статическим ключом — в дампе не будет узнаваемого TLS ClientHello, только непрозрачные блоки данных, как и у WireGuard. Это защита от DPI, а не повод для тревоги.

Захват на обеих сторонах туннеля синхронно

Разбор проблем «на стыке» — трафик доходит до одной стороны, но не появляется на другой — требует параллельного захвата на клиенте и сервере с сопоставлением. Порядок действий:

  1. Убедитесь, что время на обеих машинах синхронизировано через NTP (chronyc tracking или timedatectl) — без этого сопоставлять пакеты по времени будет неудобно.
  2. На клиенте и на сервере одновременно запустите захват с сохранением в файл:
# на клиенте
sudo tcpdump -i wg0 -nn -w /tmp/client-wg0.pcap &
sudo tcpdump -i eth0 -nn udp port 51820 -w /tmp/client-eth0.pcap &

# на сервере
sudo tcpdump -i wg0 -nn -w /tmp/server-wg0.pcap &
sudo tcpdump -i eth0 -nn udp port 51820 -w /tmp/server-eth0.pcap &
  1. Воспроизведите проблему (пинг, запрос к сервису) и остановите захваты (sudo kill %1 %2 или Ctrl+C в каждом терминале).
  2. Скопируйте файлы на рабочую машину (scp user@server:/tmp/server-*.pcap .) и откройте в Wireshark — там удобно сравнивать временные метки, фильтровать по ip.addr или udp.port, и визуально видеть, на каком именно этапе пакет пропадает.

Такой параллельный захват — надёжный способ доказать (себе, коллеге или в тикете провайдеру), на чьей стороне обрывается цепочка: если пакет виден в client-wg0.pcap, но его нет ни в server-eth0.pcap, ни тем более в server-wg0.pcap — проблема на пути между машинами, а не в конфигурации VPN. Для таких экспериментов удобно держать тестовый стенд на отдельном VPS — так вы не рискуете рабочим сервером, перезапуская сетевые правила во время диагностики.

Арендуйте сервер под свои задачи!

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

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

Можно ли увидеть расшифрованный трафик на внешнем интерфейсе (eth0)?

Нет, и не должно быть — если на eth0 виден расшифрованный трафик, значит шифрование не работает вообще, это критическая проблема безопасности, а не диагностический успех. Расшифрованные пакеты видны только на интерфейсе туннеля (wg0/tun0), куда их отдаёт ядро уже после снятия шифрования.

Нужны ли root-права для tcpdump?

Да, захват сырых пакетов требует прав уровня ядра — запускайте через sudo или добавьте себе capability cap_net_raw (sudo setcap cap_net_raw,cap_net_admin=eip $(which tcpdump)), если не хотите каждый раз использовать sudo.

Как понять, что трафик вообще не заходит в туннель, даже не запуская tcpdump?

Команда ip route get <адрес> покажет, какой интерфейс операционная система выберет для этого адреса — если это не wg0/tun0, трафик пойдёт мимо туннеля независимо от того, что показывает wg show.

Захват пакетов замедляет VPN или роняет соединения?

На типичных нагрузках VPS — нет, tcpdump сам по себе даёт минимальный оверхед. Заметное замедление возможно только при очень высокой интенсивности трафика и записи полного дампа без фильтров на диск с низкой скоростью записи.

Чем отличается захват на wg0 от захвата на tun0 по сути данных?

Ничем принципиальным — оба интерфейса отдают tcpdump уже декапсулированные IP-пакеты. Разница только в деталях протокола на внешнем интерфейсе: формат UDP-сообщений WireGuard и опкоды/session ID у OpenVPN.

Как оплатить VPS для тестового стенда из России?

В MAATRIX — картой российского банка, через СБП или криптовалютой, без иностранной карты и посредников.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →