Таблица маршрутизации против реального поиска: куда уходит трафик VPN
Начните с одного назначения и его источника, затем проверьте, какое правило и какая таблица действительно определяют путь. Полный дамп таблицы без этого контекста вводит в заблуждение.
Дамп таблицы маршрутизации — наименее полезная диагностика при поиске проблем VPN и самая часто вставляемая. Сорок строк префиксов говорят о том, что машина могла бы сделать, а не о том, что она сделала для неудавшегося запроса. Механизм, который вам действительно нужен, — это поиск: при заданных источнике и назначении какое правило совпало, какая таблица была опрошена и какие интерфейс и следующий хоп вышли. Начните с одного назначения и одного источника, затем читайте таблицу с этим вопросом в руках, и тот же вывод станет доказательством вместо шума.
Таблица — это набор кандидатов, а не решение
Каждая запись описывает префикс и то, что делать с соответствующим ему трафиком: отправить его на интерфейс, передать следующему хопу или отбросить. Ничто в этом списке не упорядочено по намерению, и запись, которая человеку кажется самой конкретной, не всегда та, которую выбирает ядро, потому что выбор следует самому длинному совпадению префикса, а среди равных префиксов — метрике.
Поэтому первый шаг — спросить ядро, а не читать список. Команда поиска отвечает для назначения, а с аргументом источника — для той самой пары, которую использовало бы перенаправленное или привязанное соединение:
ip route get 198.51.100.10
ip route get 198.51.100.10 from 10.80.0.25
ip -6 route get 2001:db8:10::40
Каждый адрес выше — документационный пример. Дело в форме ответа: интерфейс, выбранный адрес источника, шлюз и таблица, из которой пришла запись. Если этот вывод не совпадает с ожидаемым интерфейсом, вы локализовали проблему одной командой, и никакое чтение полной таблицы не сказало бы, какой кандидат победил.
Поиск проходит сначала правила, затем таблицы
В Linux решение принимается в два этапа. Правила политики оцениваются в порядке приоритета, и первое совпавшее правило называет таблицу для обращения; затем эта таблица выполняет совпадение самого длинного префикса. Правило может совпадать по источнику, назначению, метке межсетевого экрана, интерфейсу или их комбинации, поэтому дамп основной таблицы может быть совершенно точным и совершенно не относящимся к исследуемому пакету.
ip rule show
ip route show table all | head -40
ip route show table 100
Если правило отправляет трафик из вашего пула VPN в таблицу 100, то важна именно таблица 100, и основная таблица — приманка. Это также механизм маршрутизации на основе источника на маршрутизаторе: одно и то же назначение может иметь два разных ответа в зависимости от того, откуда пришёл пакет, и только поиск с аргументом источника показывает, какой из них действует.
У IPv6 свои правила и таблицы. Проекту, который обслуживает оба семейства, нужны оба поиска, а работающий ответ IPv4 ничего не говорит о пути v6, который клиент с двумя стеками может предпочесть.
Что устанавливает клиент VPN
Клиенты обычно не заменяют маршрут по умолчанию, потому что это сломало бы собственный внешний путь туннеля. Они устанавливают нечто более конкретное, что выигрывает по длине префикса: пара половинных маршрутов по умолчанию, покрывающих 0.0.0.0/1 и 128.0.0.0/1, — классический трюк, поскольку оба являются более длинными префиксами, чем 0.0.0.0/0, и вместе покрывают всё пространство. Другие устанавливают конкретные частные префиксы плюс правило политики, а некоторые добавляют метку, чтобы захватывался только выбранный трафик.
Поэтому "VPN не изменил мой маршрут по умолчанию" не является доказательством сбоя. Проверьте, что он всё-таки добавил, и попадает ли рассматриваемое назначение в эти префиксы:
ip route show | grep -E 'tun|wg|ppp|ipsec'
ip route get 10.20.30.40 from 10.80.0.25
Две половинные маршруты легко пропустить в дампе, потому что они не выглядят как маршрут по умолчанию. Конфигурация раздельного туннеля, забывшая включить префикс, даёт ровно тот симптом, который вы ищете: приложение, которое должно было использовать туннель, вместо этого разрешает имя и подключается локально. Сравните установленные префиксы с назначениями, которые пользователю действительно нужны, а не с адресами, которые вы случайно проверили. Список раздельного туннеля, покрывающий файловый сервер, но не его резолвер, даёт соединение, которое разрешается в публичный адрес, а затем не проходит аутентификацию; это похоже на проблему с паролем, а на самом деле проблема маршрута.
Внешний маршрут тоже должен выжить
Туннель сам по себе является трафиком. Пакеты, несущие инкапсулированную нагрузку, идут на адрес партнёра через физический интерфейс, и этот путь не должен маршрутизироваться обратно в туннель. Когда это происходит, вы получаете характерный сбой: туннель устанавливается, а затем перестаёт пропускать трафик, потому что транспорт туннеля теперь находится внутри туннеля.
Проверьте адрес партнёра так же, как проверяли внутреннее назначение, и убедитесь, что он разрешается в физический интерфейс, а не в туннель:
ip route get 203.0.113.10
traceroute -n -m 5 203.0.113.10
Рекурсивный маршрут, правило политики, перехватывающее партнёра, или маршрут по умолчанию, заменённый клиентом полного туннеля, — три обычные причины. Все три видны во внешнем поиске, и ни одна из них не видна в дампе основной таблицы, снятом задним числом.
Чего не может сказать вывод маршрутизации
Правильный поиск означает, что ядро отправило бы пакет в разумное место. Это не значит, что брандмауэр его разрешает, политика IPsec его покрывает, правило NAT его транслирует или у удалённой стороны есть обратный маршрут. Каждый из этих пунктов — более поздний этап, и заметки strongSwan о пересылке описывают цепочку, которую пакет должен пройти на обоих концах.
Он также не учитывает привязку на уровне приложения. Процесс может привязаться к интерфейсу, установить метку или использовать собственный резолвер и подключиться по имени, которое разрешается иначе, чем вы проверяли. Когда поиск верен, а соединение всё равно не удаётся, следующий вопрос — какой процесс его создаёт и видит ли этот процесс ту же таблицу, что и вы.
Поэтому держите диагностику упорядоченной: назовите назначение и источник, выполните поиск, читайте только ту таблицу и то правило, которые назвал поиск, затем проверьте следующий этап. Эта последовательность удерживает исследование маршрутизации в минутах и оставляет запись, которую может повторить кто-то другой, чего вставленная таблица никогда не делает.