Пользователь сообщает, что внутреннее приложение работает с одной машины и не работает с другой, а ping, запущенный со шлюза, успешен в обоих случаях. При нескольких туннелях равной стоимости это не противоречие. Каждый поток помещается на свой следующий хоп, поэтому ваша проверка и сеанс пользователя могут просто использовать разные пути. Разбор ниже воспроизводит этот выбор до каких-либо изменений.

Один ping, несколько возможных путей

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

Именно поэтому диагностика со шлюза доказывает так мало. Собственная проверка шлюза имеет свои адреса и порты, а значит и свой хеш. Она может попасть на исправный туннель, тогда как пользователь продолжает попадать на сломанный.

Как платформа выбирает следующий хоп

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

ip route get 10.20.5.7 from 10.20.0.14

Более новые выпуски iproute2 принимают также протокол и порт назначения, что важно, когда хеш включает их. Сравните этот вывод с тем же поиском с работающего клиента, и разница станет недостающим доказательством.

ObservationLikely causeFirst check
Ping works, application failsA different flow hash selects another tunnelPer-flow lookup from the client's address
Some users fail, others do notOne tunnel lacks a prefix or selectorCompare both tunnels' installed routes
Fails only at larger sizesTunnels have different effective MTUProbe the same size over each path
Fails after a reconnectStateful asymmetry between pathsSession state on both gateways

Идите по сбойному потоку, а не по таблице маршрутов

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

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

Проверьте также MTU на каждом пути. Путь с дополнительной инкапсуляцией уменьшает полезный размер, и передача, которая проходит через один туннель, застревает на другом ровно на том размере, где ломается меньший.

Сравнивайте по одному пути за раз

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

Сравнивайте реальное приложение, а не повторные ping. Запишите, следует ли сбой за определённым следующим хопом, размером пакета или переходом после переподключения, потому что эти три закономерности указывают на разные исправления.

Наконец, запишите, почему пути считаются эквивалентными и как сбой должен выводить один из них из эксплуатации. Многопутевость безопасна только тогда, когда пути действительно взаимозаменяемы, и это проектное утверждение, которое стоит проверить, а не предполагать.

Похожие статьи