Переживает ли аварийный выключатель VPN перезагрузку? Как это проверить
Перезагрузка говорит об аварийном выключателе меньше, чем вы думаете. Проверьте, какой уровень восстанавливает блокировку, когда он запускается и как это проверить до входа в систему.
Перезагрузка — самый распространённый способ проверить аварийный выключатель, и именно этот тест чаще всего лжёт. Флажок в клиенте — всего лишь настройка; важно, применяет ли что-то блокировку между моментом, когда сетевой стек поднимается, и моментом, когда туннель действительно установлен. В Windows это что-то обычно фильтр в Windows Filtering Platform, в Linux — набор правил, загружаемый юнитом, в macOS — якорь pf, в Android — собственные флаги системы для постоянного подключения и блокировки. Эти решения ведут себя очень по-разному при перезагрузке, и только решения на уровне платформы находятся на месте до того, как кто-либо сможет войти.
Перезагрузка задаёт три отдельных вопроса
Разделите вопрос. Во-первых, существует ли политика на диске в виде, который что-то читает при загрузке? Во-вторых, запускается ли этот читатель до того, как какой-либо трафик может уйти? В-третьих, покрывает ли политика интересующий вас трафик, то есть каждый процесс, оба семейства адресов и DNS. «Да» на первый и «нет» на второй дают ровно ту неисправность, которую люди описывают как аварийный выключатель, не переживающий перезагрузку: при запуске трафик утекает на несколько секунд, и никто этого не замечает, пока кто-нибудь не пойдёт проверять.
Держите уровни раздельно. Сохранённый набор правил межсетевого экрана, служба, запускающаяся при загрузке, и настройка клиента — это три разных объекта с тремя разными жизнями. Настройка переживает перезагрузки, потому что это значение в файле конфигурации. Правила — единственное, что блокирует пакеты, и они исчезают вместе с ядром, которое их держало.
Найдите объект, который восстанавливает блокировку
В Linux правила netfilter живут в ядре. Ничто не записывает их обратно при загрузке, если вы это не устроили: iptables-save плюс netfilter-persistent, nftables.service загружает /etc/nftables.conf, или юнит systemd, который выполняет ваш собственный скрипт. Проверьте, что включено, а не то, что вы помните как настроенное.
systemctl is-enabled nftables netfilter-persistent 2>/dev/null sudo nft list ruleset sudo iptables -S OUTPUT
Пустой набор правил через несколько секунд после загрузки — это ответ на вопрос из заголовка. В Windows спросите службу клиента, как она запускается, а затем выгрузите состояние фильтра платформы, пока туннель опущен.
Get-Service | Where-Object { $_.Name -match 'vpn' } | Select-Object Name, Status, StartType
netsh wfp show stateВторая команда записывает wfpstate.xml в текущий каталог. Ищите фильтры с действием блокировки, которые существуют ещё до подключения клиента. Base Filtering Engine запускается рано при загрузке и восстанавливает фильтры, добавленные с постоянным флагом, поэтому одни аварийные выключатели блокируют трафик ещё до появления какого-либо окна клиента, а другие нет. В macOS sudo pfctl -s info сообщает, включён ли pf, sudo pfctl -s rules показывает, что загружено, а клиенты VPN обычно привязывают свои правила к якорю, а не к основному набору. Правило, которое называет utun3, после следующей загрузки может указывать на другой интерфейс, потому что этот номер назначается во время работы.
Следите за разрывом между подъёмом сети и подъёмом туннеля
Опасный интервал — не вся перезагрузка, а разрыв. Интерфейс получает аренду и маршрут по умолчанию в один момент, служба VPN запускается в другой, а туннель аутентифицируется ещё позже, иногда только после того, как пользователь войдёт и отработает агент учётных данных. Если блокировка применяется последней, всё в разрыве уходит открыто.
На хостах с systemd читайте порядок, а не угадывайте его. Выполните systemctl cat на юнитах VPN и межсетевого экрана и поищите After= или Before= относительно network-pre.target и network-online.target. Юнит межсетевого экрана, упорядоченный после network-online.target, проигрывает интерфейсу; тот, который требуется и упорядочен до network-pre.target, выигрывает. В Windows эквивалентные вопросы — тип запуска службы и её зависимости, потому что служба, заданная как Manual, не может блокировать процесс при загрузке. Если ваше требование включает трафик до входа, его удовлетворяет только решение на уровне устройства: туннель устройства Always On VPN аутентифицируется сертификатом машины и подключается до того, как пользователь войдёт, и Microsoft документирует конфигурацию туннеля устройства отдельно от пользовательского туннеля. Android идёт другим путём, принудительно включает VPN и блокирует соединения без него со стороны системы, а не из процесса приложения.
Выполните тест, затем сравните две шкалы времени
Перезагрузитесь с назначением, которое ничего не стоит, если утечёт, и фиксируйте состояние во время разрыва, а не после него. Самый чистый метод — зонд времени загрузки: юнит oneshot или запланированная задача, которая запускается как можно раньше, записывает маршрут по умолчанию и состояние межсетевого экрана, пробует один запрос с коротким тайм-аутом и добавляет строку в локальный файл. Сравните эту запись со временем запуска службы VPN из journalctl -b -u или системного журнала.
Затем выполните обычный тест: туннель поднят, оборвите соединение, посмотрите, блокируется ли прямой трафик, восстановите. Пройти второй и провалить первый — нормальный результат, и он означает, что применение на стороне клиента, срабатывает при подключении клиента, а не при загрузке. На последней машине, которую я проверял, блокировка шла из скрипта диспетчера NetworkManager: присутствующая и правильная и бесполезная для секунд до подъёма интерфейса. Запишите оба результата, потому что переживание перезагрузки что-то значит только тогда, когда вы говорите, какой уровень пережил и с какого момента.
Закройте разрыв, не отрезая себе путь назад
Если при загрузке блокировки нет, опустите применение на уровень ниже вместо добавления второго правила клиента. Сохраните набор правил и загружайте его из юнита, упорядоченного до того, как сеть станет пригодной, и убедитесь, что этому юниту не нужны DNS-запрос или сетевое монтирование, которые он должен защищать. Охват важен не меньше времени: правила, совпадающие по ID пользователя или cgroup, оставляют каждый системный демон вне блокировки, а набор, который обрабатывает только IPv4, оставляет IPv6 и DNS доступными.
Оставьте себе путь назад. Машина, которая при загрузке блокирует всё и затем не может аутентифицироваться, вообще не имеет сети, и исправление не в удалении блокировки, а в починке учётных данных или порядка. Держите документированную процедуру для локальной консоли и узкое, намеренное исключение для того, что туннелю действительно нужно, например адрес сервера и резолвер, используемый до появления туннеля.
Прежде чем доверять этой схеме, подтвердите четыре вещи по порядку. Политика хранится там, откуда её читает загрузка. Этот читатель запускается до того, как интерфейс станет пригодным. Блокировка охватывает оба семейства адресов и DNS. VPN всё ещё может аутентифицироваться, пока блокировка активна. Когда выполняются все четыре, перезагрузка ничего не меняет.