VPN-подключение Windows не хранит DNS-серверы в профиле, который вы правите в Параметрах. Когда туннель поднимается, клиент согласует IP-конфигурацию со шлюзом, шлюз присылает список резолверов, а Windows применяет его к адаптеру туннеля. Этот адаптер — отдельный интерфейс от вашего Wi-Fi или Ethernet, и список принадлежит интерфейсу, а не профилю. Когда вы знаете, какой объект владеет значением, переопределить его в PowerShell — одна команда; заставить переопределение пережить переподключение — это та часть, которая требует решения.

Какой объект владеет адресом

RAS создаёт адаптер туннеля при успешном подключении и удаляет его при обрыве. DNS-серверы, которые вы видите в ipconfig /all, приходят во время этого обмена конфигурацией, рядом с адресами IPv4 и IPv6 и маршрутами. Поскольку значение привязано к интерфейсу, Set-DnsClientServerAddress пишет в нечто, что существует только пока существует подключение.

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

Найдите псевдоним, прежде чем трогать DNS

Имя профиля и псевдоним интерфейса обычно совпадают как строка, но это не один и тот же объект. Get-VpnConnection выводит профили; Get-NetAdapter выводит интерфейсы, которые у Windows действительно есть. Командам cmdlet DNS нужен второй, и эти двое расходятся чаще, чем люди ожидают, особенно когда клиент добавляет к имени адаптера описание вроде "(RAS)".

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

Add-VpnConnection -Name "Corporate" -ServerAddress vpn.example.net `
  -TunnelType Ikev2 -EncryptionLevel Required `
  -AuthenticationMethod Eap -AllUserConnection

Подключитесь один раз, затем прочитайте настоящий псевдоним, прежде чем писать любую команду DNS:

rasdial.exe "Corporate"
Get-NetAdapter | Where-Object InterfaceDescription -like "*VPN*"
Get-DnsClientServerAddress -InterfaceAlias "Corporate"

Применяйте переопределение в правильном порядке

Порядок важнее синтаксиса. Адаптер должен быть поднят, псевдоним должен разрешаться, а учётной записи должно быть разрешено менять параметры интерфейса. Подключение на пользователя обычно принимает изменение от вошедшего пользователя; подключение для всех пользователей, созданное с -AllUserConnection, как правило, требует повышенной оболочки.

Сам cmdlet — одна строка, задокументированная в справочнике Set-DnsClientServerAddress от Microsoft:

Set-DnsClientServerAddress -InterfaceAlias "Corporate" -ServerAddresses 10.20.0.53,10.20.0.54
Get-DnsClientServerAddress -InterfaceAlias "Corporate" -AddressFamily IPv4

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

Почему переподключение может отменить изменение

Переопределение принадлежит одному экземпляру интерфейса. Когда клиент сносит адаптер и пересоздаёт его при следующем подключении, присланные значения применяются снова, и ваш список исчезает. Одни клиенты пересоздают интерфейс при каждом подключении; другие используют его всю сессию. Сравните индекс интерфейса в Get-NetAdapter между двумя подключениями, и вы узнаете, какое поведение у вас.

Есть три долговечных ответа, и их наложение порождает собственные дефекты. DNS-суффикс, привязанный к подключению, плюс правило NRPT отправляют во внутренний резолвер только внутреннее пространство имён и не трогают публичные имена. Параметр групповой политики или MDM, применённый к VPN-подключению, задаёт DNS в момент подключения без всякого скрипта. Запланированная задача, которая реагирует на событие подключения и перезапускает cmdlet, — грубый вариант, но он работает и оставляет журнал. Выберите одного владельца DNS и запишите, кто это.

Внутренние имена с одной меткой тоже нуждаются в списке поиска суффиксов. Set-DnsClientGlobalSetting -SuffixSearchList действует на всю машину, поэтому меняет разрешение для каждого адаптера на компьютере, включая Ethernet. Проверьте его на лабораторной машине, прежде чем оно попадёт в образ.

Проверяйте разрешение, а не только настройку

Резолвер, указанный на адаптере, доказывает лишь то, что значение записано. Спросите нужный сервер напрямую, затем спросите обычным путём:

Resolve-DnsName server01.corp.example -Server 10.20.0.53
Resolve-DnsName server01.corp.example

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

Запустите тест дважды: один раз сразу после подключения и один раз после отключения и повторного подключения, и сравните вывод Get-DnsClientServerAddress из обоих запусков. Если присланное значение вернулось на втором подключении, переопределение живело и умерло вместе с адаптером, и удержится только правило NRPT или маршрут политики из предыдущего раздела. Сохраните обе расшифровки и метки времени подключения; они решают вопрос, сохраняется ли настройка, быстрее, чем ещё один круг правок.

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