Диагностика сети: traceroute, tcpdump, nc, mtr

Когда «сайт не открывается», важно не гадать, а измерять: на каком участке теряется связь, доходит ли пакет, открыт ли порт. Соберём набор диагноста: traceroute, mtr, tcpdump, nc.

Сетевая диагностика — методичное сужение проблемы: от «работает ли DNS» и «доходит ли пакет до хоста» до «открыт ли конкретный порт» и «что реально летит по проводу». Каждый инструмент отвечает на свой слой вопроса.

Зачем это на практике

Жалоба «у нас всё лежит» почти всегда расплывчата. Задача инженера — превратить её в точный диагноз: проблема в DNS, в маршруте до сервера, в закрытом порте файрвола или в самом приложении? Правильный инструмент даёт ответ за минуту вместо часа догадок. Эти команды — первая помощь при любом сетевом инциденте.

traceroute и mtr: где рвётся связь

traceroute показывает путь пакета до хоста по шагам (hop) — через какие маршрутизаторы он идёт и где задержка или обрыв:

traceroute example.com        # путь по UDP (по умолчанию)
traceroute -T -p 443 example.com   # TCP-трейс на порт 443 (проходит файрволы)
1  192.168.1.1   0.5 ms
2  10.0.0.1      8.2 ms
3  203.0.113.7   15.1 ms
4  * * *
5  93.184.216.34 41.0 ms

Строки * * * означают, что на этом шаге узел не ответил (или режет диагностические пакеты) — само по себе не всегда проблема, но если дальше идут только звёздочки, связь рвётся примерно тут. Резкий скачок задержки на каком-то hop показывает узкое место.

mtr (My TraceRoute) — гибрид traceroute и ping: непрерывно шлёт пакеты по всему маршруту и показывает живую статистику потерь и задержки на каждом hop.

mtr example.com         # интерактивный режим (обновляется в реальном времени)
mtr -rwc 50 example.com # отчёт: 50 пакетов, удобно скопировать в тикет

mtr лучше одиночного traceroute, потому что потери видны статистически: если на 7-м hop стабильно теряется 30% пакетов — вот вам виновник.

netcat (nc): открыт ли порт

Самый частый вопрос: «сервис на порту X доступен?». ping тут бесполезен — он проверяет хост, а не порт. Нужен nc:

nc -zv example.com 443    # проверить, открыт ли TCP-порт 443 (-z скан, -v вывод)
nc -zv example.com 22
nc -zvu 10.0.0.5 53       # проверить UDP-порт (-u)
Connection to example.com (93.184.216.34) 443 port [tcp/https] succeeded!

Ответ succeeded значит, что TCP-соединение установилось — порт открыт и кто-то его слушает. Connection refused — порт закрыт (сервис не запущен), а зависание без ответа обычно означает, что пакет режет файрвол. nc умеет и больше: вручную «поговорить» с сервисом, например отправить HTTP-запрос:

printf 'GET / HTTP/1.0\r\n\r\n' | nc example.com 80   # сырой HTTP-запрос

tcpdump: смотрим реальные пакеты

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

Захватить трафик с фильтром по хосту и порту (фильтр обязателен, иначе утонете в потоке):

sudo tcpdump -i eth0 host 93.184.216.34       # всё с/на этот IP
sudo tcpdump -i any port 443 -n               # порт 443, не резолвить имена
sudo tcpdump -i any 'tcp port 80 and host example.com' -A   # HTTP с текстом пакета
sudo tcpdump -i eth0 -w capture.pcap          # записать в файл для Wireshark

Флаги: -i интерфейс (any — все), -n не резолвить (быстрее и понятнее), -A печатать содержимое в ASCII, -w сохранить в .pcap для анализа в Wireshark. С помощью tcpdump видно, доходит ли SYN-пакет до сервера и приходит ли ответный SYN-ACK, — это разрешает спор «у меня всё работает» vs «у меня ничего не приходит».

Типичный разбор: «сайт не открывается»

Сводим инструменты в методичный чек-лист — сужаем проблему слой за слоем:

# 1) Резолвится ли имя? (слой DNS)
dig +short example.com
# 2) Доходит ли пакет до хоста? (слой маршрутизации)
ping -c 3 93.184.216.34
mtr -rwc 20 93.184.216.34
# 3) Открыт ли нужный порт? (слой файрвола/сервиса)
nc -zv 93.184.216.34 443
# 4) Что реально происходит на проводе? (слой пакетов)
sudo tcpdump -i any host 93.184.216.34 and port 443 -n

Логика: если шаг 1 пуст — проблема в DNS (см. предыдущий урок). Если 1 дал IP, но ping/mtr не доходят — маршрут или хост лежит. Если хост пингуется, а nc на порт даёт refused/таймаут — виноват сервис или файрвол. Если и порт открыт, а сайт всё равно не грузится — проблема уже в приложении (HTTP), и тут поможет tcpdump -A или curl -v. Такой проход не оставляет места для гаданий.

Как это работает под капотом

traceroute хитро эксплуатирует поле TTL (Time To Live) в IP-пакете: он шлёт пакеты с TTL=1, 2, 3… Каждый маршрутизатор уменьшает TTL на единицу, и когда тот доходит до нуля, узел отвечает сообщением ICMP Time Exceeded — так и выясняется адрес каждого hop. mtr делает то же самое, но в цикле, накапливая статистику. tcpdump переводит сетевую карту в режим перехвата и через механизм ядра BPF (Berkeley Packet Filter) фильтрует пакеты ещё в ядре, до передачи в userspace, — поэтому фильтры работают быстро. nc просто пытается выполнить TCP-рукопожатие (SYN → SYN-ACK → ACK): успех значит, что порт слушается и доступен сквозь все файрволы на пути.

Частые ошибки

  • Делать вывод по одному traceroute со звёздочками. Многие узлы намеренно не отвечают на диагностические пакеты — * * * в середине пути часто норма, важен лишь обрыв до конца.
  • Проверять доступность сервиса через ping. ping работает по ICMP и ничего не знает про порты: хост может пинговаться, а нужный порт быть закрыт. Для порта — nc.
  • Запускать tcpdump без фильтра на нагруженном сервере. Вы получите лавину пакетов и нагрузку; всегда сужайте по host/port.
  • Забыть, что многие сети режут ICMP и UDP. Тогда обычный traceroute «не доходит», хотя TCP работает; используйте traceroute -T -p 443, который идёт по TCP, как реальный трафик.

Итоги

  • traceroute/mtr показывают путь пакета и где растёт задержка или теряются пакеты; mtr даёт статистику потерь по каждому hop.
  • nc -zv host port проверяет именно порт (не хост): succeeded — открыт, refused — закрыт, таймаут — обычно файрвол.
  • tcpdump -i any host X port Y -n показывает реальные пакеты; всегда с фильтром, для глубокого анализа пишите в .pcap.
  • Разбор «не открывается» идёт по слоям: DNS (dig) → маршрут (ping/mtr) → порт (nc) → пакеты/приложение (tcpdump/curl -v).
Проверьте себя
1. Хост example.com успешно пингуется (ping отвечает), но веб-страница не открывается. Чем дальше всего проверить, доступен ли именно порт 443?
AЕщё раз ping — он покажет порт
Bnc -zv example.com 443 — установит TCP-соединение к порту и покажет, открыт ли он
Ctraceroute — он проверяет порты
Ddig example.com — он откроет страницу
2. Что обычно означают строки '* * *' посередине вывода traceroute?
AСвязь полностью оборвана и хост недостижим
BУзел на этом шаге не ответил на диагностический пакет (часто он намеренно их режет) — само по себе это не всегда проблема
CНа этом узле потеряны все данные
DМаршрут зациклился