Как раздельный туннель решает, какой трафик использует VPN
Раздельный туннель — это набор решений о маршрутах и привязках, а не режим, который вы включаете. Посмотрите, как взаимодействуют правила для отдельных приложений, префиксы, DNS и аварийные переключатели.
Раздельный туннель — это политика маршрутизации, выраженная набором правил, и клиент — это лишь то, что их устанавливает. Разделение происходит в двух местах: правила сопоставления, выбирающие путь для каждого пакета, и привязки, удерживающие приложение на одном интерфейсе, что бы ни говорила таблица. То, на каком механизме основан ваш клиент, объясняет большинство неожиданностей, о которых сообщают люди.
Политику, которую можно изложить одной строкой, можно проверить. Политика, описанная как более быстрый просмотр, таковой не является, и она не скажет, какое правило изменить, когда запрос идёт не туда.
Клиент устанавливает правила, ядро делает выбор
Когда туннель поднимается, клиент добавляет маршруты и часто правила политики в ту же таблицу, которую используют другие ваши интерфейсы. Каждый пакет затем попадает в поиск, который сравнивает его назначение с каждым кандидатным префиксом и оставляет самое точное совпадение, а приоритет разрешает ничьи между правилами, указывающими на разные таблицы. Ничто в этом поиске не знает, что пакет пришёл из вкладки браузера, а не из задачи резервного копирования. Побеждает правило, задающее путь, и вы можете прочитать его до и после изменения.
Поэтому раздельный туннель может казаться произвольным. Два назначения в одном приложении могут пойти разными путями просто потому, что один префикс уже другого.
Тот же выбор есть на каждой платформе, хотя названия меняются. Windows вталкивает решение в свою платформу фильтров, Android публикует список разрешённых приложений через свою службу VPN, а macOS привязывает туннель к устройству, которое всё ещё подчиняется таблице маршрутизации. Заметки Microsoft о маршрутизации стоит прочитать для случая Windows, а руководство, написанное для одной платформы, редко переносится без изменений на другую.
Привязка к приложению и префиксы назначения — разные инструменты
Политика назначения спрашивает, куда идёт пакет, и обращается к таблице маршрутов или правилу политики. Политика для приложения спрашивает, какая программа открыла сокет, и платформа удерживает эту программу на интерфейсе туннеля даже тогда, когда более конкретный маршрут указывает в другое место. Вторая сильнее, потому что переживает изменения таблицы, но охватывает только процессы, которые платформа может сопоставить. Вспомогательный процесс, встроенный браузер или служба, открывающая собственное соединение, могут не унаследовать привязку, которую вы предполагали.
Ни один из подходов не выживает без помощи при политике, основанной на именах. Адреса крупных сайтов вращаются между сетями доставки, поэтому прикрепление имени хоста к нескольким префиксам создаёт правило, которое тихо перестаёт совпадать. Политике, которая должна следовать за именами, нужен компонент, понимающий резолвер, а не статический маршрут.
DNS и аварийный переключатель следуют своим правилам
Разрешение имён — отдельное решение от маршрутизации пакетов, и раздельному туннелю обычно нужны два резолвера: корпоративный для внутренних имён и локальный для всего остального. Клиент может установить настройки DNS для каждого интерфейса, передать запросы промежуточному резолверу или оставить системное значение нетронутым. Браузер с собственным шифрованным резолвером обходит все три варианта. Проверьте запрос вместо того, чтобы предполагать, что резолвер последовал за маршрутом.
Аварийный переключатель добавляет фильтр сверху, и этот фильтр не всегда отличает намеренное исключение от случайной утечки. Одни клиенты блокируют всё вне туннеля, другие разрешают исключения, объявленные политикой, поэтому прочитайте, какое поведение реализует ваш, прежде чем полагаться на любое из двух.
Проверьте разделение с обеих сторон
Проверьте включённый путь и исключённый путь по отдельности и оценивайте результат по имени интерфейса, а не по публичному адресу. Эти команды предполагают хост Linux с уже поднятым туннельным устройством. Замените 203.0.113.10 на назначение, которое ваша политика направляет внутрь, а 198.51.100.25 — на то, которое она отправляет наружу.
ip route get 203.0.113.10
ip route get 198.51.100.25
resolvectl query intranet.example.com
curl -s --interface tun0 https://example.com -o /dev/null -w '%{http_code}\n'
Читайте первые два ответа вместе, потому что интерфейс, названный в каждом из них, показывает, поместило ли разделение это назначение в туннель. Запрос к резолверу показывает, какой сервер ответил на внутреннее имя, а последняя команда доказывает, что туннельное устройство вообще способно нести запрос. Сбой во второй строке при успехе первой означает, что политика делает ровно то, что ей велено.
Повторите набор после переподключения и после смены сети. Обновление аренды и смена интерфейсов — это места, где разделение перестаёт соответствовать замыслу, для которого строилось, и сохранённый вывод каждого запуска делает дрейф очевидным.