Одна сеть /24 для лабораторного принтера исчезает между двумя вызовами ip route show, а журнал клиента лишь сообщает, что сеть изменилась. С командой, префиксом и вашими правами всё было в порядке. Корпоративный клиент, владеющий моделью маршрутизации хоста, заново утверждает эту модель всякий раз, когда кто-то другой её редактирует, поэтому добавленная вами запись удаляется как посторонняя. Бороться с ним в той же таблице — проигрышная позиция. Решение — полностью прекратить конкуренцию за эту таблицу и поместить исключение туда, куда монитор никогда не смотрит.

Монитор объясняет пропавший маршрут

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

ip route show
ip route add 192.168.2.0/24 dev enp0s31f6
sleep 5; ip route show

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

Вторая таблица невидима для монитора

Агент перестраивает только ту таблицу, которой владеет. Дайте исключению собственную таблицу плюс правило, направляющее туда подходящие адресаты, и главная таблица никогда не меняется, так что агенту нечего исправлять. В этом вся идея: одно пространство имён маршрутов, которое поддерживает кто-то другой, и другое, которого касаетесь только вы.

Плата за это — сопровождение. Два объекта могут разойтись, и положение правила в списке значит столько же, сколько маршрут внутри таблицы, которую оно выбирает.

Постройте исключение, а затем заставьте его победить

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

ip rule add to 192.168.2.0/24 table 110 pref 30010
ip route add 192.168.2.0/24 dev enp0s31f6 table 110
ip route get 192.168.2.50

ip route get разрешает маршрут, который использовало бы ядро, включая устройство и адрес источника. Он не печатает идентификатор таблицы, поэтому сочетайте его с ip rule show, когда нужно подтвердить, какая таблица победила. Вместе они отвечают на единственный важный вопрос: уходит ли трафик к этому адресу туда, куда вы задумали?

Другие формы той же идеи

Шаблон обобщается, как только вы перестаёте думать адресатами. Локальная подсеть может оставаться доступной, пока туннель держит маршрут по умолчанию. Ответы SSH-сервера, подключённого к локальной сети, могут уходить через тот интерфейс, через который пришли, вместо того чтобы исчезать в туннеле. А правило на основе интерфейса может заталкивать в туннель всё, что приходит на беспроводной интерфейс, тогда как трафик, который порождает сам хост, остаётся в Ethernet:

ip rule add iif wlan0 table 10
ip route add default dev tun0 table 10

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

Относитесь к правилу как к одноразовому

Правила и табличные маршруты живут в памяти. После переподключения устройство туннеля может быть переименовано, назначенный адрес может сместиться, а правило со старым значением тихо перестаёт совпадать. Примените всё изменение заново из одного скрипта, который им владеет, а затем перепроверьте ip rule show, текущее имя устройства и свежий ip route get на реальном адресате, прежде чем доверять исключению.

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

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

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