DNS через VPN працює, але імена .local усе ще не розв'язуються: хто їх розв'язує?
Ім'я .local може повністю обійти резолвер VPN. Порівняйте три шляхи резолвера, а потім оголосіть домен замість перестановки nsswitch.
Дві машини в одній VPN, те саме ім'я хоста, і розв'язується воно лише на одній: різниця зазвичай не в тунелі, а в тому, який резолвер відповів. На робочому столі Linux це ім'я може пройти через перемикач служб імен, через stub systemd-resolved або через резолвер, який застосунок приніс із собою, і кожен із них застосовує своє правило до того самого суфікса. Саме на суфіксі правила розходяться, тому що .local не є нейтральною міткою. З'ясуйте, який шлях насправді проходить збійна програма, перш ніж змінювати порядок, у якому щось запускається.
Два резолвери, дві різні відповіді
Традиційний пошук glibc проходить рядком hosts: у nsswitch.conf і опитує кожен модуль по черзі, доки один не відповість. Клієнт, який спілкується з systemd-resolved через stub-слухач, натомість питає один процес, і цей процес застосовує політику для кожного з'єднання плюс свої особливі випадки. Застосунок, який приносить власний резолвер або лінкує бібліотеку, що це робить, може обійти обидва. Тож одне ім'я хоста може мати трьох власників на одній машині, і лише один із них знає, що мав на увазі VPN.
Визначте власника, перш ніж щось змінювати, бо виправлення для кожного з трьох різне. Браузер та інструмент командного рядка на одному робочому столі можуть законно розходитися, і ця розбіжність — підказка, а не помилка. Якщо браузер розв'язує ім'я, а інструмент ні, ви налагоджуєте шлях резолвера, а не маршрут VPN. Підтвердьте маршрут окремо, щоб збій маршрутизації не було сприйнято за збій служби імен. Коли обидва згодні, збій вище хоста, і тутешня конфігурація резолвера не варта ще однієї правки.
Яка команда справді запитала ваш резолвер
Дві команди лише для читання відповідають на пов'язані питання, і їхнє порівняння локалізує проблему швидше, ніж читання конфігурації. Використовуйте справжнє внутрішнє ім'я і тримайте вивід приватним, бо внутрішні записи залишаються внутрішніми. Запустіть обидві в тій самій сесії, у якій працює збійна програма:
getent ahosts files.corp.local
resolvectl query files.corp.local
resolvectl statusПерша питає через налаштовані модулі, що й відчуває типова програма. Друга питає безпосередньо systemd-resolved і повідомляє про з'єднання, протокол і сервер, який відповів. Запит до корпоративного сервера за адресою доводить лише те, що сервер має запис, бо він нічого не каже про те, чи питав його застосунок. Прочитайте з'єднання, яке несе VPN, і домени, які воно заявляє, а потім порівняйте цей список із суфіксом у збійному імені.
Чому .local обходить вашу зону unicast
довідка systemd-resolved зазначає, що багатоскладові імена, які закінчуються на .local, коли mDNS увімкнено, зазвичай ідуть до multicast DNS, а не до звичайного unicast DNS. RFC 6762 відводить цей простір імен для link-local multicast, тож корпоративна зона може мати правильний запис, про який для цього суфікса ніколи не питають. Тунель може ідеально маршрутизувати резолвер і все одно програти гонку. Успішний ping із кешу нічого не каже про пошук, що щойно відбувся.
Є задокументований виняток, і він вирішує більшість таких випадків: коли з'єднання оголошує цей суфікс як домен пошуку або домен маршрутизації, демон тримає його на шляху unicast і пропускає особливий випадок multicast. Це політика для кожного з'єднання, а не глобальна перевага. Дві машини з тим самим сервером VPN можуть поводитися по-різному, коли один мережевий профіль оголошує домен, а інший ні, тож читайте активний профіль, а не той, який, як вам здається, ви редагували.
Вузький виняток перемагає глобальну перестановку
Для наявної зони, яку ви не можете перейменувати, попросіть власників резолвера й VPN оголосити домен на тому з'єднанні, яке його несе. Запис домену маршрутизації для цього одного суфікса плюс потрібна адреса сервера — невелика зміна з названим власником, і вона живе разом із з'єднанням, а не у файлі, відредагованому вручну.
Воно переживає і відключення, бо політика з'єднання застосовується знову, коли з'єднання повертається. Правка спільного nsswitch.conf — спокуслива і дорожча альтернатива, бо вона змінює поведінку пошуку для кожного імені на машині, включно з локальним виявленням. Вимкнення демона multicast теж не є еквівалентом: воно прибирає локальну поведінку, не навчаючи жоден резолвер корпоративної зони. Якщо служба нова, а не успадкована, розмістіть її в піддомені, який контролює ваша організація, і повністю пропустіть конкуренцію. Виберіть вузький виняток, коли ім'я зафіксоване в прошивці або надруковане на етикетці, і новий піддомен, коли ви ще контролюєте клієнт.
Що довести після зміни
Доведіть виправлення власним пошуком застосунку, а не інструментом, який ви встановили для тестування, і очистіть будь-який кеш, що міг би відповісти замість нього. Потім підтвердьте шлях резолвера і з'єднання, яке дало відповідь. Насамкінець перевірте, що локальне виявлення поводиться як до зміни, бо принтер, який перестає з'являтися, — це та частина, яку люди помічають найпізніше. Ці три команди перевіряють ім'я, шлях і ідентичність TLS саме в цьому порядку:
getent ahosts files.corp.local
resolvectl query files.corp.local
curl -sv --max-time 5 https://files.corp.local/ 2>&1 | head -n 20Правильна адреса з неправильним сертифікатом усе одно провалює суворого клієнта, тож перевірте ім'я, яке очікує застосунок, коли розв'язання запрацює. Підтвердьте, що служба приймає з'єднання з адреси VPN, а не лише з офісного діапазону. Запишіть обсяг домену, сервер і власника в документацію з'єднання. Інакше наступна людина, яка зіткнеться з цим збоєм, потягнеться до тієї самої глобальної правки, якої ви щойно уникли.