Почему traceroute умирает в одном направлении через туннель VPN
Трассировка, которая завершается в одну сторону и печатает звёздочки в другую, обычно является диагностической проблемой. Сравните методы зондов, обратные пути и настоящий запрос.
Вывод traceroute, который завершается в одном направлении и печатает ряды звёздочек в другом, выглядит как асимметричная пересылка, и обычно ею не является. Каждому показанному хопу нужно, чтобы зонд дошёл, чтобы маршрутизатор решил ответить и чтобы ответ вернулся и сопоставился с зондом. Разорвите любое из этих звеньев, и строка станет звёздочкой, а туннель продолжит нести данные.
Трассировка — это доказательство о диагностике раньше, чем доказательство о транспорте. Стоит спросить, какое из трёх звеньев отказало, и ответ приходит из пакетов, а не из формы вывода.
Звёздочка — это отсутствующий ответ, а не отсутствующий хоп
Traceroute движется наружу, отправляя зонды, TTL которых истекает на один маршрутизатор дальше в каждом раунде. Маршрутизатор, отбрасывающий просроченный зонд, должен вернуть сообщение ICMP Time Exceeded с собственным именем, и инструмент печатает это имя. На самом деле инструмент ждёт, что это сообщение придёт в пределах тайм-аута. Если маршрутизатор отвечает с другого адреса источника, ограничивает частоту создания ошибок или молча отбрасывает зонд, раунд не даёт ничего пригодного для печати.
Ни один из этих результатов не говорит, что прямой путь сломан. Звёздочка — это отчёт о неотвеченной почте, а не о пустой дороге.
Метод зонда решает, с каким фильтром вы встретитесь
Метод по умолчанию в Linux — обычно UDP-порт назначения с большим номером, tracert в Windows отправляет ICMP-эхо, а Linux можно попросить использовать вместо этого ICMP или TCP. Каждый из них выглядит для межсетевого экрана с отслеживанием состояний или для облачной группы безопасности как иной вид трафика. Сравнивать UDP-трассировку с одной стороны с ICMP-трассировкой с другой — значит сравнивать два разных эксперимента. Зафиксируйте метод, семейство адресов, адрес источника и тайм-аут, прежде чем называть результаты различием.
Для честного сравнения запускайте трассировку с тех хостов, которые действительно несут трафик, а не со шлюза, пересылающего за них. Трассировка, созданная маршрутизатором, использует его собственный адрес источника и политику выхода, которые могут быть строже всего, что видит клиент. Запишите точную команду, чтобы следующий человек мог её повторить.
Значение тайм-аута — другая половина эксперимента, и его легко упустить в заметках. Ожидание в две секунды на перегруженном пути сообщает о звёздочках там, где ожидание в пять секунд сообщает о хопах. Держите значение одинаковым во всех запусках, чтобы сравнение оставалось о сети.
Обратный путь — это собственный маршрут
Ошибка ICMP — это обычный пакет со своим источником и назначением, и ему нужен маршрут обратно к трассировщику. Если политика туннеля несёт префиксы LAN, но не адрес маршрутизатора, создавшего ошибку, сообщение уходит путём, который не может до вас добраться. Фильтрация ответов может отбросить его даже при существующем маршруте, потому что пакет приходит с неожиданного адреса на неожиданном интерфейсе. Это несоответствие в диагностической плоскости, а не сбой приложения.
Расширение каждого селектора, пока трассировка не завершится, делает картину красивее, а политику хуже. Почините конкретный диагностический адрес или примите звёздочку и проверьте приложение иначе.
Подтвердите туннель настоящим запросом
Рукопожатие TCP на собственном порту службы проверяет пересылку, обратную маршрутизацию и фильтрацию в том направлении, которое важно. Команды ниже выполняются на обоих концах и сравнивают, что может открыть каждая сторона. Замените порт службы и имя интерфейса туннеля на свои.
traceroute -I -n -w 2 203.0.113.40
traceroute -T -p 443 -n -w 2 203.0.113.40
curl -sS -o /dev/null -w '%{http_code} %{time_total}\n' --max-time 5 http://203.0.113.40:8080/health
ss -tan state established
Сначала прочитайте два запуска traceroute: если запуск ICMP показывает хопы, а запуск TCP нет, различие в методе, а не в пути. Затем примите результат curl как ответ на уровне приложения, потому что завершённый обмен с разумным кодом состояния означает, что прямой и обратный пути работают для настоящего трафика. Список сокетов показывает, установлено ли соединение вообще, чего никакая трассировка вам не скажет.
Туннель, который несёт интерактивную сессию в обе стороны, пока один traceroute печатает звёздочки, здоров и просто нефотогеничен. Сохраняйте вывод команд с каждой стороны как запись и относитесь к отсутствующим хопам как к открытому вопросу о диагностике, а не как к приговору о VPN.