Нижестоящая подсеть и VPN на рабочем столе: исключайте транзит, а не приложения
Обход для отдельного приложения классифицирует только локальный вывод. Устройствам за рабочей станцией нужна собственная политика входа, пересылки и обратного пути.
Одна машина, две задачи, один брандмауэр: восходящий канал Wi-Fi, небольшая подсеть Ethernet за ним и клиент VPN для рабочего стола, который считает, что всё, покидающее машину, локально. Локально запущенные приложения выходят через локальный путь вывода. Устройства за рабочей станцией приходят на порт Ethernet и требуют решения о пересылке. Исключение, написанное для первого пути, никогда не видит второй, и поэтому браузер обходит туннель, а устройства — нет.
Два пути пакетов, одна политика
| Origin | Path | Decision owner |
|---|---|---|
| Application on the workstation | OUTPUT then egress | The VPN app's routing policy |
| Device behind the workstation | PREROUTING then FORWARD | The workstation's own forwarding policy |
Первая строка — это то, что описывают большинство руководств по split-tunneling. Вторая — конфигурация маршрутизатора, которая случайно живёт на той же машине. Сливать их в одну мысленную модель — ошибка; они делят ядро, но не политику. Нарисуйте оба пути, прежде чем править любое правило, и остальная часть проекта следует из того, какого пути не хватает.
Таблица также объясняет, почему одна машина может пройти один тест и провалить другой. Браузер на рабочей станции подтверждает локальный путь; ноутбук, подключённый к порту Ethernet, подтверждает путь пересылки. Проверяйте изменение обоими, иначе второй останется непроверенным, сколько бы раз ни обновлялся браузер.
Что на самом деле классифицирует исключение приложения
Исключение для отдельного приложения обычно работает так: помечаются пакеты процесса или пользователя, а затем помеченный трафик направляется вне туннеля. Это конструкция локального вывода. У пакета от нижестоящего устройства нет локального процесса, поэтому он никогда не совпадает с селектором, каким бы селектор ни был.
Каким бы ни был селектор, два списка — не один и тот же список, и в этом вся суть. Руководство Mullvad для Linux описывает метки, которые потребляет его брандмауэр и политика маршрутизации, а примеры нацелены на локальный вывод; это не поддерживаемое описание нижестоящего маршрутизатора. Их копирование даёт машину, которая считает, что у неё есть исключение, но передаёт всё в туннель.
Напишите транзитный контракт
Назовите вместе префикс источника внизу и входной интерфейс, затем ограничьте этот префикс на входе. Без ограничения любое устройство, достигающее порта, может заявить исключённый адрес и выйти через обход. Рассматривайте это как два вопроса: могут ли эти хосты вообще использовать этот восходящий канал и могут ли они достигать рабочей станции или частных диапазонов туннеля? Это дополнительные разрешения, а не побочный эффект выбора канала.
Разрешите пересылку, а затем отфильтруйте её. Шлюзу Linux нужны включённая пересылка, правила, разрешающие нужный трафик в обе стороны, и либо обратный маршрут вверх, либо намеренно ограниченное преобразование источника. Один NAT не выбирает канал и не даёт прохода через фильтр; он лишь переписывает адрес после этих решений.
Классификация для транзита должна происходить до решения о маршруте пересылки, то есть на этапе prerouting, а не output. Правило, размещённое после решения, ещё может изменить пакет, но не может изменить, куда он уже отправлен.
Метки принадлежат приложению, которому они принадлежат
Значения меток, номера таблиц и приоритеты цепочек — часть политики приложения VPN, а не вечные константы. Устойчивая сеть, зависящая от вставки правила в таблицу, которую пересоздаёт другая программа, сломается при следующем обновлении, обычно во время переподключения, а не в удобный момент.
Добавление второй базовой цепочки с вердиктом accept не обязательно отменяет drop более поздней цепочки. У базовых цепочек есть хуки и приоритеты, и первый вердикт в порядке выигрывает; accept в одной цепочке не отменяет drop, до которого другая цепочка доходит раньше. Смотрите на полный набор правил и порядок политики маршрутизации, а не на единственный счётчик, который вырос. Счётчик доказывает, что правило сработало, но никогда — что применён именно его вердикт.
Интегрируйте или перенесите подсеть
Два проекта различаются тем, кто владеет обходом. Интегрированный проект сохраняет одну машину и одну политику ценой зависимости от жизненного цикла таблиц приложения VPN и от набора меток, которые может изменить его документация. Отдельный маршрутизатор для нижестоящей сети полностью убирает эту зависимость: у подсети есть свой восходящий канал, а рабочая станция остаётся клиентом без роли пересылки.
Выберите второй, когда нижестоящая сеть должна продолжать работать через обновления VPN, или когда никто не может проверить интегрированную политику после каждого выпуска. Выберите первый только когда интеграция документирована и кто-то за неё отвечает.
Проверьте границу в четырёх состояниях: подключено, переподключение, намеренно заблокировано и остановлено. Проверяйте разрешение имён и оба семейства адресов в каждом из них, потому что обход, утекающий DNS, — это не то исключение, которое вы спроектировали. Тест должен доказать точную границу, а не только то, что загрузилась одна страница.