MAATRIX / Блог / Хоп со 100% потерь в трассировке — и всё работает: как ICMP обманывает диагностику

Хоп со 100% потерь в трассировке — и всё работает: как ICMP обманывает диагностику

MAATRIX

Открываете mtr, видите на пятой строке 100.0% в колонке Loss — и первая реакция: канал разорван, надо срочно писать в поддержку хостера. Но сайт при этом открывается, SSH не подвисает, видеозвонок идёт без заикания. Это одна из самых частых ловушек сетевой диагностики: сто процентов потерь на одной строке трассировки почти никогда не означают, что теряется сто процентов вашего трафика. В большинстве случаев это значит лишь одно — конкретный узел на пути не хочет разговаривать с трассировкой, хотя транзитный трафик через него идёт совершенно нормально.

Что на самом деле означает 100% Loss на одной строке

Когда mtr или traceroute строят маршрут, они не спрашивают у сети список роутеров напрямую. Они шлют пакеты с последовательно растущим TTL (Time To Live) и ждут от каждого промежуточного узла служебный ICMP-пакет Time Exceeded — именно по нему трассировка узнаёт IP-адрес этого хопа. Строка 100.0% в колонке Loss% означает одно и только одно: за всё время замера ни один из отправленных на этот TTL пробников не получил ответа Time Exceeded от этого конкретного узла.

Это не «сто процентов пакетов не дошли до цели». Это «сто процентов диагностических запросов к этому конкретному узлу остались без ответа». Разница принципиальная, и вот почему:

  • обычный транзитный пакет (TCP-сегмент вашего сайта, UDP-пакет видеозвонка, ICMP echo к конечной цели) роутер форвардит — просто уменьшает TTL и отправляет дальше по таблице маршрутизации;
  • пакет, вызвавший Time Exceeded, роутер должен не форвардить, а сгенерировать новый пакет — ICMP-ответ с собственным IP в поле источника, адресованный обратно вам.

Это две совершенно разные операции на разном оборудовании внутри одного и того же роутера. Форвардинг — это data plane, обычно реализованный в специализированных чипах (ASIC) и работающий на полной скорости линии, без каких-либо искусственных ограничений. Генерация ICMP-ответа — это control plane, часто обслуживаемый обычным процессором роутера, который на магистральном оборудовании умышленно изолируют от перегрузки. Именно на этом стыке и рождается ложная «потеря».

В выводе можно встретить два разных обозначения этой ситуации, и они означают чуть разные вещи:

 3. (waiting for reply)             100.0%   100    -     -     -     -
 4. 10.10.10.1                       42.0%   100   8.1   9.4   7.9  22.1

Строка (waiting for reply) — узел вообще не назвал свой IP ни разу (в traceroute это классические * * *). Строка с реальным IP и Loss% меньше 100, например 42%, — узел иногда всё же отвечает, просто через раз. Оба варианта не говорят о разрыве канала.

Почему роутер прекрасно пересылает трафик, но молчит на ICMP

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

Причина первая — политика «не свети топологию». Многие операторы сетей и администраторы файрволов сознательно настраивают оборудование не отвечать на ICMP TTL-exceeded и/или echo-request вовсе. Логика простая: трассировка раскрывает внутреннюю структуру сети — количество хопов, их адресацию, иногда имена в reverse DNS, что для магистрального оператора или корпоративного периметра лишняя информация для потенциального сканирования. Правило обычно выглядит примерно так на Cisco-подобном оборудовании:

# пример политики на пограничном маршрутизаторе — не генерировать ICMP unreachable/time-exceeded наружу
no ip unreachables

На Linux-хостах с iptables то же самое достигается явным дропом исходящих ICMP-ответов определённых типов, оставляя при этом форвардинг обычного трафика (FORWARD chain) нетронутым:

# не отвечать на ICMP echo-request, но не трогать форвардинг остального трафика
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP

Обратите внимание: это правило в цепочке INPUT, оно касается входящих ICMP-запросов к самому узлу, и никак не задевает FORWARD — то есть транзитный трафик через этот узел эта настройка вообще не трогает.

Причина вторая — ICMP rate limiting как защита от DDoS и сканирования. Даже там, где полного запрета на ICMP-ответы нет, почти всё сетевое оборудование ограничивает скорость генерации именно диагностических ICMP-сообщений — обычно через policer или CoPP (Control Plane Policing). Смысл в том, чтобы шторм traceroute-запросов (случайный от миллионов пользователей интернета или намеренный при DDoS/сканировании) не нагружал управляющий процессор роутера, отвечающий заодно за BGP, ARP и прочую служебную логику. Превышение лимита — и часть ICMP-ответов просто отбрасывается ещё до генерации, а форвардинг обычных пакетов эту очередь вообще не проходит.

Итог одинаковый в обоих случаях: узел выглядит в трассировке «мёртвым» или «теряющим», при этом транзитный TCP/UDP-трафик через него проходит без каких-либо изменений.

Нужен сервер под эту задачу?

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

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

100% против частичных потерь: в чём разница для диагностики

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

Что видно в mtrВероятная причинаЧто это значит для реального трафика
Стабильные 100.0% на одном хопе, повторяются от замера к замеруАдминистративный запрет отвечать на ICMP (no ip unreachables или аналог)Обычно ничего — узел просто никогда не участвует в диагностике
Частичные потери (10-60%), колеблются между замерамиICMP rate limiting: часть запросов укладывается в лимит, часть — нетОбычно ничего, но полезно перепроверить с большим числом циклов, чтобы исключить совпадение по времени с реальной перегрузкой
100% на одном хопе, но следующий хоп и цель отвечают чистоЛюбая из двух причин вышеТранзит через этот узел работает — иначе следующий хоп физически не получил бы ваш пакет
Потери нарастают на этом хопе и сохраняются на всех последующихРеальная потеря пакетов на канале или перегрузка интерфейсаСтоит разбираться всерьёз — см. следующий раздел

Ключевая колонка здесь — не Loss% самого «красного» хопа, а то, что происходит после него. Именно этому посвящено практическое правило, которое стоит запомнить один раз и больше не путать.

Золотое правило: последняя строка и хопы после проблемного узла

Единственный надёжный способ отличить диагностический шум от реальной потери трафика — посмотреть не на сам «красный» хоп, а на то, что происходит дальше по маршруту.

Если хоп N показывает 100% (или высокий процент) потерь, а хоп N+1 и все последующие хопы вплоть до цели отвечают чисто — узел N в порядке. Он просто не участвует в диагностике, но пакеты через него проходят исправно: чтобы хоп N+1 вообще получил ваш пробник и ответил на него, этот пробник обязан был физически пройти через узел N. Ответ хопа N+1 — прямое доказательство того, что форвардинг на узле N работает.

Пример типичного вывода, который вызывает панику зря:

Host                               Loss%   Snt   Last   Avg  Best  Wrst
1. 192.168.1.1                      0.0%   100    0.4   0.5   0.3   1.2
2. 10.20.0.1                        0.0%   100    2.1   2.3   1.9   5.4
3. core1.upstream-carrier.net      100.0%   100    -     -     -     -
4. core2.upstream-carrier.net       0.0%   100   11.9  12.4  11.7  15.0
5. edge.hosting-provider.net        0.0%   100   13.2  13.6  12.9  17.4
6. target-server.example.com        0.0%   100   14.0  14.5  13.7  18.1

Хоп 3 молчит стопроцентно на каждом цикле опроса. Хоп 4 отвечает без единой потери, с адекватной задержкой, продолжая маршрут через тот же магистральный сегмент. Хоп 5 и цель (хоп 6) — идеальны. Единственное разумное прочтение: core1.upstream-carrier.net административно не отвечает на ICMP, но пересылает всё остальное без проблем. Разрыва канала здесь нет.

А вот противоположный пример, где паниковать уже стоит:

Host                               Loss%   Snt   Last   Avg  Best  Wrst
3. core1.upstream-carrier.net      35.0%   100   11.8  12.1  11.5  14.0
4. core2.upstream-carrier.net      33.0%   100   12.4  12.9  11.9  16.2
5. edge.hosting-provider.net       34.0%   100   13.2  13.8  12.7  17.9
6. target-server.example.com       32.0%   100   14.0  14.6  13.5  19.0

Здесь потери не исчезают на следующем хопе, а тянутся дальше практически неизменным процентом вплоть до последней строки, которая отражает ответ непосредственно от вашего сервера, без посредников. Это уже похоже на реальную потерю пакетов на участке до хопа 3 включительно, а не на особенность ICMP-политики одного узла. Как отличать такие каскадные потери от шума и локализовать проблемный участок, подробнее разобрано в статье про поиск участка, где теряются пакеты.

Как проверить, что сервис реально работает, а не полагаться на mtr

ICMP-трассировка — вспомогательный инструмент, а не источник истины о работоспособности сервиса. Если сомневаетесь, работает ли сервис на самом деле, несмотря на «красный» хоп посередине, проверяйте это на уровне приложения — тем же протоколом, которым реально пользуются клиенты.

Для HTTP/HTTPS-сервиса — прямой запрос с разбивкой по фазам соединения:

curl -o /dev/null -s -w \
  "connect: %{time_connect}s  ttfb: %{time_starttransfer}s  total: %{time_total}s  code: %{http_code}\n" \
  https://your-service.example.com/

Если time_connect и time_total стабильны и http_code возвращает ожидаемый код на десятках последовательных запросов — сервис отвечает нормально, и один «красный» хоп в трассировке к делу не относится.

Для оценки реальных потерь и повторных передач на уровне TCP-соединения (а не ICMP) — статистика сокета:

ss -ti dst your-service.example.com

В выводе интересны поля retrans (реальные ретрансмиссии на активном соединении) и rtt (round-trip time для данных, а не для ICMP-пробников). Если ретрансмиссий почти нет, а RTT стабилен — транспорт работает штатно вне зависимости от того, что показывает трассировка.

Для нагрузочной или потоковой проверки, когда важна не просто доставка одного запроса, а устойчивость под трафиком — iperf3 между двумя контролируемыми точками (клиент и сервер, если на сервере можно временно поднять iperf3 -s):

iperf3 -c your-server-ip -t 30 -i 5

Смотрите на колонку retransmits в TCP-режиме — она отражает реальные потери на канале, а не ответы промежуточных узлов на диагностику. Классический ping тоже может вводить в заблуждение и не показывать потери, которые реально бьют по приложению, — отдельный разбор в статье о потере пакетов, которую не видно в ping.

Когда красный хоп всё же повод насторожиться

Правило «смотри на хопы после» не означает, что любой Loss% в середине трассы можно игнорировать по умолчанию. Есть три ситуации, где стоит копнуть глубже, прежде чем списывать всё на ICMP-политику:

  • Потери есть на самой последней строке. Это уже не промежуточный узел, экономящий на диагностике, а ответ непосредственно от целевого сервера или ближайшего к нему узла. Если тут есть Loss%, разбираться нужно всерьёз, начиная с проверки на уровне приложения из предыдущего раздела.
  • Потери на проблемном хопе повторяются («тащатся») на всех последующих хопах, включая цель, как во втором примере выше. Если процент потерь примерно одинаковый на нескольких хопах подряд вплоть до цели — это, скорее всего, реальная деградация на участке до первого из этой цепочки, а не совпадение независимых ICMP-политик.
  • Симптом воспроизводится не только в mtr, но и в приложении — обрывы звонков, таймауты, ретраи на клиенте, ошибки в логах в то же самое время. Совпадение по времени — повод проверить, не изменилась ли картина именно на последней строке или после проблемного узла.

Если ни одно из трёх условий не выполняется — конечная точка чистая, потери не накапливаются дальше, приложение работает без сбоев — статистически вероятнее всего, что дело именно в административной ICMP-политике узла, а не в реальном инциденте на сети.

Практический чеклист: что делать при виде одного «красного» хопа

  1. Не открывайте тикет в поддержку хостера или провайдера сразу после первого mtr с одним красным хопом посередине. Это самая частая и самая избыточная эскалация в сетевой диагностике — узел, который не отвечает на ICMP, встречается почти на любом достаточно длинном маршруте и это нормальная часть работы интернета.
  1. Прогоните mtr ещё раз с увеличенным числом циклов, чтобы отличить стабильную картину от случайного совпадения:
mtr -rwnc 300 your-service.example.com
  1. Проверьте, что происходит на хопе сразу после проблемного и на последней строке. Если оба чистые — узел в порядке, дальше разбираться не с чем.
  1. Если сомнения остаются, проверьте сам сервис по протоколу, которым реально пользуются клиенты (curl для HTTP, ss -ti для активных TCP-соединений, iperf3 для пропускной способности) — не через ICMP, а через тот же транспорт, что и у пользователей.
  1. Если потери накапливаются к цели или видны на последней строке — вот тогда стоит писать в поддержку, приложив оба mtr-отчёта (свой и, если есть доступ, встречный со стороны сервера), а не скриншот одной «красной» строки. Более широкий разбор того, к кому именно обращаться — своему провайдеру, транзитной сети или хостеру, — в статье про локализацию потери пакетов.
  1. Держите под рукой «нормальную» трассу до ключевых серверов, снятую заранее, пока всё работает штатно — так при следующей жалобе на «сеть тормозит» будет с чем сравнить.

Нужен сервер под эту задачу?

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

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

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

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

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

В mtr один хоп показывает ровно 100.0% Loss, остальные — 0%. Точно ли это ложная тревога?

В подавляющем большинстве случаев да. Если хоп сразу после проблемного и сама цель отвечают без потерь на протяжении нескольких прогонов, это означает, что узел просто не генерирует ICMP-ответы (административная политика или rate limiting), а транзитный трафик через него проходит нормально.

Чем 100% Loss на промежуточном хопе отличается от * * * в классическом traceroute?

По сути ничего — оба обозначения означают отсутствие ICMP-ответа от узла на этом TTL. mtr показывает это как процент от общего числа отправленных пробников, а однократный traceroute — как три звёздочки за один неудавшийся замер.

Может ли узел с ICMP rate limiting всё же слегка тормозить реальный трафик?

Теоретически, если ограничение затрагивает общую политику QoS на интерфейсе, а не только генерацию ICMP-ответов — да, но на практике это редкость: rate limiting почти всегда настраивается на control plane узла, отдельно от data plane, который форвардит обычные пакеты. Разница в реальном трафике подтверждается только прямым тестом (curl, iperf3), а не косвенно через mtr.

Как быстро проверить, реальная ли проблема, если нет доступа к серверу для встречного замера?

Смотрите, накапливаются ли потери на хопах после подозрительного (признак реальной проблемы) или обнуляются (признак ICMP-политики), и параллельно проверьте сервис напрямую — curl с таймингами или ping до самой цели, а не до промежуточного хопа.

Стоит ли вообще обращать внимание на Loss% в mtr, если он всё равно часто ложный?

Да, но как на вспомогательный сигнал, а не как на окончательный вердикт. Полезно смотреть на общую форму трассы (где начинаются и где заканчиваются потери) и держать её под рукой для сравнения со временем, а окончательное решение о реальности проблемы всегда принимать по последней строке и по поведению самого сервиса.

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

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

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