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

Отправленный параметр — это предложение, а не установка

На сервере две директивы описывают намерение, а не эффект:

push "dhcp-option DNS 10.8.0.1"
push "dhcp-option DOMAIN corp.example"

Клиент не получает настроенный резолвер. Он получает переменные окружения, foreign_option_1 и следующие, по одной на каждую отправленную строку, и что-то локальное должно их прочитать и переписать состояние резолвера операционной системы. В Linux по умолчанию этого не делает ничто, поэтому исправный сервер и подключённый клиент всё ещё могут разрешать имена через LAN.

Между двумя концами три этапа: отправка должна дойти, клиент должен её раскрыть, а хук применить. Читайте средний этап в журнале клиента, а последний в состоянии резолвера, никогда наоборот, потому что одна строка журнала доказывает только первые два.

Убедитесь, что отправка дошла, и найдите владельца

Начните с названия запускающего: голая openvpn команда, экземпляр systemd, NetworkManager или клиент поставщика. Это решает, где может жить хук. На хосте с systemd-resolved, resolvectl status перечисляет каждое звено с DNS-серверами и доменами поиска, которые оно действительно использует, а звено туннеля не всегда называется tun0.

Если отправленный адрес есть в журнале, но ни на одном звене нет, интеграция отсутствует. Если он есть на звене, а запросы всё равно уходят в другое место, проблема в том, какие запросы выбирают это звено. NetworkManager dns=dnsmasq в файле /etc/NetworkManager/NetworkManager.conf запускает локальный пересыльщик, который намеренно реализует разделённый DNS: имена внутри домена VPN идут к резолверу VPN, всё остальное сохраняет прежний путь. Такое поведение выглядит как неисправность, когда вы ждали, что переместится весь трафик; проверьте настройки для каждого соединения с помощью nmcli connection show "My VPN", где ipv4.dns и ipv4.dns-search хранят значения за тем, что сообщает устройство, прежде чем называть это сломанным. Если каждый запрос действительно должен достигать резолвера VPN, удалите dns=dnsmasq из NetworkManager.conf и перезапустите NetworkManager, что вернёт разрешение имён настройкам соединения; иначе оставьте разделённый DNS и исправьте отправленный список доменов.

Linux: передайте параметры резолверу

Пакеты дистрибутивов поставляют для этого хук, и клиенту должно быть разрешено его запускать. Типичная схема на хосте без systemd-resolved:

script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

С systemd-resolved старый скрипт resolv.conf может ничего важного не изменить, потому что stub-резолвер держит состояние по каждому звену. update-systemd-resolved помощник документирует форму хука, использующую up-restart и down-pre, что важно, когда интерфейс переживает одну попытку соединения. Что бы вы ни выбрали, состоянием должен владеть один компонент. Добавление постороннего хука рядом с NetworkManager даёт двух писателей одному звену, и результат тогда зависит от порядка, а не от вашей конфигурации.

Есть и случай, когда NetworkManager полностью игнорировал отправленный параметр, пока адрес сервера не был введён в настройках IPv4 соединения, после чего состояние резолвера показало, что он используется. Стоит попробовать до переписывания скриптов, потому что это переносит проблему из хука оболочки в профиль соединения, который уже несёт туннель.

Windows и macOS применяют разные части

Клиент Windows действительно задаёт DNS-серверы адаптера VPN, но Windows по-прежнему выбирает интерфейс по метрике и по-прежнему требует суффикс, чтобы раскрыть короткое имя. Подтвердите состояние адаптера, а не профиля:

Get-DnsClientServerAddress -InterfaceAlias "My VPN"
Get-DnsClientNrptPolicy

Если адрес отсутствует, задайте его с помощью Set-DnsClientServerAddress -InterfaceAlias "My VPN" -ServerAddresses 10.8.0.1, затем добавьте суффикс в свойства IPv4 адаптера, чтобы fileserver стал fileserver.corp.example. Значение SearchList в масштабе всей машины под Tcpip\Parameters делает то же самое. Там, где длинное имя разрешается, а голое нет, резолвер уже верен, и виноват список поиска. Исправления по порядку: отправьте DOMAIN чтобы клиент узнал суффикс, добавьте этот суффикс в список поиска адаптера или соединения и как временную меру закрепите имя в hosts, либо в LMHOSTS в Windows; обзор NetBIOS не проходит через маршрутизатор, поэтому широковещательный запрос, находящий короткое имя в офисной LAN, никогда не доходит до клиента туннеля.

block-outside-dns block-outside-dns — поведение клиента Windows, а не переносимая строка профиля, и копирование в профиль Linux или macOS не воспроизводит его там. Если в Windows публичные имена работают, а внутренние нет, сравните порядок адаптеров в Дополнительных параметрах с ipconfig /all. В macOS порядок резолверов для каждой службы принадлежит системе, поэтому используйте scutil --dns чтобы увидеть, какой резолвер спрашивается для какого домена, и относитесь к любому отдельному сообщённому исправлению профиля как к зависящему от клиента, а не общему.

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

История — третья причина. DNS-серверы или настройки суффикса из прежнего профиля могут пережить переподключения, поэтому когда адаптер выглядит правильно, а поиск всё ещё не удаётся, сравните живой адаптер с Get-VpnConnection и удалите или перезапишите устаревшую запись, прежде чем трогать сервер.

Докажите, куда ушёл запрос

Запись во время одного поиска решает спор: tcpdump -ni eth0 port 53 показывает запросы на физическом интерфейсе, то есть они уходят вне туннеля, и резолвер никогда не переключался. dig @10.8.0.1 name.corp.example затем разделяет два оставшихся случая. Если прямой запрос отвечает, резолвер работает и клиент его не использует; если истекает время, резолвер недоступен через туннель, и никакое локальное изменение не поможет.

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

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

Держите одного владельца и проверяйте по порядку

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

Замкните цикл четырьмя проверками: отправленный адрес присутствует на звене туннеля, внутреннее имя разрешается как полное квалифицированное имя, то же имя разрешается без суффикса, и оба всё ещё верны после одного переподключения. Одна запись скажет, какая из четырёх не удалась. Руководство OpenVPN 2.6 перечисляет dhcp-option и директивы скриптов с примечаниями по платформам.

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