Автоматическое добавление маршрута для VPN-подключения в Windows 10

Когда мы подключаемся к некой сети по VPN и при этом нам выдается IP из отдельного пула, который в целевую сеть не входит, то мы должны вручную прописать маршрут до нужной нам сети. Что-то вроде:

route add -p 192.168.2.0 mask 255.255.255.0 172.16.0.1

И так делать необходимо каждый раз при подключении к этому VPN, что хоть и не сложно, но необходимость каких-то дополнительных телодвижений жутко бесит. А если у нас нет прав администратора – выполнить эту команду вообще невозможно. Прописать один раз статический маршрут тоже не выйдет, т.к. при отключении происходит уничтожение соответствующего интерфейса, и маршрут хоть и почему-то остается в списке route print, но при последующем подключении не работает, пока не прописать его заново.

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

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

Исполняется наше желание с помощью виндового же планировщика задач, который будет триггериться на события из журнала – собственно, подключения и отключения нужного нам VPN.

Допустим, что мы подключаемся к VPN-серверу, который находится в сети 192.168.2.0/24, а VPN-клиентам выдает адреса из пула 172.16.0.0/16, сам же имея при этом адрес 172.16.0.1. Таким образом, мы видим шлюз 172.16.0.1, но не знаем, что путь до 192.168.2.0/24 лежит через него.

Нужный нам журнал находится тут:

Просмотр событий – Журналы приложений и служб – Microsoft – Windows – NetworkProfile – Выполняется.

В этот журнал попадают подключения и отключения к различным сетям, что нам и требуется.

Успешное подключение к VPN посредством стандартного rasdial генерирует событие с кодом 10000:

А отключение генерирует событие с кодом 10001:

Это мы и будем ловить. Далее нужно создать два задания в планировщике – на подключение и отключение, которые будут отличаться всего в двух местах.

Создаем задачу:

Создаем действие «Запуск программы» и ставим запуск C:\Windows\System32\ROUTE.EXE с параметрами add -p 192.168.2.0 mask 255.255.255.0 172.16.0.1 – получается та же самая команда на создание маршрута.

Обязательно ставим галку «Выполнить с наивысшими правами», т.е. от админа.

Триггером же нужно поставить событие из журнала. Создаем:

Выбираем «При событии», «Настраиваемое», «Создать фильтр событий», далее «XML», галка «Изменить запрос вручную» и копипастим туда следующее:

<QueryList>
  <Query Id="0" Path="System">
    <Select Path="Microsoft-Windows-NetworkProfile/Operational">
      *[System[(EventID=10000)]] and *[EventData[(Data[@Name="Name"]="MY-VPN")]]
    </Select>
  </Query>
</QueryList>

Где вместо MY-VPN ставим имя нашего подключения.

В «Условиях» снимаем галки про питание и батарею, а также ставим галку «Запускать только при подключении к следующей сети» и выбираем «Любое подключение». Если выбрать в этом списке что-то другое, то задача выполняться вообще не будет, а при попытке запустить ее вручную выдаст непонятную сраку:

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

Задание на создание маршрута готово, теперь создаем задание на его удаление. Оно будет такое же, кроме пары отличий – в параметре команды ROUTE задаем delete 192.168.2.0, а в XML-копипасте ставим EventID=10001.

Теперь подключаемся к нашему VPN и делаем route print. Как видим, маршрут появился сам по себе. Магия!

А теперь отключаемся и видим, что маршрут пропал.

Спасибо за внимание.

Leave a Reply