DNS через VPN перехоплює кожен запит: виправте dns-priority у NetworkManager
VPN-з’єднання за замовчуванням має пріоритет 0 і претендує на кожен домен. Задайте від’ємний пріоритет для порядку, а потім поверніть решту через домени маршрутизації.
Підключіть офісний VPN, і раптом кожен запит імені йде до корпоративного resolver. Публічні імена все ще розв’язуються, тому ніщо не виглядає зламаним, доки не відмовить ім’я локального принтера або запис split-horizon не поверне адресу офісу. У деяких інсталяціях Fedora відбувається протилежне: resolver провайдера продовжує відповідати після підняття тунелю. І те, і інше — одне питання: який resolver володіє цим запитом, — і в системах NetworkManager відповідь живе у властивостях DNS кожного з’єднання.
Два з’єднання, один переможний resolver
Кожне з’єднання оголошує пріоритет DNS. Звичайні з’єднання за замовчуванням мають 50, а VPN-з’єднання — 0, і перемагає менше значення. Саме тому VPN-з’єднання тихо обганяє дротове для кожного домену, на який воно претендує: нуль перемагає п’ятдесят без чийогось вибору.
Пріоритет упорядковує кандидатів. Він не обмежує, про що питають переможця. VPN-з’єднання без домену пошуку претендує на все, тому його перевага надсилає й публічні запити в тунель, а за розділеного тунелю — туди, куди пересилає корпоративний resolver.
Пріоритет задає порядок, список пошуку — володіння
nmcli -f connection.id,ipv4.dns,ipv4.dns-search,ipv4.dns-priority con show "Corp VPN"
resolvectl status
readlink -f /etc/resolv.conf
Список пошуку — це заява про володіння. Голий домен на кшталт corp.example стає суфіксом пошуку й доменом маршрутизації. Форма лише для маршрутизації ~corp.example надсилає запити під цим суфіксом до цього з’єднання, не додаючи домен до коротких імен. Ця тильда — різниця між «спитай цей сервер» і «спитай цей сервер і допиши за мене».
Використовуйте обидві форми, коли користувачі вводять короткі імена хостів, а записи адресуються й повністю кваліфікованими іменами. Використовуйте лише форму маршрутизації, коли потрібен поділ без зміни того, як resolver доповнює голе ім’я.
Далі зробіть перевагу явною й активуйте з’єднання знову:
nmcli con modify "Corp VPN" ipv4.dns-priority -100
nmcli con modify "Corp VPN" ipv6.dns-priority -100
nmcli con modify "Corp VPN" ipv4.dns-search "~corp.example,corp.example"
nmcli con up "Corp VPN"
Від’ємний пріоритет — це документований спосіб сказати «надай перевагу цьому з’єднанню», а встановлення для обох родин адрес зберігає однакову поведінку на хості з підключенням IPv6. Зміна властивості без повторної активації з’єднання не змінює нічого з того, що працює зараз, тому послідовність завершується явною командою up.
Нехай поділ тримає systemd-resolved
Типовий плагін dnsmasq зливає запити в один локальний resolver, тому розділення за з’єднаннями лишається грубим. systemd-resolved показує поділ за кожним з’єднанням, а resolvectl query називає з’єднання, яке відповіло.
systemctl enable --now systemd-resolved
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
systemctl restart systemd-resolved NetworkManager
resolvectl query build.corp.example
Після цього корпоративне з’єднання несе corp.example, а публічний resolver обслуговує решту. Коли запит потрапляє на неправильне з’єднання, команда називає з’єднання, яке відповіло на нього, і знати це краще, ніж знати лише адресу.
Узгодьте проєкт DNS із типом тунелю
Проєкти з приватністю, що надсилають усе через тунель, не повинні мати список поділу, бо він повернув би публічні імена локальному resolver і скасував задум. Проєктам із розділеним тунелем він потрібен: без нього корпоративний resolver бачить кожен публічний запит, і налаштування ламається тієї миті, коли тунель падає.
Далі є kill switch, який блокує DNS поза тунелем. Імена розв’язуються для зон тунелю й зазнають невдачі скрізь інде, хоча з’єднання цілком справне. Робочі відповіді — явний дозвіл для resolver у LAN або локальний кеш, що пересилає лише корпоративну зону, і кожен із них є винятком із власником, а не дефектом тунелю.
Профіль, який під час запуску інтерфейсу переписує конфігурацію resolver, поводиться майже так само: щойно локальний resolver стає недоступним, розв’язуються лише імена, відомі тунелю. Який би механізм не діяв, запишіть, які імена мають працювати в кожному стані, і передайте цей список тому, хто опрацьовує звіти.
Перевірте за з’єднаннями, а потім ще раз після повторного підключення
Запитайте одне внутрішнє й одне публічне ім’я та подивіться, куди запит справді йде. Сторінка перевірки витоків каже, який resolver відповів, а не яке з’єднання обрала система, тому вона нічого не каже про порядок, який ви щойно налаштували.
Запустіть обидва запити знову після відключення й повторного підключення. Пріоритети застосовуються наново, коли з’єднання активується, а старе символьне посилання може пережити оновлення, про яке ніхто не пам’ятає. Наприкінці ви хочете записати, який resolver володіє яким суфіксом, плюс перевірку, що буде чинною й завтра.