Сетевая диагностика Linux: ss, tcpdump, mtr и поиск потерь пакетов
Классическая ситуация: пользователь пишет, что «всё тормозит», мониторинг показывает зелёное, а ping до шлюза идёт идеально. Вот тут и выясняется, умеешь ли ты диагностировать сеть руками. В этой статье разберём рабочий набор инструментов на Linux: ss для сокетов, tcpdump для захвата трафика и mtr для поиска потерь по маршруту. Все примеры привязаны к нашей лабораторной сети itpages.lab.local (192.168.10.0/24), диагностировать будем с хоста srv-linux01 в сторону srv-dns01, srv-dhcp01 и пограничного маршрутизатора rtr-edge01.
Главная идея проста: диагностика идёт снизу вверх. Сначала канал и интерфейс, потом IP и маршрутизация, потом транспорт (TCP/UDP), и только потом приложение. Если начинать с логов приложения, можно потратить час на поиск ошибки, которая живёт в кабеле или в MTU.
Шаг 1. Проверяем интерфейс и маршрут
Начни с самого низа. Команда ip заменила старые ifconfig и route, и привыкнуть к ней стоит раз и навсегда.
ip -br addr
ip -br link
ip route show
ip route get 8.8.8.8
ip -s link show dev eth0
Первые две команды дают компактную сводку: состояние интерфейсов и адреса. Третья показывает таблицу маршрутов, четвёртая отвечает на вопрос «каким путём пойдёт пакет к этому адресу», а это бесценно, когда в системе несколько интерфейсов. Последняя команда выводит счётчики интерфейса. Смотри на колонки errors, dropped и overrun: растущие ошибки на приёме почти всегда означают проблему физического уровня, то есть кабель, порт коммутатора или несогласованный дуплекс.
Дуплекс и скорость проверяются так:
ethtool eth0 | egrep 'Speed|Duplex|Link detected'
ethtool -S eth0 | egrep -i 'err|drop|crc'
Если видишь Half duplex или 100Mb/s вместо гигабита, дальше можно не копать: причина найдена. Растущий rx_crc_errors говорит о плохом кабеле или разъёме.
Шаг 2. Быстрая проверка связности
Теперь убедимся, что хосты вообще видят друг друга. Идём от ближнего к дальнему: шлюз, затем сервисные хосты, затем внешний мир.
ping -c 4 192.168.10.1
ping -c 4 srv-dns01.itpages.lab.local
ping -c 4 -M do -s 1472 192.168.10.1
ping -c 4 8.8.8.8
Третья команда особенная: флаг -M do запрещает фрагментацию, а размер 1472 плюс 28 байт заголовков даёт ровно 1500. Если такой пакет не проходит, а маленькие проходят, у тебя проблема с MTU. Это классика для туннелей и VPN: веб-страницы наполовину грузятся, SSH подключается, но зависает при выводе большого количества текста.
Отдельно проверь разрешение имён. Если ping по IP работает, а по имени нет, проблема не в сети, а в DNS:
getent hosts srv-dns01.itpages.lab.local
resolvectl status
dig +short srv-dhcp01.itpages.lab.local @192.168.10.2
Обрати внимание на getent: он идёт тем же путём, что и приложения (через nsswitch), а dig обращается напрямую к DNS-серверу. Разница в результатах сама по себе диагностика.
Шаг 3. ss: кто слушает и кто подключён
Утилита ss пришла на смену netstat и работает заметно быстрее. Базовый набор флагов стоит запомнить: -t TCP, -u UDP, -l слушающие, -n без разрешения имён, -p процессы, -a все.
ss -tulpn
ss -tn state established
ss -tn state established '( dport = :443 or sport = :443 )'
ss -s
ss -ti dst 192.168.10.2
Первая команда отвечает на вопрос «что вообще слушает на этом хосте и от какого процесса». Если сервис запущен, а подключиться к нему нельзя, сначала смотри сюда: он может слушать только 127.0.0.1, а не 0.0.0.0. Вторая и третья показывают установленные соединения с фильтром по состоянию и порту. Команда ss -s выдаёт сводку, по которой видно, не копятся ли тысячи соединений в состоянии TIME-WAIT или SYN-RECV.
Последняя команда с ключом -i особенно ценна: для каждого соединения она показывает внутреннюю информацию TCP, включая RTT, окно перегрузки (cwnd) и счётчик ретрансмитов (retrans). Растущие ретрансмиты на конкретном соединении означают потери на пути, и это уже веский повод идти дальше с tcpdump и mtr.
Ещё один полезный приём: поиск соединений в очереди. Колонки Recv-Q и Send-Q для слушающих сокетов показывают состояние очереди ожидающих подключений. Если Recv-Q у слушающего сокета упирается в Send-Q, приложение не успевает принимать соединения, и проблема в нём, а не в сети.
Шаг 4. tcpdump: смотрим, что реально летит по проводу
Когда логи и метрики противоречат друг другу, правду скажет только захват трафика. tcpdump стоит запускать с чётким фильтром, иначе утонешь в шуме.
sudo tcpdump -i eth0 -nn host 192.168.10.2
sudo tcpdump -i eth0 -nn port 53
sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-syn|tcp-rst) != 0'
sudo tcpdump -i eth0 -nn icmp
sudo tcpdump -i any -nn -c 200 -w /tmp/case01.pcap host 192.168.10.3 and port 443
Ключ -nn отключает разрешение имён и портов, без него tcpdump сам будет ходить в DNS и тормозить. Третий пример выводит только пакеты SYN и RST: быстрый способ увидеть, кто отказывает в соединении. Если клиент шлёт SYN, а ответа нет, пакеты теряются по дороге или фильтруются файрволом. Если в ответ приходит RST, порт доступен, но на нём никто не слушает.
Последняя команда сохраняет до 200 пакетов в файл. Его потом можно открыть в Wireshark на рабочей станции и спокойно разобрать. Для долгих захватов используй ротацию, чтобы не забить диск:
sudo tcpdump -i eth0 -nn -w /var/tmp/cap-%H%M.pcap -G 300 -W 12 host 192.168.10.3
Здесь каждые 300 секунд создаётся новый файл, всего их двенадцать, то есть часовое окно. Это удобно, когда проблема плавающая и ты не знаешь, когда она случится.
Что искать в захвате? Повторяющиеся пакеты с одинаковым номером последовательности (ретрансмиты), нулевое окно (win 0), означающее что приёмник не справляется, и дубликаты ACK. Каждый из этих признаков указывает на свою причину: потери, медленное приложение или перегруженный буфер.
Шаг 5. mtr: где именно теряются пакеты
Traceroute показывает путь, ping показывает потери, а mtr объединяет оба подхода и работает непрерывно. Для отчёта лучше всего подходит режим report:
mtr -rwbzc 100 -i 0.2 8.8.8.8
mtr -rwn -c 100 -T -P 443 192.168.10.3
mtr -rwn -c 50 -u 192.168.10.2
Ключи: -r отчёт, -w широкий вывод, -c 100 сто циклов, -b показать и имя, и адрес, -z показать номера AS, -T -P 443 использовать TCP-пробы на порт 443 (полезно, когда ICMP режется). Интервал 0.2 секунды ускоряет сбор статистики, но на чужих хопах не злоупотребляй, чтобы не выглядеть как атака.
Читать отчёт нужно правильно, и тут большинство ошибается. Смотри на колонку Loss%. Если потери появились на каком-то хопе, но на следующих хопах их нет, это не потери, а ограничение ответов ICMP на этом маршрутизаторе: роутеры обрабатывают транзитный трафик быстро, а на ответы mtr тратят низкоприоритетные ресурсы. Настоящая потеря начинается на хопе и сохраняется до конца маршрута. Пример:
HOST: srv-linux01 Loss% Snt Last Avg Best Wrst StDev
1. rtr-edge01.itpages.lab 0.0% 100 0.4 0.5 0.3 1.1 0.1
2. 10.20.0.1 0.0% 100 2.1 2.3 1.9 4.0 0.4
3. 203.0.113.9 34.0% 100 9.8 10.4 9.5 25.0 2.2
4. 203.0.113.17 33.0% 100 11.2 11.9 10.8 28.4 2.5
5. 8.8.8.8 34.0% 100 12.0 12.6 11.5 30.1 2.9
Потери в 34 процента начинаются на третьем хопе и доходят до цели, значит проблема на стыке после второго хопа, то есть в канале провайдера или на его оборудовании. Именно такой отчёт и стоит прикладывать к обращению в техподдержку провайдера, а не просто фразу «у нас тормозит интернет». Если же потери 34 процента на третьем хопе, а на пятом 0 процентов, можно спокойно идти пить чай.
Обязательно запускай mtr в обе стороны. Маршрут туда и обратно часто различается, и потери могут возникать только на обратном пути. Для этого нужен доступ к удалённой стороне, например, запусти такой же отчёт с rtr-edge01 в сторону srv-linux01.
Шаг 6. Собираем всё в метод
Вот последовательность, которую мы применяем на практике, когда приходит жалоба на сеть.
- Уточни симптом: что именно не работает, откуда, с какого времени, для всех или для одного хоста.
- Проверь интерфейс:
ip -s link,ethtool. Ошибки на физическом уровне исключают всё остальное. - Проверь маршрут:
ip route getдо проблемного адреса. - Проверь связность и MTU: ping с флагом
-M do. - Проверь сокеты:
ss -tulpnиss -tiдля ретрансмитов. - Если картина неясна, запусти tcpdump с узким фильтром и сохрани pcap.
- Для проблем на маршруте запусти mtr в обе стороны и приложи отчёт.
Такой порядок экономит время: каждый шаг либо находит причину, либо исключает целый слой.
Шаг 7. Диагностика на уровне ядра: счётчики и очереди
Иногда пакеты теряются не в сети, а внутри самого хоста: переполнен буфер сетевой карты или сокета. Для таких случаев есть отдельные счётчики, и смотреть их нужно до того, как винить провайдера.
nstat -az | egrep 'TcpRetransSegs|TcpExtListenDrops|UdpInErrors|IpInDiscards'
netstat -s | egrep -i 'retransmit|overflow|drop'
sudo ethtool -g eth0
cat /proc/net/softnet_stat | head -3
sudo dropwatch -l kas
Счётчик TcpExtListenDrops растёт, когда очередь приёма соединений у слушающего сокета переполнена, и значит приложение не успевает вызывать accept. Рост UdpInErrors говорит о переполнении буфера UDP-сокета, типичная картина для DNS-сервера или приёмника syslog под нагрузкой. Команда ethtool -g показывает размер кольцевых буферов сетевой карты: если текущее значение сильно меньше максимального, его можно увеличить через ethtool -G eth0 rx 4096. Второй столбец файла softnet_stat отражает количество пакетов, отброшенных из-за нехватки очереди обработки на ядре процессора, и растущее значение говорит о том, что пора смотреть на распределение прерываний.
Полезный приём: снимай счётчики дважды с интервалом в минуту и сравнивай разницу. Абсолютные значения копятся с момента загрузки и сами по себе ничего не доказывают, а вот скорость роста сразу показывает, идёт ли проблема сейчас.
nstat -n; sleep 60; nstat
Команда nstat без флагов печатает только изменения с прошлого запуска, поэтому такая пара запусков даёт готовую картину за минуту. Если счётчики стоят на месте, а пользователи по-прежнему жалуются, проблема, скорее всего, выше по стеку: в приложении, базе данных или в самом клиенте.
Частые ошибки и как их избежать
- Паника из-за потерь на промежуточном хопе. Потери, которые не доходят до конечного узла, почти всегда результат ограничения ICMP на маршрутизаторе. Оценивай только потери, сохраняющиеся до цели, и сравнивай результаты ICMP-проб и TCP-проб (
-T). - Запуск tcpdump без фильтра и без ограничений. На загруженном сервере это забьёт диск и создаст нагрузку. Всегда указывай хост, порт, ограничение по числу пакетов
-cили ротацию через-Gи-W, и не забывай-nn. - Диагностика не с того уровня. Приложение «не работает», и начинается разбор логов, хотя интерфейс получает CRC-ошибки или сервис слушает только на localhost. Идти нужно снизу вверх: интерфейс, маршрут, сокет, приложение. Тогда каждая проверка занимает секунды.
Что дальше
Администрирование Linux — это набор связанных навыков, вот соседние темы серии: