Почему шлюз брандмауэра, привязанный к состоянию VPN, — не правило ping только через туннель
Правило, которое отвечает на ping только пока подключён именованный профиль VPN, — это политика публичного адреса, привязанная к постороннему состоянию, а не разрешение исключительно для туннеля.
Представьте правило брандмауэра, которое включает ICMP echo для публичного адреса сервера каждый раз, когда подключён именованный профиль VPN. Это читается как «ping только через туннель», и такое прочтение ошибочно в важном смысле. Правило не ограничивает, кто может добраться до хоста; оно меняет то, на что отвечает публичный интерфейс, пока случайно активно другое подключение. Это две разные политики, и одна из них тихо расширяет экспозицию.
Правило, которое вы, как вам кажется, написали
Предполагаемое требование обычно узкое: система мониторинга или единственный администратор в VPN должны иметь возможность подтвердить, что сервер жив. Записанное как предложение, оно звучит как контроль доступа к туннелю. Записанное как объект брандмауэра, оно превращается в условие в публичном профиле, потому что именно туда приходит запрос echo.
Как только условием становится состояние соединения, а не адрес источника, набор разрешённых отправителей уже не набор партнёров VPN. Любой, кто может добраться до публичного адреса, может отправить запрос echo, пока шлюз открыт. Туннель не стал путём; туннель стал переключателем.
Люди, продвигающие эту идею, обычно не лгут о желаемом эффекте. Им нужна была проверка, которая отвечает только когда канал здоров, а здоровье канала проще всего было наблюдать через VPN. Ошибка — считать сигнал доступности решением о доступе и затем автоматизировать его.
Чем шлюз на самом деле управляет
Эта схема сливает две независимые вещи, и их разделение — большая часть исправления. Первое — охват: какой локальный адрес, какие удалённые адреса, какой протокол и какой тип ICMP. Второе — условие: включён ли объект правила в данный момент. Охват — это то, что брандмауэр оценивает для каждого пакета; условие — это то, что скрипт записывает в хранилище политик, и они согласуются по совершенно разным часам.
Если требование действительно только партнёры VPN, охват отвечает на него без всякой логики состояния соединения: привяжите правило к интерфейсу туннеля или к диапазону адресов туннеля, ограничьте удалённые адреса пулом клиентов и укажите тип echo вместо «ICMP». Это правило остаётся верным, когда ни один VPN не поднят, и его не может открыть посторонний профиль.
Если требование действительно публичный шлюз, скажите это в тексте политики, потому что критерии приёмки меняются. Публичный шлюз должен назвать точный профиль, определить, что значит «подключён», и заявить, что публичные отправители входят в охват по замыслу. Большая часть путаницы исчезает в тот момент, когда кого-то заставляют записать это предложение.
Постройте объект один раз, потом переключайте
Заранее создайте одно правило со стабильным идентификатором, отключённое, и позвольте контроллеру менять только его состояние включения. Создание правил по отображаемому имени при каждом запуске — это путь, которым хранилище политик обзаводится пятью почти одинаковыми объектами и не имеет надёжного способа их убрать.
New-NetFirewallRule -Name "VpnGateEchoV4" -DisplayName "Public echo gated on VPN state" -Direction Inbound -Action Allow -Protocol ICMPv4 -IcmpType 8 -LocalAddress 203.0.113.10 -RemoteAddress Any -Enabled False
Set-NetFirewallRule -Name "VpnGateEchoV4" -Enabled True
Имя — устойчивый идентификатор; отображаемое имя — документация, которую человек может редактировать. Согласуйте по -Name, и скрипт перестанет создавать дубликаты. Та же форма команды покрывает случай IPv6 с -Protocol ICMPv6 -IcmpType 128, но это отдельное правило, потому что номера типа echo различаются у двух семейств.
Держите семейство адресов и тип ICMP явными и по второй причине: -Protocol ICMPv4 без типа разрешает любое сообщение ICMPv4, которое допускает профиль, включая те, которые вы никогда не собирались принимать. Указание типа 8 сужает правило до запроса echo, и только это отправляет проверка доступности.
Где автоматизация противоречит замыслу
Опрос клиентского профиля каждые несколько минут не может дать мгновенной границы. Между падением соединения и следующим опросом правило всё ещё отвечает на публичном адресе; между подъёмом соединения и следующим опросом не отвечает. Признать эту задержку честно, а утверждать, что схема обеспечивает строгий инвариант, — нет.
В самой проверке состояния есть ловушка охвата. Get-VpnConnection сообщает о клиентских профилях, настроенных на машине, по умолчанию для текущего пользователя и для всех пользователей с -AllUserConnection. Он не сообщает об удалённых пользователях, которые прямо сейчас подключены к серверу RRAS; это другое наблюдение с другой командой. Шлюз, построенный на неправильном, ни с чем не связан.
Затем покройте состояния, которые никто не описывает скриптом: запуск с уже включённым правилом из прошлого прогона, падение контроллера при открытом шлюзе и удалённый профиль, чьё правило остаётся живым. Каждому нужно определённое значение по умолчанию, а безопасное значение по умолчанию для публичного разрешения — выключено. Если требование действительно не терпит окно опроса, правило, привязанное к состоянию, — неверный инструмент, и принуждение относится к туннелю, а не к публичному интерфейсу.
Наконец, проверьте публичный запрос дважды: один раз с поднятым выбранным соединением и один раз с опущенным, с хоста, который не находится в VPN. Успешный ping изнутри туннеля ничего не доказывает об этой политике, и именно это измерение пропускает большинство внедрений.