DNS постійно повертається до попереднього стану, перепідключення VPN скасовує вашу правку, і зрештою хтось у команді пропонує заблокувати файл. Ця послідовність — симптом, а не рішення: два компоненти обидва вважають, що володіють /etc/resolv.conf, і перемагає той, хто пише останнім. Блокування файлу не вирішує конфлікт власності, воно лише приховує його і водночас ламає той компонент, який вам насправді був потрібен. Виконайте чотири перевірки нижче по порядку і виправте влаштування на тому рівні, який ним володіє, а не в самому файлі.

Перевірка 1: це символічне посилання, і куди

Почніть із самого файлу, бо шлях, який ви редагуєте, може взагалі не бути файлом. Символічне посилання в каталог часу виконання резолвера поводиться зовсім інакше, ніж звичайний файл, який переписує клієнтський скрипт:

ls -l /etc/resolv.conf
readlink -f /etc/resolv.conf
cat /etc/resolv.conf

Посилання на stub-шлях systemd-resolved означає, що вміст файлу генерується, і ручне редагування буде перезаписано під час наступної події. Звичайний файл із рядками nameserver зазвичай записує той клієнт або хук DHCP, який запускається під час підключення. Обидва варіанти законні; важливо знати, який саме у вас, перш ніж щось змінювати.

Перевірка 2: який демон працює

З'ясуйте, що насправді активне, а не що встановлене. У сучасному дистрибутиві може бути кілька резолверів, і відповідає той, який тримає порт 53 на інтерфейсі loopback:

systemctl status systemd-resolved --no-pager
resolvectl status
ss -lunp | grep ':53'

Вивід стану називає DNS-сервери для кожного посилання й домени маршрутизації, а це карта, потрібна для split DNS. Якщо внутрішні імена мають іти на внутрішній сервер, а все інше на публічний, ця політика живе в доменах кожного посилання, і зведення її до статичного списку nameserver у файлі мовчки втрачає цю різницю.

Власна конфігурація NetworkManager вирішує, який із цих бекендів він використовує. Його параметр dns= у головному файлі конфігурації вибирає між його внутрішнім резолвером, dnsmasq, systemd-resolved і none, і дистрибутив міг вибрати за вас. Прочитайте цей параметр, перш ніж вирішувати, що означає «виправити DNS» на цьому хості.

Перевірка 3: що клієнту VPN дозволено писати

Саме тут зазвичай і живе конфлікт. Клієнт VPN, який напряму переписує файл резолвера, воюватиме з будь-якою службою, яка теж його підтримує, і програє той, хто запускається першим. Нові випуски OpenVPN вміють передавати налаштування DNS до systemd-resolved замість переписування файлу — це та кооперативна поведінка, якої ви хочете; старі скрипти й написані вручну хуки часто викликають застарілий допоміжний інструмент або просто переписують файл.

Ситуація з WireGuard подібна за формою: сама конфігурація інтерфейсу не керує DNS, це роблять інструменти навколо неї — через помічник резолвера або інтеграцію з resolved. Якщо встановлено два такі помічники, обидва намагатимуться застосувати своє бачення світу під час підключення.

Читайте хуки підняття й опускання клієнта, а не здогадуйтеся. Кілька рядків shell у /etc/openvpn/up.sh або аналогічному каталозі пояснюють поведінку, яка інакше виглядає випадковою, і саме там можна змусити клієнт співпрацювати, а не змагатися.

Перевірка 4: виправляйте у власника, а не у файлі

Коли власник відомий, налаштуйте DNS через інтерфейс, який він підтримує. Для systemd-resolved це налаштування для кожного посилання й домени маршрутизації замість статичного файлу; для NetworkManager — налаштування DNS профілю підключення й вибраний бекенд; для дистрибутива з інтеграцією resolvconf — запис через цього помічника.

Не робіть файл незмінним. Атрибут незмінності зупиняє законні поновлення DHCP і оновлення VPN разом із тими, з якими ви боролися, і залишає систему в стані, коли наступне оновлення пакетів або перепідключення дає збій, який ніхто не може пояснити з конфігурації. Він приховує конфлікт власності — саме те, що ви намагалися вирішити.

Там, де два компоненти справді мають співіснувати, дайте їм різні завдання. Нехай мережевий менеджер володіє конфігурацією на рівні інтерфейсу, нехай клієнт VPN додає DNS і домени для кожного посилання через ту саму інтеграцію, а третій скрипт, який напряму пише файл, приберіть. Документація systemd-resolved описує підтримувані режими й те, що кожен із них показує в /etc/resolv.conf. Виберіть режим, що відповідає обсягу політики, який треба зберегти. Якщо split DNS важливий, stub-влаштування з доменами для кожного посилання зберігає його, а режим, що копіює вищі сервери у файл, мовчки його вирівнює.

Перевіряйте після перепідключення, а не після редагування

Файл, який виглядає правильним одразу після вашої зміни, нічого не доводить, бо наступна подія ще не відбулася. Запустіть ту послідовність, яка раніше його ламала: опустіть і підніміть тунель, поновіть оренду DHCP або перемкніть інтерфейс, а потім знову прочитайте ті самі значення.

resolvectl query build.corp.example
resolvectl query example.com
resolvectl status | head -40

Потім підтвердьте різницю, яка важлива: внутрішнє ім'я розв'язується через внутрішній сервер, а публічне ім'я досі працює. Конфігурація, що надсилає все на внутрішній сервер, виглядає добре, доки хтось не спробує вийти в інтернет через тунель, а конфігурація, що надсилає все на публічний, витікає внутрішні імена.

Запишіть власника, бекенд і режим символічного посилання в нотатках про розгортання. Цей один абзац перетворює майбутнє оновлення пакетів з інциденту на пункт перегляду і не дає наступній людині знову виявити той самий конфлікт командою chattr.

Схожі статті