Журнал показує параметр, який проштовхнув сервер, тунель піднято, а внутрішні імена все одно не розв'язуються. Прямий запит до резолвера відповідає, отже сервер гаразд, але кожен застосунок далі питає локальний маршрутизатор. Те, що дійшло до клієнта, є пропозицією, а не зміною в резолвері, і компонент, який володіє розв'язанням імен, різниться в 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 і директиви скриптів із примітками про платформи.

Схожі статті