Редагування resolv.conf не виправляє DNS після відключення VPN
Мертвий резолвер тунелю на початку списку коштує одного тайм-ауту на кожен запит. Перевірте, кому належить файл, скиньте стан з’єднання і припиніть редагувати згенерований вивід.
Ви відключаєте VPN, ping 1.1.1.1 усе ще відповідає, і кожен запит імені зависає, доки сторінка нарешті не здасться. Потім cat /etc/resolv.conf показує сервер імен, який коли-небудь існував лише всередині тунелю, зазвичай першим у списку. Видалення цього рядка ніби виправляє проблему хвилин на десять, доки призупинення, роумінг Wi-Fi або перезавантаження не повернуть його. Файл, який ви редагували, — не налаштування; це відображення стану з’єднання, яким володіє інший компонент.
Чому один застарілий запис коштує секунд на кожен запит
Резолвер glibc проходить список серверів імен по порядку і вичікує тайм-аут, перш ніж спробувати наступний, а resolv.conf(5) обмежує цей список трьома записами. Поставте резолвер з боку тунелю, наприклад 10.8.0.1, на початок після того, як тунель зник, і кожен запит заплатить тайм-аутом, перш ніж перейти до сервера, який відповідає. Тому симптом виглядає як мертве з’єднання, а не як помилка DNS: браузери блокуються, виходять за часом і іноді віддають кешовану адресу, яка згодом застаріває.
Це також пояснює, чому скарга приходить як «інтернет зламався». Ping до IP-адреси доводить, що з’єднання в порядку, і через це збій виглядає як проблема застосунку. Список резолверів — це перше, що треба прочитати, і останнє, що треба редагувати.
Міф: resolv.conf — це файл налаштувань
Запитайте, чим насправді є цей шлях, перш ніж його змінювати:
ls -l /etc/resolv.conf
readlink -f /etc/resolv.conf
На хості з systemd-resolved це символічне посилання на stub-файл, що вказує на 127.0.0.53, а справжні сервери живуть у стані за кожним з’єднанням, який друкує resolvectl. На хості з NetworkManager це може бути файл, який NetworkManager записує з активного з’єднання. У деяких клієнтах виробників це звичайний файл, який перезаписується на місці під час підключення і, якщо вам не пощастило, ніколи не відновлюється під час відключення. Це три різні власники, і редагування перших двох вручну або нічого не робить, або тримається до наступної мережевої події.
resolvectl status — це подання, яке говорить правду: DNS-сервери за кожним з’єднанням, домени маршрутизації і чи існує ще з’єднання тунелю. resolvectl query example.com іде далі й показує, який інтерфейс відповів. Використовуйте обидва, перш ніж торкатися файлу, і пам’ятайте, що браузер із власним захищеним DNS усе це ігнорує.
Знайдіть власника, перш ніж щось редагувати
Зазвичай три компоненти змагаються за одне й те саме налаштування: systemd-resolved, NetworkManager і те, що встановив клієнт VPN. Спершу визначте живий:
systemctl is-active systemd-resolved
nmcli connection show --active
ps aux | grep -E "openvpn|wg-quick|vpn"
Якщо resolved активний і символічне посилання вказує на його stub, глобальний файл є згенерованим виводом, і ваше редагування косметичне. Якщо з’єднанням володіє NetworkManager, сервери належать профілю з’єднання, тож виправлення — це зміна властивості через nmcli, а не редагування файлу. Якщо працює демон виробника, наступне підключення переживе лише його власний шлях відновлення.
Приберіть стан з’єднання, який залишив клієнт
Убитий клієнт не може виконати свій хук очищення. SIGKILL взагалі неможливо перехопити, а SIGINT і SIGTERM можна, тому тунель, який «просто зупинився» після примусового вбивства, часто залишає на місці і реєстрацію інтерфейсу, і запис резолвера. Знайдіть конкретний PID і надішліть сигнал лише йому:
ps aux | grep -E "openvpn|wg-quick"
sudo kill <pid>
resolvectl revert tun0
Не хапайтеся за pkill -f vpn або killall vpn, доки не прочитали повний список збігів. -f зіставляє весь командний рядок, тому може завершити скрипт-обгортку, сеанс редактора або сторонній процес, у шляху якого є цей рядок. Завершення не того процесу посеред роботи — це спосіб, яким проблема резолвера перетворюється на втрачений файл.
resolvectl revert скидає конфігурацію DNS часу виконання цього з’єднання, що вужче, ніж перезапуск резолвера, і набагато вужче, ніж редагування глобального файлу. Якщо з’єднання тунелю зникло повністю, systemctl restart NetworkManager перебудовує стан з’єднання, і це той крок, до якого постійно повертаються нитки джерел. Стежте за менеджером служб із Restart=always, бо він може повернути вбитого клієнта та його налаштування DNS просто назад.
Інший напрямок: проштовхнутий DNS, який так і не прийшов
Дзеркальне відображення застарілого запису — це тунель без жодного придатного резолвера. Опція DNS у профілі — це запит; компонент, що керує з’єднанням, має передати його резолверу. Якщо журнал показує, що сервер отримано, але з’єднання тунелю не несе жодних налаштувань DNS, бракує інтеграції, а не сервера.
Перевірте передачу, виконавши її вручну; це відокремлює «сервер неправильний» від «ніхто його не застосував»:
resolvectl dns tun0 10.10.10.10
resolvectl domain tun0 ~.
Домен маршрутизації, що перехоплює все, надсилає кожне ім’я на це з’єднання, чого хоче клієнт повного тунелю і що не повинен використовувати розділений DNS. Ці налаштування зникають під час наступного підключення. Щоб зробити їх постійними в NetworkManager, вимкніть автоматичний DNS, задайте сервер на з’єднанні та додайте домен:
nmcli connection modify office ipv4.ignore-auto-dns yes
nmcli connection modify office ipv4.dns 10.10.10.10
nmcli connection modify office ipv4.dns-search "~."
Для корпоративного тунелю, який має відповідати лише на внутрішні імена, перелічіть ці зони з провідною тильдою замість перехоплення всього, щоб публічні імена далі використовували локальний резолвер.
Обхідні шляхи, що стають наступною аварією
Копіювати resolv.conf перед підключенням і відновлювати після — законний рядок у runbook, і це обхідний шлях, а не ремонт. Він відмовляє саме тоді, коли це важливо, бо падіння або примусове перезавантаження пропускають відновлення. Запишіть це як обхідний шлях, щоб наступна людина не будувала на ньому.
Вимкнення systemd-resolved і жорстко прописані публічні сервери — другий популярний хід. Він робить підключення й відключення передбачуваними та прибирає DNS за кожним з’єднанням для всіх інших мереж, що ламає розділений DNS для внутрішніх імен і зводить нанівець сенс тунелю, призначеного тримати запити всередині. Встановлення resolvconf і закріплення публічних серверів коштує того ж із додатковим шаром. Ставтеся до будь-якого з них як до діагностики: якщо він повертає перегляд, ви дізналися, що винна інтеграція резолвера, а не те, що публічні сервери правильні.
Довготривале виправлення — один власник на шар: вирішіть, який компонент володіє DNS з’єднання тунелю, а який — глобальним значенням за замовчуванням, запишіть це й приберіть інших із шляху. Потім перевірте після відключення іменем, яке вирішує лише VPN. Якщо приватне ім’я все ще відповідає, реєстрацію не було видалено; якщо нічого не вирішується, файл указує на сервер, якого вже немає. І те, і те видно в resolvectl, перш ніж ви відкриєте браузер.