WSL2 втратив DNS після підключення VPN? Дві причини
Застарілий файл resolver і конкуруюча метрика маршруту дають однаковий симптом усередині WSL2. Зафіксуйте обидві сторони, а потім виправте ту, що справді зламана.
Ping за адресою працює всередині дистрибутива, встановлення пакетів і завантаження git не працюють, а збій з’явився одразу після підняття тунелю. Перестали розв’язуватися лише імена, що вказує на DNS, а не на зв’язність. Перевстановлення пакетів це найпопулярніший хибний перший крок тут. WSL2 має два незалежні способи дати саме такий симптом, і вони потребують різного виправлення.
Чому дистрибутив тримає власний resolver
DNS-клієнт Windows не використовується всередині дистрибутива. WSL2 під час запуску будує власний файл resolver, що вказує на stub-адресу, яку Windows публікує на віртуальному комутаторі для допоміжної віртуальної машини.
Ця схема стабільна за звичайних змін мережі, бо записується один раз і використовується повторно. Схема перестає бути правильною, коли клієнт тунелю переписує список адаптерів хоста після того, як допоміжна віртуальна машина вже запущена.
Ніщо всередині дистрибутива не стежить за зміною, тому файл продовжує вказувати на адресу, якої може вже не бути на шляху. Наступний запит тоді чекає, завершується за тайм-аутом або отримує відповідь від сервера, який ніколи не чув про внутрішню зону. Зсередини resolver просто перестає відповідати, і всі імена падають одночасно.
Спершу зберіть докази з обох боків
Зафіксуйте, що бачить дистрибутив, а потім що бачить Windows, перш ніж щось змінювати. Саме два види разом розрізняють режими відмови.
Усередині дистрибутива виведіть файл resolver, таблицю маршрутизації та один внутрішній і один публічний запит:
ip -4 route
cat /etc/resolv.conf
getent hosts intranet.corp.example
getent hosts example.comУ Windows перелічіть DNS-сервери за адаптерами й таблицю IPv4 з метриками. Клієнт VPN зазвичай встановлює маршрут для підмережі WSL2, і його метрика вирішує, чи цей трафік піде через тунель, чи залишиться локальним.
Get-NetAdapter | Get-DnsClientServerAddress
route print -4
Метрика маршруту чи застарілий файл
Перша відмова це застарілий файл. Resolver було написано для стану адаптера на момент запуску, а тунель змінив цей стан. Його stub-адреса тепер може бути недосяжною або вказувати на сервер, який нічого не знає про внутрішню зону.
Друга це проблема маршрутизації. Коли VPN додає маршрут, що покриває підмережу WSL2, з метрикою нижчою за маршрут зв’язку хоста, пакети, адресовані допоміжній віртуальній машині, потрапляють у тунель. Тоді тайм-аут настає в кожної служби WSL2, а не лише в DNS.
Розрізнювальний тест коштує одного рядка. Якщо числова адреса, наприклад публічний resolver, досі відповідає на ping, поки імена падають, шлях цілий і проблема в DNS. Це випадок, коли зміна resolver виправдана, і випадок, коли ні, теж стає очевидним. Якщо числовий тест також не проходить, допоміжна віртуальна машина втратила свій маршрут, і жоден файл resolver цього не виправить.
Для випадку маршрутизації зніміть автоматичну метрику з адаптера тунелю і задайте йому число вище за маршрут зв’язку WSL2:
Get-NetAdapter | Where-Object InterfaceDescription -Match VPN | Set-NetIPInterface -InterfaceMetric 5500
wsl.exe --shutdown
Вимкнення важливе. Зміна метрики не переписує працюючу допоміжну віртуальну машину, тому дистрибутив треба перезібрати, перш ніж зміна стане видимою.
Візьміть файл на себе, свідомо
Якщо маршрутизація правильна і падають лише внутрішні імена, винен resolver, і ви можете зупинити генератор. Це свідома зміна з витратами на обслуговування, а не обхідний шлях, який застосовують недбало.
Створіть /etc/wsl.conf усередині дистрибутива з мережевою секцією, що вимикає генерацію, а потім самі напишіть файл resolver: спочатку корпоративний сервер, потім публічний резервний:
[network]
generateResolvConf = falsesearch corp.example
nameserver 10.88.4.53
nameserver 9.9.9.9
Порядок важливий. Публічний resolver не може відповісти на внутрішнє ім’я, а резерв існує лише для інтернет-запитів. Щойно файл ваш, ніщо його не перегенеровує, тому корпоративний resolver, що переїжджає, стає збоєм, який ви маєте помітити самі.
Перевірте імена, потім пакети
Перевірте одне внутрішнє і одне публічне ім’я системним resolver, а потім повторіть операцію, що не вдалася. Менеджери пакетів іноді використовують власний resolver, тому робочий getent може співіснувати зі зламаним встановленням.
Якщо ви автоматизуєте перезапис, зробіть його ідемпотентним: без тунелю зберігайте наявний файл замість запису порожнього списку серверів.
getent hosts intranet.corp.example
resolvectl status | head -20
getent hosts example.com
Робочий внутрішній запит і робочий публічний запит зсередини дистрибутива це результат, який варто зафіксувати. Зелений значок VPN на хості не доводить ні того, ні іншого.