Спросите, может ли брандмауэр Windows сам служить аварийным выключателем, и получите два уверенных и несовместимых ответа. Один говорит, что правило по типу интерфейса делает всю работу; другой — что без скриптов это не работает. Оба описывают половину одного механизма. Брандмауэр умеет выразить блокировку, а то, действительно ли результат закрывается безопасно, зависит от трёх вещей: как Windows классифицирует туннельный адаптер, сохраняется ли исключение для конечной точки и покрыты ли разрешение имён и IPv6. Ошибётесь хотя бы в одном — машина либо утечёт, либо потеряет всякую связь.

Три условия, в этом порядке

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

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

Третье — покрытие. Набор правил, который блокирует IPv4 и забывает IPv6, или разрешает локальному резолверу искать конечную точку и тем самым разрешает любой другой запрос, открыто отказывает ровно в том окне, для которого и существует выключатель. Это пробел в проектировании, а не ошибка брандмауэра. Это ещё и пробел, который переживает любой прогон тестов на столе.

Классификация — первые ворота

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

Get-NetConnectionProfile | Select-Object Name,InterfaceAlias,NetworkCategory
Get-NetAdapter | Select-Object Name,InterfaceDescription,Status,ifIndex
Get-NetFirewallProfile | Select-Object Name,Enabled,DefaultOutboundAction

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

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

Исключению для конечной точки нужен не только правило, но и маршрут

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

New-NetFirewallRule -DisplayName "VPN endpoint allow" -Direction Outbound -Action Allow \
  -Protocol TCP -RemoteAddress 203.0.113.9 -RemotePort 443 -InterfaceType Wired,Wireless
New-NetRoute -DestinationPrefix 203.0.113.9/32 -InterfaceIndex 12 -NextHop 192.168.1.1
Get-NetRoute -DestinationPrefix 203.0.113.9/32

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

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

DNS и IPv6 — места, где он открыто отказывает

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

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

GapWhat leaksControl
Resolver permitted for endpoint lookupEvery name queried while downPin the endpoint as an address, or block non-tunnel DNS
Rules only for IPv4Full IPv6 connectivityAdd the same rules for the other family
Application bound to physical interfaceIts own trafficFirewall cannot fix this; change the binding

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

Тестируйте, останавливая клиент, а не выдёргивая кабель

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

Stop-Service -Name "YourVpnService" -Force
Test-NetConnection -ComputerName 1.1.1.1 -Port 443
Resolve-DnsName example.com
Test-NetConnection -ComputerName 2606:4700:4700::1111 -Port 443

Все три должны отказать. Если первый удался, блокировка не действует; если второй удался там, где первый отказал, у вас утечка DNS; если удался третий, IPv6 не покрыт. Каждый результат указывает ровно на один из пробелов выше.

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

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

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