Ви відкриваєте WSL2, запускаєте apt update, і воно просто… зависає. Або збоять завантаження Docker. Або ваш внутрішній
віддалений Git зникає, якщо VPN не «саме такий». Ви дивитесь у /etc/resolv.conf, він виглядає
правдоподібно, але DNS поводиться так, ніби вступає в переговори про профспілку.
Ось історія DNS у WSL2: Windows мережі, легкий VM, VPN‑клієнти з власною думкою та файл
(resolv.conf), який WSL2 переписує, коли ви не дивитесь. Виправлення не в тому, щоб «відредагувати файл».
Виправлення — змусити WSL2 припинити його перезаписувати, а потім обрати стратегію DNS, що відповідає вашій реальності і переживе перезавантаження.
Що насправді відбувається, коли WSL2 «втрачає DNS»
WSL2 — це не шар сумісності. Це справжнє ядро Linux, що працює в керованій віртуальній машині.
Ваш дистрибутив отримує віртуальний мережевий інтерфейс на приватному vSwitch; Windows знаходиться з іншого боку і виконує роль «каналу в інтернет».
DNS всередині WSL2 за замовчуванням — це ланцюжок довіри:
- Linux‑додатки викликають libc resolver (або systemd‑resolved, залежно від конфігурації дистрибутива).
- Резолвер читає
/etc/resolv.conf(безпосередньо або опосередковано). - За замовчуванням WSL2 авто‑генерує
/etc/resolv.confпід час завантаження з уявлення Windows про DNS. - Уявлення Windows про DNS змінюється, коли ви підключаєтесь до Wi‑Fi, переключаєте мережі, підключаєте/відключаєте VPN або отримуєте нову DHCP‑оренду.
- Деякі VPN встановлюють DNS‑проксі, правила split DNS або політики NRPT, і Windows охоче їх застосовує.
- WSL2 може не оновлювати згенерований конфіг на льоту так, як ви інтуїтивно очікуєте.
Коли щось ламається, зазвичай це одне з наступного:
- Застаріла IP‑адреса DNS‑сервера у
/etc/resolv.conf(поширено після сну, перемикання VPN, зміни мережі). - Недоступний DNS‑сервер, бо DNS на боці Windows — локальний проксі, з яким WSL2 не може спілкуватись.
- Несумісність split‑horizon: Windows знає, як вирішувати внутрішні домени через політики; WSL2 — ні.
- Дивакуватість IPv6: Windows віддає перевагу IPv6 DNS, WSL2‑резолвер — IPv4, або навпаки.
- Пошкоджені search‑домені: ви покладаєтесь на короткі імена (
git,jenkins), які потребують суфіксуsearch. - Змагання резолвера / кешування: локальний резолвер кешує неправильні записи і здається, що мережа зачаклована.
Редагування /etc/resolv.conf «працює» до перезавантаження, тому що WSL2 його перезаписує. Це не баг.
Це поведінка за замовчуванням: Windows — джерело істини, якщо ви явно не берете контроль.
Голі факти: DNS — це залежність, про яку ви забуваєте, поки вона не ламається, а тоді ламає все.
Виправлення нудне. І нудне — це добре.
Цікаві факти й історичний контекст (те, що пояснює біль)
- resolv.conf існує десятиліттями: формат файлу походить від ранніх реалізацій резолвера Unix і вижив, бо все на ньому залежить.
- WSL1 і WSL2 принципово різні: WSL1 транслював системні виклики Linux; WSL2 запускає справжнє ядро в VM, що радикально змінює мережеву поведінку.
- WSL2 спочатку використовував модель NAT: він ізольований за віртуальним свічем, тож Windows фактично виступає шлюзом і часто «радником» DNS.
- systemd не завжди був увімкнений у WSL: старі дистрибутиви WSL працювали без systemd, тож поведінка DNS залежала від дистро‑дефолтів і скриптів.
- Корпоративний Windows DNS може керуватися політиками: Windows підтримує політики розв’язування і поведінку для конкретних доменів, що важко відтворити у гості Linux без додаткових налаштувань.
- search‑домени — це спадкова зручність: короткі імена залежать від правил
search; це також часте джерело «працює на моєму ноуті» помилок. - VPN‑клієнти часто впроваджують захист DNS: багато з них проконсольовують DNS через тунель, щоб уникнути витоку, що робить гостьові VM виглядати як недовірені зовнішні клієнти.
- Кешування DNS змінило очікування: сучасні стеки агресивно кешують (systemd‑resolved, nscd, кеш браузера). Ви можете виправити DNS і все одно бачити застарілі результати.
- Windows і Linux віддають перевагу різним підходам: Windows опирається на системні служби й політики; Linux очікує явних серверів у
resolv.conf. WSL2 опиняється між ними.
Швидкий план діагностики (перший/другий/третій)
Коли в продукції пожежа, ви не «досліджуєте». Ви бісектуєте. Ось найшвидший шлях до правди.
Перший: це DNS, маршрутизація чи додаток?
- Перевірте доступність по IP (ping шлюз / відома IP‑адреса).
- Перевірте резолюцію DNS для публічного домену та внутрішнього домену.
- Порівняйте розв’язування Windows і WSL2.
Другий: чи WSL2 використовує застарілий або недоступний nameserver?
- Прочитайте
/etc/resolv.conf. - Спробуйте зв’язатися з IP nameserver на порті 53 (тести UDP/TCP).
- Перевірте, чи є nameserver адресою локального Windows‑проксі, до якої WSL2 не може дістатись.
Третій: це split DNS / VPN‑політика?
- Розв’яжіть внутрішні імена за допомогою інструментів Windows і порівняйте.
- Перевірте search‑домени та очікування для конкретних доменів.
- Прийміть рішення: чи потрібно запускати локальний резолвер у WSL2, чи можна вказати безпосередньо корпоративні резолвери?
Правило прийняття рішення: якщо nameserver у /etc/resolv.conf недоступний або застарілий, припиніть боротися з симптомами.
Візьміть контроль над тим, як генерується resolv.conf. Це важіль.
Практичні завдання: команди, очікуваний вивід і рішення
Це ті перевірки, які я реально виконую. Не тому, що люблю набирати, а тому, що гадання дороге.
Кожне завдання містить: команду, що означає вивід, і яке рішення він дає.
Завдання 1: Підтвердіть, що ви справді в WSL2 (не WSL1)
cr0x@server:~$ uname -r
5.15.133.1-microsoft-standard-WSL2
Значення: Якщо бачите microsoft-standard-WSL2, ви в WSL2.
WSL1 поводиться інакше і не має тих самих мережевих нюансів VM.
Рішення: Якщо ви не в WSL2, зупиніться і підлаштуйте очікування; ця стаття орієнтована на WSL2.
Завдання 2: Перевірте поточну конфігурацію резолвера
cr0x@server:~$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 172.26.112.1
search corp.example
Значення: Цей коментар каже, що WSL авто‑генерує файл. Nameserver часто — віртуальна адреса шлюзу.
Рішення: Якщо DNS ламається після перезавантажень або перемикань VPN, вам потрібно вимкнути генерацію і взяти файл під свій контроль.
Завдання 3: Швидко розв’яжіть публічне ім’я (чи взагалі DNS працює?)
cr0x@server:~$ getent ahosts example.com | head
93.184.216.34 STREAM example.com
93.184.216.34 DGRAM
93.184.216.34 RAW
Значення: getent тестує системний шлях резолвера (NSS), а не лише конкретний інструмент.
Рішення: Якщо це не вдається, DNS загалом зламаний. Якщо працює, але внутрішні імена — ні, думайте про split DNS / search‑домени.
Завдання 4: Підтвердіть, що внутрішнє ім’я падає так, як ви думаєте
cr0x@server:~$ getent hosts git
Значення: Відсутній вивід зазвичай означає «не розв’язано», а не «мережа впала».
Рішення: Якщо git не працює, але git.corp.example працює, у вас відсутній/невірний рядок search.
Завдання 5: Використайте dig, щоб побачити думку резолвера (таймаути vs NXDOMAIN)
cr0x@server:~$ dig +time=2 +tries=1 git.corp.example
; <<>> DiG 9.18.24-1ubuntu1.4-Ubuntu <<>> +time=2 +tries=1 git.corp.example
;; connection timed out; no servers could be reached
Значення: Таймаут означає, що ви не можете дістатись налаштованих DNS‑серверів. Це відрізняється від NXDOMAIN.
Рішення: Таймаути підштовхують до думки «nameserver недоступний/застарілий». NXDOMAIN вказує на «невірний DNS‑сервер для цього домену».
Завдання 6: Визначте IP‑адресу nameserver, який використовує WSL2
cr0x@server:~$ awk '/^nameserver/{print $2}' /etc/resolv.conf
172.26.112.1
Значення: Вам потрібна точна IP‑адреса для тестування підключення.
Рішення: Якщо це приватна адреса 172/10/192, вона ймовірно є шлюзом WSL2/Windows або резолвером на боці VPN.
Завдання 7: Протестуйте підключення до DNS‑сервера (UDP і TCP)
cr0x@server:~$ NS=$(awk '/^nameserver/{print $2; exit}' /etc/resolv.conf); echo $NS
172.26.112.1
cr0x@server:~$ nc -vz -w2 $NS 53
nc: connect to 172.26.112.1 port 53 (tcp) failed: Connection timed out
Значення: Таймаут TCP 53 — сильна підказка, що сервер недосяжний з гостя.
UDP тестувати складніше за допомогою nc, але TCP‑провал уже має поганий запах.
Рішення: Якщо порт 53 недоступний, припиніть ганятися за налаштуваннями резолвера в додатках. Виправляйте шлях до DNS.
Завдання 8: Перевірте базову маршрутизацію (це DNS чи мережа?)
cr0x@server:~$ ip route
default via 172.26.112.1 dev eth0
172.26.112.0/20 dev eth0 proto kernel scope link src 172.26.121.45
Значення: Маршрут за замовчуванням через той самий IP, що й ваш nameserver, — звично для WSL2. Якщо цього маршруту немає, у вас проблеми серйозніші за DNS.
Рішення: Якщо маршрутизація зламана, перезапуск WSL або мережевого стека — крок нуль.
Завдання 9: Перевірте наявність systemd-resolved і як він підключений
cr0x@server:~$ ps -ef | grep -E 'systemd-resolved|named|dnsmasq' | grep -v grep
root 330 1 0 09:12 ? 00:00:00 /lib/systemd/systemd-resolved
Значення: Якщо systemd-resolved працює, ваш резолвер може не читати /etc/resolv.conf так, як ви думаєте.
Рішення: Вирішіть, чи використовувати systemd‑resolved правильно (рекомендовано для split DNS), або спростити з статичним resolv.conf.
Завдання 10: Перевірте, чи /etc/resolv.conf — файл чи символічне посилання
cr0x@server:~$ ls -l /etc/resolv.conf
-rw-r--r-- 1 root root 188 Feb 5 09:40 /etc/resolv.conf
Значення: Якщо це сим‑посилання на stub systemd, ви будете усувати проблему інакше.
Рішення: Звичайний файл означає, що WSL його створив (або ви). Сим‑посилання часто означає, що systemd‑resolved ним володіє.
Завдання 11: Порівняйте поведінку DNS у Windows (з середини WSL)
cr0x@server:~$ cat /etc/resolv.conf | sed -n '1,5p'
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 172.26.112.1
Значення: Ми не запускаємо PowerShell у цьому блоці через формат, але можна зробити висновок:
якщо Windows використовує DNS‑проксі (поширено з VPN), WSL може вказувати на щось, до чого тільки Windows має надійний доступ.
Рішення: Якщо задіяний корпоративний VPN, плануйте стабільну явну конфігурацію DNS.
Завдання 12: Чисто перезапустіть WSL2 (примусова генерація тестів)
cr0x@server:~$ wsl.exe --shutdown
The operation completed successfully.
Значення: Це вимикає всі інстанси WSL. Наступний запуск — холодний старт.
Рішення: Використовуйте це як тест «вціліло моє виправлення після перезавантаження?».
Завдання 13: Доведіть, що файл перезаписується (перед тим, як вимкнути генерацію)
cr0x@server:~$ sudo sh -c 'echo "# test-marker" >> /etc/resolv.conf'
cr0x@server:~$ tail -n 3 /etc/resolv.conf
search corp.example
# test-marker
Значення: Тепер вимкніть WSL і перезапустіть. Якщо маркер зникає, WSL його регенерував.
Рішення: Якщо файл перезаписується, ви мусите вимкнути генерацію. Все інше — театральність.
Завдання 14: Перевірте, що DNS працює після зміни резолверів
cr0x@server:~$ dig +short example.com
93.184.216.34
cr0x@server:~$ dig +short git.corp.example
10.40.12.23
Значення: Ви хочете, щоб і публічне, і внутрішнє розв’язування успішно працювали послідовно.
Рішення: Якщо публічне працює, але внутрішнє — ні, ваш вибір DNS‑серверів невірний для потреб split‑horizon.
Одна цитата, щоб зберегти тверезість: «Надія — не стратегія» — часто приписується оперційній культурі (парафразована ідея).
Налагодження DNS — саме те місце, де «надія» з’являється у вигляді «може, після підключення VPN пройде».
Виправлення resolv.conf, що витримує перезавантаження (рекомендовані шляхи)
Існують три робочі стратегії. Оберіть одну. Змішування їх створює «інколи» систему, а «інколи» — найгірший SLA.
Стратегія A (рекомендовано більшості): Вимкнути авто‑генерацію і записати статичний resolv.conf
Це найпростіше виправлення, коли ви можете вказати безпосередньо стабільні DNS‑сервери (публічні резолвери, ваш роутер або корпоративні резолвери, доступні в поточній мережі/VPN).
Воно також витримає перезавантаження, бо ви забороняєте WSL перезаписувати файл.
Крок 1: Зупиніть генерування resolv.conf WSL
cr0x@server:~$ sudo tee /etc/wsl.conf >/dev/null <<'EOF'
[network]
generateResolvConf = false
EOF
Значення: WSL читає /etc/wsl.conf під час старту інстансу. Це каже йому лишити /etc/resolv.conf недоторканим.
Рішення: Якщо вам потрібна стабільність більше, ніж «авто‑підлаштування під випадкові мережі», це ваш хід.
Крок 2: Створіть власний resolv.conf
cr0x@server:~$ sudo rm -f /etc/resolv.conf
cr0x@server:~$ sudo tee /etc/resolv.conf >/dev/null <<'EOF'
nameserver 10.10.0.53
nameserver 10.10.0.54
search corp.example
options timeout:2 attempts:2 rotate
EOF
cr0x@server:~$ sudo chmod 644 /etc/resolv.conf
Значення: Два nameserver’и, search‑домен і консервативні таймаути, щоб відмови відбувалися швидко, а не гальмували збірки.
Рішення: Якщо у вас немає стабільних внутрішніх DNS IP, не гадіть. Отримайте їх у мережевої/VPN‑команди або з деталей адаптера Windows.
Крок 3: Перезапустіть WSL для застосування
cr0x@server:~$ wsl.exe --shutdown
The operation completed successfully.
Запустіть дистро знову і перевірте розв’язування (Завдання 14). Якщо воно витримує кілька перезапусків — ви в цілі.
Жарт №1: DNS як офісна кава — ніхто її нормально не фінансує, поки вона не пропаде, і тоді це всінагорі пріоритет.
Стратегія B: Використати systemd-resolved у WSL2 для split DNS (коли важливі корпоративні правила VPN)
Якщо у вас split‑horizon DNS (внутрішні домени мають йти на внутрішні резолвери, все інше — публічно),
статичний resolv.conf може бути занадто грубим інструментом. systemd‑resolved може керувати маршрутизацією за доменами правильно.
Але його треба правильно підключити, інакше отримаєте гірше з обох світів: кешування плюс невірні сервери.
Загальний підхід:
- Вимкнути генерацію resolv.conf у WSL.
- Зробити
/etc/resolv.confвказівкою на systemd‑stub (127.0.0.53) або на файл, яким управляє resolved. - Сконфігурувати systemd‑resolved з правильними DNS‑серверами і routing‑доменами.
Крок 1: Підтвердіть, що systemd доступний/активний
cr0x@server:~$ ps -p 1 -o comm=
systemd
Значення: PID 1 — systemd. Якщо ні, ввімкнення resolved — інша розмова.
Рішення: Якщо systemd не працює, віддайте перевагу Стратегії A, якщо ви не готові переналаштовувати дистро.
Крок 2: Налаштуйте resolved
cr0x@server:~$ sudo tee /etc/systemd/resolved.conf >/dev/null <<'EOF'
[Resolve]
DNS=10.10.0.53 10.10.0.54
FallbackDNS=1.1.1.1 8.8.8.8
Domains=~corp.example corp.example
DNSSEC=no
EOF
cr0x@server:~$ sudo systemctl restart systemd-resolved
Значення: Domains=~corp.example робить зону маршрутизованою: запити для цього простору йдуть на корпоративні DNS.
Простий corp.example задає search‑домен для зручності.
Рішення: Використовуйте це, коли ваш VPN вимагає, щоб внутрішні імена розв’язувались внутрішньо, але публічний DNS мав бути швидким.
Крок 3: Вкажіть /etc/resolv.conf на resolved
cr0x@server:~$ sudo rm -f /etc/resolv.conf
cr0x@server:~$ sudo ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
cr0x@server:~$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Feb 5 10:02 /etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf
Значення: Додатки читають /etc/resolv.conf, звертаються на 127.0.0.53, і resolved приймає розумні рішення.
Рішення: Якщо бачите дивне кешування, тепер ви знаєте, де воно живе (resolved), і можете його очистити.
Стратегія C: Зробити resolv.conf незмінним (ефективно, але не дуже рекомендую)
Так, можна поставити chattr +i на /etc/resolv.conf. Це зупинить перезапис навіть якщо ви забудете wsl.conf.
Це також підстереження: майбутній ви (або автоматизація) не зможе оновити DNS і витратить час на дебаг прав доступу.
cr0x@server:~$ sudo chattr +i /etc/resolv.conf
cr0x@server:~$ lsattr /etc/resolv.conf
----i--------e----- /etc/resolv.conf
Значення: Атрибут immutable встановлено.
Рішення: Використовуйте це лише в контрольованому середовищі й якщо розумієте компроміс. Інакше: правильно вимкніть генерацію.
Жарт №2: Поставити chattr +i на resolv.conf — як приклеїти суперклеєм термостат: тихо приємно, поки інженери з експлуатації не дізнаються.
VPN, корпоративний DNS і split‑horizon: не гадати
Корпоративний DNS рідко — це просто «кілька nameserver’ів». Це політика. Це умовна пересилка. Це внутрішні зони, які ніколи не повинні попадати у публічний інтернет.
VPN‑клієнти часто це реалізують, перенаправляючи DNS через:
- резолвер, доступний лише через VPN‑тунель,
- локальний Windows‑DNS‑проксі, зв’язаний із loopback або віртуальним адаптером,
- правила для конкретних доменів, які Windows виконує, але Linux у WSL2 не бачить.
Режим відмови виглядає так:
- Windows без проблем розв’язує
git.corp.example. - WSL2 таймаутить або повертає NXDOMAIN.
- Ви редагуєте resolv.conf, воно деякий час працює, потім скидається.
- Після сну/відновлення воно знову ламається.
Ключове рішення: чи потрібен вам split DNS всередині WSL2?
- Якщо вам потрібне лише публічне розв’язування інтернету: статичний resolv.conf з публічними DNS підходить.
- Якщо потрібні внутрішні корпоративні зони: вказуйте корпоративні резолвери, до яких реально можна дістатися з WSL2, або запускайте локальний резолвер з належними routing‑доменами.
- Якщо ваш VPN надає DNS лише через локальний Windows‑проксі: можливо, доведеться вказати WSL2 адресу, досяжну (інколи це шлюз WSL), або використовувати systemd‑resolved і передати йому правильні сервери.
Якщо ваше середовище часто змінює мережі (життя ноутбука), статичний resolv.conf може бути «занадто стабільним».
Але практична реальність така: авто‑генерація WSL2 — це не «динамічний DNS, що завжди залишається вірним».
Це «найкраща спроба при старті». Якщо ваш день включає перемикання VPN і сон, вам потрібен явний контроль.
Три корпоративні міні‑історії з полі боїв DNS
Міні‑історія 1: Інцидент, спричинений невірним припущенням
Команда продукту мала WSL2‑базований девелоперський образ: Ubuntu, Docker‑інструменти, кілька внутрішніх CLI‑утиліт.
Все працювало в офісі. Працювало на домашньому Wi‑Fi. Навіть працювало з VPN — більшість часу.
Потім почалася ротація on‑call для роботи зі стендом, і раптом половина команди не могла розв’язувати внутрішні імена.
Неправильне припущення було тонким: «Якщо Windows може це розв’язати, WSL2 теж може».
На Windows VPN‑клієнт встановив політики для конкретних доменів і маршрутизував corp.example на внутрішні резолвери,
одночасно залишивши публічні домени на локальному ISP DNS. Windows був політично‑обізнаний.
WSL2 — ні; він успадкував згенерований resolv.conf на старті, який вказував на адресу шлюзу, що не завжди коректно форвардить DNS під VPN.
Команда виконала звичні ритуали: перезапустити VPN, перезапустити WSL, очистити кеші, спробувати знову.
Отримали періодичний успіх, що гірше від постійної невдачі, бо витрачався час і з’являлася хибна впевненість.
Один інженер «виправив» проблему, прописавши публічний DNS вручну, що вирішило публічні імена і мовчки зламало внутрішні.
Справжнє виправлення полягало в тому, щоб зупинити авто‑генерацію і явно налаштувати split DNS через systemd‑resolved:
внутрішні зони спрямовувалися на корпоративні резолвери, fallback для решти — публічні, і був чіткий план тестування.
Після цього звіти про баги припинилися. Не тому, що DNS став магічним, а тому, що припущення було вилучене з системи.
Міні‑історія 2: Оптимізація, яка відкотилася
Інша організація виконувала великі інсталяції залежностей у WSL2 під локальними CI‑подібними роботами. Хтось помітив, що DNS‑запити «повільні»
і вирішив оптимізувати, збільшуючи кількість спроб резолвера та додаючи кілька публічних nameserver’ів «для надлишковості».
Додали чотири nameserver’и і встановили attempts:5 та timeout:5.
В лабораторії це виглядало стійким. У реальному світі це створило ідеальний шторм:
коли перший nameserver став недоступний через VPN, кожен запит затримувався на 25 секунд, перш ніж перейти до наступного.
Помножте це на репозиторії пакетів, реєстри контейнерів і внутрішнє виявлення сервісів.
Вентилятори ноутбуків закрутило на максимум, розробники звинувачували Docker, а команда VPN була втягнута в наради.
Наслідок був класичний: «надлишковість» з довгими таймаутами — не надлишковість; це посилення латентності.
Резолвер може бути настільки швидким, наскільки швидким є його найповільніша відмова.
Додавати більше nameserver’ів без скорочення таймаутів — означає збільшити кількість повільних відмов, які ви чекатимете.
Виправлення було нудним: максимум два nameserver’и, короткі таймаути і явний split DNS, щоб внутрішні запити не блукали по публічних резолверах.
Коли вони виміряли знову, «повільність DNS» зникла — бо вона була самозаподіяна.
Міні‑історія 3: Нудна, але правильна практика, що врятувала день
Команда платформи підтримувала стандартний bootstrap WSL2 для інженерів.
Вони зробили одне глибоко непривабливе: написали короткий runbook з трьома командами для перевірки DNS і канонічною стратегією resolv.conf.
Ніяких героїчних вчинків. Ніякого «просто перезавантажити». Все тестовано.
Одного понеділка оновлення Windows і оновлення VPN‑клієнта вийшли майже одночасно. Раптом частина інженерів не могла розв’язувати внутрішні домени з WSL2.
Замість того, щоб кожен пробував випадкові фікси, вони слідували runbook:
перевірити поточний nameserver, протестувати доступність порту 53, порівняти внутрішні й публічні запити.
Діагностика була однаковою на всіх машинах: WSL2 отримував IP nameserver, що був валідний лише коли конкретний VPN‑адаптер піднімався.
Після сну/відновлення адаптер піднімався пізно, WSL2 стартував раніше, і resolv.conf генерувався з недоступним сервером.
«Виправлення» не полягало в боротьбі з таймінгом. Воно полягало у вимкненні генерації і використанні стабільних корпоративних DNS IP, доступних через тунель.
Вони запхнули оновлення у свій bootstrap: встановити generateResolvConf = false, розгорнути шаблон resolv.conf,
і додати швидкий крок перевірки. Інцидент перетворився на дрібну неприємність, головним чином тому, що практика була відтворюваною і нудною.
Нудне перемагає цікаве, коли треба відправляти релізи.
Поширені помилки: симптом → корінь проблеми → виправлення
1) «Працює до перезавантаження WSL»
Симптом: Ви редагуєте /etc/resolv.conf, DNS працює, потім ламається після рестарту.
Корінь проблеми: WSL авто‑генерує resolv.conf під час старту і перезаписує ваші зміни.
Виправлення: Додайте generateResolvConf = false у /etc/wsl.conf, потім управляйте своїм resolv.conf.
2) «Публічні домени розв’язуються, внутрішні — ні»
Симптом: example.com працює; git.corp.example повертає NXDOMAIN або таймаут.
Корінь проблеми: Ви використовуєте публічні DNS‑сервери, які не знають внутрішніх зон, або ваша політика split DNS не відтворена в WSL.
Виправлення: Направте WSL на корпоративні резолвери (доступні через VPN) або використовуйте systemd‑resolved з routing‑доменами (~corp.example).
3) «Повне ім’я всередині працює, коротке ім’я — ні»
Симптом: getent hosts git.corp.example працює; getent hosts git не працює.
Корінь проблеми: Відсутній або неправильний search‑домен у resolv.conf (або у конфіг resolved).
Виправлення: Додайте search corp.example (або встановіть Domains=corp.example в resolved).
4) «DNS повільний, збірки зависають, але зрештою успіх»
Симптом: Команди затримуються на секунди за запит; іноді хвилини під час встановлення пакетів.
Корінь проблеми: Довгі таймаути резолвера, забагато nameserver’ів, недосяжний перший сервер або затримки при фолбеку на TCP.
Виправлення: Використовуйте 1–2 доступні nameserver’и, встановіть options timeout:2 attempts:2. Переконайтесь у доступності порту 53 до обраних серверів.
5) «Зламалось після підключення до VPN»
Симптом: DNS відразу ламається після підключення/відключення VPN.
Корінь проблеми: Windows DNS змінився на VPN‑сервери/проксі; WSL resolv.conf не оновився коректно або оновився на недоступний проксі.
Виправлення: Вимкніть авто‑генерацію і явно вкажіть DNS‑сервери, які підходять для режиму VPN; розгляньте systemd‑resolved для split DNS.
6) «Падає тільки після сну/відновлення»
Симптом: Після ранкового пробудження ноутбука — вечірка таймаутів DNS у WSL.
Корінь проблеми: WSL VM відновлюється з застарілим мережевим станом; resolv.conf вказує на шлюз/проксі, що ще не готовий.
Виправлення: wsl.exe --shutdown і перезапуск; довгострокове виправлення — стабільна конфігурація DNS, не прив’язана до тимчасового шлюзу/проксі.
7) «Я зробив chattr +i і тепер нічого не може змінити resolv.conf»
Симптом: Оновлення або скрипти не можуть змінити resolv.conf; ви отримуєте помилки прав навіть як root.
Корінь проблеми: Встановлено атрибут immutable.
Виправлення: sudo chattr -i /etc/resolv.conf, потім керуйте resolv.conf через /etc/wsl.conf і обрану стратегію.
8) «nslookup працює, але apt все ще падає»
Симптом: Один інструмент розв’язує; інший інструмент таймаутить.
Корінь проблеми: Різні шляхи резолвера (NSS vs прямі запити), рівні кешування або відмінності в пріоритеті IPv6/IPv4.
Виправлення: Використовуйте getent для системного шляху; перевірте, що у /etc/nsswitch.conf для hosts є dns; перевірте A і AAAA записи за допомогою dig.
Чеклисти / покроковий план
Чеклист 1: План «припинити ламатись після перезавантаження» (статичний DNS)
- Перегляньте поточний
/etc/resolv.confі зафіксуйте IP nameserver’а. - Протестуйте доступність до цього nameserver на TCP 53. Якщо таймаут — припиніть звинувачувати apt.
- Створіть
/etc/wsl.confзgenerateResolvConf = false. - Замініть
/etc/resolv.confдвома стабільними nameserver’ами і вашим search‑доменом. - Перезапустіть WSL за допомогою
wsl.exe --shutdown. - Перевірте: розв’яжіть публічний домен і внутрішній домен. Повторіть після ще одного перезапуску.
Чеклист 2: План «Я на корпоративному VPN і split DNS важливий» (systemd‑resolved)
- Підтвердіть, що systemd — PID 1 (або погодьтесь використовувати статичний DNS).
- Вимкніть генерацію resolv.conf у WSL.
- Сконфігуруйте
/etc/systemd/resolved.confз корпоративними DNS уDNS=, публічними уFallbackDNS=, і routing‑доменом~corp.example. - Символічно зв’яжіть
/etc/resolv.confз/run/systemd/resolve/stub-resolv.conf. - Перезапустіть systemd‑resolved і перевірте
digдля внутрішніх і публічних імен. - Під час налагодження: очистіть кеші (перезапуск resolved) і перезапустіть запити для перевірки поведінки.
Чеклист 3: План «це 2‑я ночі і мені треба, щоби працювало зараз»
- Запустіть
getent ahosts example.com. Якщо не вдається, це загальний DNS‑злам. - Перевірте IP у
/etc/resolv.confі тест TCP 53. - Якщо недоступно: тимчасово вкажіть у resolv.conf відомий доступний DNS (публічний або корпоративний) і закінчіть інцидент.
- Після інциденту: впровадьте Стратегію A або B правильно, щоб не повторювати це наступного тижня.
FAQ
1) Чому WSL2 постійно перезаписує /etc/resolv.conf?
Тому що за замовчуванням WSL2 розглядає Windows як мережевого авторитету і генерує resolv.conf при старті інстансу.
Ви вимикаєте це за допомогою generateResolvConf = false у /etc/wsl.conf.
2) Яке найбезпечніше «встановив і забув» виправлення?
Стратегія A: вимкнути авто‑генерацію і вказати стабільні nameserver’и, якими ви керуєте і до яких маєте доступ.
Додайте розумні таймаути. Перевірте після кількох перезапусків.
3) Чи вказувати WSL2 DNS на 8.8.8.8 або 1.1.1.1?
Лише якщо вам не потрібні корпоративні внутрішні зони і організація дозволяє це.
Якщо потрібні внутрішні імена — використовуйте корпоративні резолвери (або split DNS через systemd‑resolved).
4) У мене в /etc/resolv.conf адреса 172.x. Це неправильно?
Не автоматично. Часто це шлюз WSL2 або форвардер DNS.
Стає «неправильним», коли недоступний, застарілий або неправильно форвардить під VPN‑умовами.
Тестуйте доступність порту 53 і реальну резолюцію, а не відчуття.
5) Чому я бачу таймаути замість NXDOMAIN?
Таймаут означає, що ваш резолвер не зміг зв’язатися з жодним DNS‑сервером. Це шлях мережі або політика фаєрвола.
NXDOMAIN означає, що ви дістались DNS‑сервера, і він сказав, що ім’я не існує (або відсутнє в тій DNS‑види).
6) Чи можна це поправити, просто перезавантажуючи WSL щоразу?
Можна, і люди так роблять. Але це породжує племінне знання замість системи.
Перезапуск — діагностичний крок; стабільна конфігурація — виправлення.
7) Чи допоможе systemd‑resolved, або це просто ускладнення?
І те, і інше. Він допомагає, коли потрібен split DNS або послідовне кешування. Додає складності, коли все, що вам треба — два статичні nameserver’и.
Використовуйте його свідомо, а не тому, що бачили пост у блозі.
8) Що з Docker у WSL2 — це змінює DNS?
Може. Контейнери мають власну поведінку DNS і можуть успадковувати резолвер хоста або використовувати вбудований DNS у мережі контейнерів.
Виправте DNS хоста WSL2 спочатку. Потім перевірте розв’язування в контейнерах, якщо проблеми залишаться.
9) Чому це ламається тільки на одному Wi‑Fi?
Різні мережі видають різні DNS‑сервери, різні налаштування IPv6 і різну поведінку captive portal.
Авто‑згенерований resolv.conf може підхопити «працює для Windows, дивно для WSL» конфіг.
Явний стабільний DNS це уникає.
10) Якщо я вимкну генерацію, WSL2 назавжди ігноруватиме зміни DNS у Windows?
Так. Це й є мета. Якщо ви часто мандруєте між мережами і покладаєтесь на автоматичну адаптацію DNS, вам знадобиться стратегія для свідомого оновлення конфігурації
(або резолвер, що може імпортувати політику), а не випадкові зміни.
Висновок: наступні кроки, які можна зробити сьогодні
Якщо DNS у WSL2 ламається після перезавантаження, у вас не «проблема Linux». У вас проблема володіння.
WSL генерує /etc/resolv.conf з уявлення Windows про мережу, що під вами змінюється.
Ваші правки зникають, бо вони ніколи не були під контролем.
Зробіть наступне, по черзі:
- Пройдіть швидкий план діагностики один раз. Підтвердіть, чи nameserver застарілий/недоступний, чи домен — split‑DNS.
- Впровадьте Стратегію A (статичний resolv.conf), якщо можете використовувати стабільні доступні DNS‑сервери. Це найменше компонентів у грі.
- Впровадьте Стратегію B (systemd‑resolved), якщо вам потрібен split‑horizon DNS. Маршрутизуйте внутрішні домени явно.
- Тестуйте після
wsl.exe --shutdownдвічі. Якщо воно працює лише «інколи», ви ще не закінчили.
Мета — не мати DNS, що «працює прямо зараз». Мета — мати DNS, що працює завтра вранці після сну, після VPN, після наступного оновлення,
без ваших ритуалів. Продакшн‑системи не приймають ритуалів. Ваше дев‑середовище теж не повинно.