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

Правила выбирают таблицу, затем таблица выбирает маршрут

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

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

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

Читайте набор правил как последовательность, а не как список

Выведите правила с их приоритетами и таблицами, на которые они ссылаются, затем выведите каждую таблицу, которая несёт маршрут по умолчанию или маршрут туннеля. Порядок — это та часть, которая важна, и именно её снимок экрана обычно опускает:

ip rule show
ip route show table all | sed -n '1,60p'
ip route get 198.51.100.20 from 10.8.0.2
ip route get 198.51.100.20 from 10.8.0.2 mark 0x1

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

Метки и сокеты: два способа, которыми клиенты разделяют трафик

Одни клиенты помечают пакеты в межсетевом экране и добавляют правило, совпадающее с меткой. Другие используют маршрутизацию на уровне сокета, задавая маршрут на сокете до того, как он подключится. Первое видно в ip rule; второе нет, и оно не появится в общем поиске.

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

Проследите владельца, прежде чем добавлять ещё одно правило

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

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

Докажите охват двумя потоками, а не одним

Исправление проверяется только потоком, который должен быть затронут, и потоком, который не должен. Выберите назначение, которое политика направляет в туннель, и то, которое должно остаться снаружи, затем сравните поиски и перехваты для обоих:

ip route get 198.51.100.20 from 192.0.2.44
ip route get 198.51.100.21 from 192.0.2.44
tcpdump -ni any host 198.51.100.21 and port 443

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

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

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