Problèmes DNS sous WSL2 : la correction de resolv.conf qui survit aux redémarrages

Cet article vous a aidé ?

Vous ouvrez WSL2, lancez apt update, et ça… bloque. Ou les pulls Docker échouent. Ou votre remote Git interne disparaît sauf si le VPN est « parfaitement » configuré. Vous vérifiez /etc/resolv.conf, il a l’air plausible, et pourtant le DNS se comporte comme s’il négociait un contrat collectif.

Voilà l’histoire du DNS sous WSL2 : le réseau Windows, une VM légère, des clients VPN opiniâtres, et un fichier (resolv.conf) que WSL2 régénère quand vous ne regardez pas. La solution n’est pas « éditer le fichier ».
La solution consiste à empêcher WSL2 de le réécrire, puis à choisir une stratégie DNS qui colle à votre réalité et survit aux redémarrages.

Ce qui se passe vraiment quand WSL2 « perd le DNS »

WSL2 n’est pas une couche de compatibilité. C’est un vrai noyau Linux qui tourne dans une VM gérée.
Votre distribution reçoit une NIC virtuelle sur un vSwitch privé ; Windows est de l’autre côté et fait le travail « d’uplink ».
Le DNS à l’intérieur de WSL2, par défaut, est une chaîne de confiance :

  • Les applications Linux appellent le résolveur libc (ou systemd-resolved, selon la configuration de la distro).
  • Le résolveur lit /etc/resolv.conf (directement ou indirectement).
  • Par défaut, WSL2 génère automatiquement /etc/resolv.conf au démarrage à partir de la vue DNS de Windows.
  • La vue DNS de Windows change lorsque vous rejoignez un réseau Wi‑Fi, changez de réseau, connectez/déconnectez un VPN, ou obtenez un nouveau bail DHCP.
  • Certaines solutions VPN installent des proxys DNS, des règles de split DNS, ou des politiques « NRPT », et Windows s’y conforme volontiers.
  • WSL2 ne met pas forcément à jour sa configuration générée à chaud de la façon dont vous l’attendez intuitivement.

Quand ça casse, c’est généralement l’un de ces cas :

  • Adresse IP du serveur DNS périmée dans /etc/resolv.conf (fréquent après mise en veille, bascule VPN, changement de réseau).
  • Serveur DNS injoignable parce que le côté Windows utilise un proxy local que seul Windows peut contacter.
  • Inadéquation split‑horizon : Windows sait résoudre des domaines internes via une politique ; WSL2 ne le sait pas.
  • Bizarre avec IPv6 : Windows privilégie DNS IPv6, le résolveur WSL2 préfère IPv4, ou inversement.
  • Domaines de recherche cassés : vous comptez sur des noms courts (git, jenkins) qui nécessitent un suffixe search.
  • Course/réutilisation du résolveur : un résolveur local met en cache une mauvaise valeur et vous avez l’impression que le réseau est hanté.

Éditer /etc/resolv.conf « marche » jusqu’au redémarrage parce que WSL2 l’écrase. Ce n’est pas un bug.
C’est le contrat par défaut : Windows est la source de vérité à moins que vous ne preniez explicitement le contrôle.

Réalité sèche : le DNS est la dépendance que vous oubliez jusqu’à ce qu’elle casse, et quand elle casse, tout casse.
La solution est ennuyeuse. Et l’ennui, c’est une bonne chose.

Faits et contexte historique (ce qui explique la douleur)

  1. resolv.conf existe depuis des décennies : le format du fichier vient des premiers résolveurs Unix et a survécu parce que tout en dépend.
  2. WSL1 et WSL2 sont fondamentalement différents : WSL1 traduisait les appels système Linux ; WSL2 exécute un vrai noyau dans une VM, ce qui change radicalement le comportement réseau.
  3. WSL2 utilisait à l’origine un modèle NAT par conception : il est isolé derrière un commutateur virtuel, donc Windows est en pratique la passerelle et souvent le « conseiller » DNS.
  4. systemd n’a pas toujours été activé dans WSL : les anciennes distros WSL tournaient sans systemd, donc le comportement DNS dépendait fortement des valeurs par défaut et des scripts de la distro.
  5. Le DNS Windows en entreprise peut être piloté par des politiques : Windows prend en charge des politiques de résolution et des comportements par domaine qui ne se traduisent pas facilement vers un invité Linux sans travail supplémentaire.
  6. Les domaines de recherche DNS sont une commodité héritée : les noms courts dépendent des règles search ; ce sont aussi une source fréquente d’échecs « ça marche sur ma machine ».
  7. Les clients VPN implémentent souvent une « protection » DNS : beaucoup dirigent le DNS via des résolveurs tunnel‑only pour éviter les fuites, ce qui fait des VM invitées des outsiders non fiables.
  8. La mise en cache DNS a changé les attentes : les piles modernes mettent fortement en cache (systemd-resolved, nscd, caches de navigateurs). Vous pouvez réparer le DNS et voir quand même des résultats périmés.
  9. Windows et Linux préfèrent des outils différents : Windows s’appuie sur des services système et des politiques ; Linux attend des serveurs explicites dans resolv.conf. WSL2 reste coincé entre les deux.

Playbook de diagnostic rapide (premier/deuxième/troisième)

Quand la production brûle, vous n’« explorez » pas. Vous bisectez. Voici le chemin le plus rapide vers la vérité.

Premier : est‑ce le DNS, le routage, ou l’application ?

  • Testez la connectivité IP brute (ping de la passerelle / IP connue).
  • Testez la résolution DNS pour un domaine public et un domaine interne.
  • Comparez la résolution sous Windows et dans WSL2.

Second : WSL2 utilise‑t‑il un serveur de noms périmé ou injoignable ?

  • Lisez /etc/resolv.conf.
  • Essayez de contacter l’IP du serveur de noms sur le port 53 (tests UDP/TCP).
  • Vérifiez si le serveur de noms est une adresse proxy locale Windows que WSL2 ne peut pas atteindre.

Troisième : est‑ce une politique split DNS / VPN ?

  • Résolvez les noms internes avec les outils Windows et comparez.
  • Vérifiez les domaines de recherche et les attentes par domaine.
  • Décidez : avez‑vous besoin d’un résolveur local dans WSL2, ou pouvez‑vous pointer directement vers les résolveurs d’entreprise ?

Règle de décision : si le serveur de noms dans /etc/resolv.conf est injoignable ou périmé, arrêtez de lutter contre les symptômes.
Prenez le contrôle de la façon dont resolv.conf est généré. C’est le levier.

Tâches pratiques : commandes, sorties attendues, et décisions

Voici les vérifications que je lance réellement. Pas parce que j’aime taper, mais parce que deviner coûte cher.
Chaque tâche inclut : la commande, la signification de la sortie, et la décision qu’elle entraîne.

Task 1: Confirm you’re actually in WSL2 (not WSL1)

cr0x@server:~$ uname -r
5.15.133.1-microsoft-standard-WSL2

Meaning: If you see microsoft-standard-WSL2, you’re in WSL2.
WSL1 behaves differently and doesn’t have the same VM DNS edge cases.
Decision: If you’re not on WSL2, stop and adjust expectations; this article targets WSL2.

Task 2: Check the current resolver configuration

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

Meaning: That comment tells you WSL is auto-generating the file. The nameserver is often a virtual gateway address.
Decision: If DNS breaks after reboots or VPN toggles, you need to disable generation and own this file.

Task 3: Resolve a public name quickly (does DNS work at all?)

cr0x@server:~$ getent ahosts example.com | head
93.184.216.34    STREAM example.com
93.184.216.34    DGRAM
93.184.216.34    RAW

Meaning: getent tests the system resolver path (NSS), not just a single tool.
Decision: If this fails, DNS is broadly broken. If it works but internal names fail, think split DNS/search domains.

Task 4: Confirm an internal name fails the way you think it fails

cr0x@server:~$ getent hosts git

Meaning: No output typically means “not resolved,” not “network down.”
Decision: If git fails but git.corp.example works, your search line is missing/wrong.

Task 5: Use dig to see the resolver’s opinion (timeouts 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

Meaning: Timeout means you can’t reach the configured DNS server(s). That’s different from NXDOMAIN.
Decision: Timeouts push you toward “nameserver unreachable/stale.” NXDOMAIN pushes you toward “wrong DNS server for that domain.”

Task 6: Identify the nameserver IP WSL2 is using

cr0x@server:~$ awk '/^nameserver/{print $2}' /etc/resolv.conf
172.26.112.1

Meaning: You want the exact IP to test connectivity.
Decision: If it’s a 172/10/192 private address, it’s likely the WSL2/Windows virtual gateway or a VPN-side resolver.

Task 7: Test connectivity to DNS server (UDP and 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

Meaning: TCP 53 timeout is a strong hint the server isn’t reachable from the guest.
UDP is harder to test with nc, but TCP failure already smells bad.
Decision: If port 53 isn’t reachable, stop chasing resolver config inside apps. Fix the path to DNS.

Task 8: Verify you have basic routing (is it DNS or network?)

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

Meaning: Default route via the same IP as your nameserver is common in WSL2. If this route is missing, you’ve got bigger issues than DNS.
Decision: If routing is broken, restarting WSL or the network stack is step zero.

Task 9: Check for systemd-resolved and how it’s wired

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

Meaning: If systemd-resolved is running, your resolver may not be reading /etc/resolv.conf in the way you assume.
Decision: Decide whether to use systemd-resolved properly (recommended if you need split DNS), or keep it simple with a static resolv.conf.

Task 10: Inspect the current /etc/resolv.conf target (file vs symlink)

cr0x@server:~$ ls -l /etc/resolv.conf
-rw-r--r-- 1 root root 188 Feb  5 09:40 /etc/resolv.conf

Meaning: If it’s a symlink to systemd’s stub file, you troubleshoot differently.
Decision: Plain file means WSL wrote it (or you did). Symlink often means systemd-resolved owns it.

Task 11: Compare Windows DNS behavior (from inside 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

Meaning: You can’t run PowerShell in this bash block per our format constraints, but you can still reason:
if Windows is using a DNS proxy (common with VPN), WSL might be pointing at something that only Windows can reach reliably.
Decision: If corporate VPN is involved, plan for a stable, explicit DNS setup.

Task 12: Restart WSL2 cleanly (force regeneration tests)

cr0x@server:~$ wsl.exe --shutdown
The operation completed successfully.

Meaning: This shuts down all WSL instances. Next launch is a cold start.
Decision: Use this as your “did my fix survive reboot?” test loop.

Task 13: Prove the file is being overwritten (before you disable it)

cr0x@server:~$ sudo sh -c 'echo "# test-marker" >> /etc/resolv.conf'
cr0x@server:~$ tail -n 3 /etc/resolv.conf
search corp.example
# test-marker

Meaning: Now shut down WSL and restart. If the marker disappears, WSL regenerated it.
Decision: If overwritten, you must disable generation. Anything else is theater.

Task 14: Validate that DNS works after switching resolvers

cr0x@server:~$ dig +short example.com
93.184.216.34
cr0x@server:~$ dig +short git.corp.example
10.40.12.23

Meaning: You want both public and internal resolution to succeed consistently.
Decision: If public works but internal fails, your DNS server choice is wrong for split-horizon needs.

One quote to keep you honest: « L’espoir n’est pas une stratégie » — attribution fréquente à la culture opérationnelle (idée paraphrasée).
Le dépannage DNS est exactement l’endroit où « l’espoir » se présente déguisé en « peut‑être que ça marchera après avoir reconnecté le VPN ».

La correction de resolv.conf qui survit aux redémarrages (chemins recommandés)

Il existe trois stratégies exploitables. Choisissez‑en une. Les mélanger crée un système « parfois », et « parfois » est le pire SLA.

Stratégie A (recommandée pour la plupart) : Désactiver la génération automatique et écrire un resolv.conf statique

C’est la solution la plus simple quand vous pouvez pointer vers des serveurs DNS stables (résolveurs publics, votre routeur, ou les résolveurs d’entreprise accessibles sur votre réseau/VPN).
Elle survit aussi aux redémarrages parce que vous empêchez WSL de réécrire le fichier.

Étape 1 : Empêcher WSL de générer resolv.conf

cr0x@server:~$ sudo tee /etc/wsl.conf >/dev/null <<'EOF'
[network]
generateResolvConf = false
EOF

Meaning: WSL lit /etc/wsl.conf au démarrage de l’instance. Ceci lui indique de laisser /etc/resolv.conf tranquille.
Decision: If you need stability more than “auto-adapt to random networks,” this is your move.

Étape 2 : Créer votre propre 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

Meaning: Deux serveurs de noms, un domaine de recherche, et des timeouts conservateurs pour que les échecs échouent vite plutôt que de bloquer des builds.
Decision: If you don’t have stable internal DNS IPs, don’t guess. Get them from your network/VPN team or from Windows adapter details.

Étape 3 : Redémarrer WSL pour appliquer

cr0x@server:~$ wsl.exe --shutdown
The operation completed successfully.

Relancez la distro et retestez la résolution (Task 14). Si le fichier survit à plusieurs redémarrages, c’est réglé.

Blague #1 : Le DNS, c’est comme le café du bureau — personne ne l’investit correctement jusqu’au jour où il s’arrête, et là soudain c’est la priorité de tout le monde.

Stratégie B : Utiliser systemd-resolved dans WSL2 pour le split DNS (quand les règles VPN d’entreprise comptent)

Si vous avez du split‑horizon DNS (les domaines internes doivent aller vers des résolveurs internes, le reste vers le public),
un resolv.conf statique peut être trop brutal. systemd-resolved peut gérer le routage par domaine de façon structurée.
Mais il faut le câbler correctement, sinon vous obtiendrez le pire des deux mondes : cache plus mauvais serveurs.

Approche générale :

  • Désactiver la génération de resolv.conf par WSL.
  • Faire pointer /etc/resolv.conf vers le résolveur stub de systemd (127.0.0.53) ou vers le fichier géré par resolved.
  • Configurer systemd-resolved avec les bons serveurs DNS et les domaines de routage.

Étape 1 : Confirmer que systemd est disponible/actif

cr0x@server:~$ ps -p 1 -o comm=
systemd

Meaning: PID 1 est systemd. Si ce n’est pas le cas, activer resolved devient une autre conversation.
Decision: If systemd isn’t running, prefer Strategy A unless you’re ready to re-plumb the distro.

Étape 2 : Configurer 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

Meaning: Domains=~corp.example en fait un domaine de routage : les requêtes pour cette zone vont vers votre DNS d’entreprise.
Le simple corp.example définit un domaine de recherche pour la commodité.
Decision: Use this when your VPN requires internal names to resolve internally but public DNS should stay fast.

Étape 3 : Pointer /etc/resolv.conf vers 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

Meaning: Les applications lisent /etc/resolv.conf, atteignent 127.0.0.53, et resolved prend les décisions intelligentes.
Decision: If you see weird caching, you now know where it lives (resolved), and you can flush it.

Stratégie C : Rendre resolv.conf immuable (efficace, mais je n’aime pas ça)

Oui, vous pouvez coller chattr +i sur /etc/resolv.conf. Ça empêche les réécritures même si vous oubliez wsl.conf.
C’est aussi un piège : « vous dans le futur » (ou votre automation) ne pourra plus mettre à jour le DNS et perdra du temps à déboguer des permissions.

cr0x@server:~$ sudo chattr +i /etc/resolv.conf
cr0x@server:~$ lsattr /etc/resolv.conf
----i--------e----- /etc/resolv.conf

Meaning: L’attribut immuable est défini.
Decision: Only use this if you have a controlled environment and you understand the tradeoff. Otherwise: disable generation properly.

Blague #2 : Mettre chattr +i sur resolv.conf, c’est comme supercoler le thermostat — silencieusement satisfaisant jusqu’à ce que la maintenance s’en aperçoive.

VPN, DNS d’entreprise et split-horizon : ne devinez pas

Le DNS d’entreprise n’est rarement « juste quelques serveurs de noms ». C’est de la politique. C’est du forwarding conditionnel. Ce sont des zones internes qui ne doivent jamais fuiter sur Internet public.
Les clients VPN l’appliquent souvent en canalisant le DNS via :

  • un résolveur uniquement joignable par le tunnel VPN,
  • un proxy DNS local Windows lié à la loopback ou à un adaptateur virtuel,
  • des règles par domaine que Windows respecte mais que Linux dans WSL2 ne voit jamais.

Le mode de défaillance ressemble à ceci :

  • Windows résout git.corp.example correctement.
  • WSL2 met en timeout ou renvoie NXDOMAIN.
  • Vous éditez resolv.conf, ça marche un moment, puis ça revient.
  • Après mise en veille/reprise, ça casse encore.

La décision clé est : avez‑vous besoin du split DNS dans WSL2 ?

  • Si vous n’avez besoin que de la résolution Internet publique : un resolv.conf statique pointant vers des DNS publics suffit.
  • Si vous avez besoin des zones internes : pointez vers des résolveurs d’entreprise réellement joignables depuis WSL2, ou exécutez un résolveur local avec des domaines de routage appropriés.
  • Si votre VPN n’expose le DNS que via un proxy local Windows : vous devrez peut‑être pointer WSL2 vers une adresse joignable (parfois la passerelle WSL), ou utiliser systemd-resolved et lui fournir les bons serveurs.

Si votre environnement change souvent de réseau (vie de laptop), un resolv.conf statique peut être « trop stable ».
Mais voici la réalité pratique : la génération automatique de WSL2 n’est pas synonyme de « DNS dynamique qui reste toujours correct ».
C’est un « effort maximal au démarrage ». Si votre journée inclut des bascules VPN et des mises en veille, vous voulez un contrôle explicite.

Trois mini-récits d’entreprise depuis les tranchées DNS

Mini-récit 1 : L’incident causé par une mauvaise hypothèse

Une équipe produit avait une image de développement basée sur WSL2 : Ubuntu, outils Docker, quelques utilitaires CLI internes.
Ça fonctionnait au bureau. Ça fonctionnait sur le Wi‑Fi domestique. Ça fonctionnait même avec le VPN — la plupart du temps.
Puis une rotation d’on-call a commencé à l’utiliser pour un incident de staging, et soudain la moitié de l’équipe ne pouvait plus résoudre les noms internes.

La mauvaise hypothèse était subtile : « Si Windows peut le résoudre, WSL2 peut le résoudre. »
Sur Windows, le client VPN avait installé des politiques DNS par domaine et routait corp.example vers des résolveurs internes,
tout en laissant les domaines publics sur le DNS de l’ISP. La résolution Windows était consciente des politiques.
WSL2 ne l’était pas ; il héritait d’un resolv.conf généré au lancement qui pointait vers une IP de passerelle qui ne relayait pas fiablement le DNS sous VPN.

L’équipe a tenté le rituel habituel : redémarrer le VPN, redémarrer WSL, vider les caches, retenter.
Ils ont obtenu un succès intermittent, pire qu’un échec constant car cela gaspille des heures et crée une fausse confiance.
Un ingénieur a « corrigé » en durcissant un DNS public, ce qui a résolu les noms publics et a cassé en silence la résolution interne.

La vraie correction fut d’arrêter la génération automatique et de configurer explicitement le split DNS avec systemd-resolved :
zones internes routées vers les résolveurs d’entreprise, DNS de secours pour le reste, et un plan de tests clair.
Après cela, les rapports de bugs ont cessé. Pas parce que le DNS était devenu magique, mais parce que les hypothèses avaient été retirées du système.

Mini-récit 2 : L’optimisation qui s’est retournée contre eux

Une autre organisation lançait de grosses installations de dépendances dans WSL2 lors de flux de travail locaux de type CI. Quelqu’un a trouvé les requêtes DNS « lentes »
et a décidé d’optimiser en augmentant le nombre de tentatives du résolveur et en ajoutant plusieurs serveurs publics « pour la redondance ».
Ils ont ajouté quatre serveurs de noms et défini attempts:5 et timeout:5.

En laboratoire, ça semblait résilient. Dans la vraie vie, cela a créé la tempête parfaite :
quand le premier serveur est devenu injoignable en VPN, chaque lookup a attendu 25 secondes avant d’échouer sur le suivant.
Multipliez ça par des dépôts de paquets, des registres de conteneurs et la découverte de services internes.
Les ventilateurs des laptops se sont emballés, les développeurs ont accusé Docker, et l’équipe VPN a été entraînée en réunions.

Le retour de bâton était classique : la « redondance » avec de longs timeouts n’est pas de la redondance ; c’est de l’amplification de latence.
Un résolveur ne peut être plus rapide que son plus lent échec.
Ajouter plus de serveurs sans réduire les timeouts multiplie simplement les échecs lents que vous subirez.

La correction fut ennuyeuse : deux serveurs max, timeouts courts, et split DNS explicite pour que les requêtes internes n’errent pas vers des résolveurs publics.
Une fois mesuré de nouveau, la « lenteur DNS » a disparu — parce qu’elle était auto‑infligée.

Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une équipe plateforme maintenait un bootstrap WSL2 standard pour les ingénieurs.
Ils ont fait quelque chose de profondément peu sexy : une fiche runbook d’une page avec trois commandes pour vérifier le DNS, plus une stratégie canonical de resolv.conf.
Pas d’héroïsme. Pas de « juste redémarrer ». Tout était testable.

Un lundi, une mise à jour Windows et une mise à jour du client VPN sont arrivées presque en même temps. Soudain, un lot d’ingénieurs ne pouvait plus résoudre les domaines internes depuis WSL2.
Au lieu que tout le monde tente des réparations au hasard, ils ont suivi le runbook :
vérifier le serveur de noms actuel, tester la joignabilité du port 53, comparer les résolutions interne vs publique.

Le diagnostic fut cohérent sur toutes les machines : WSL2 recevait une IP de serveur qui n’était valide que lorsque un adaptateur VPN spécifique était actif.
Après mise en veille/reprise, l’adaptateur revenait tard, WSL2 démarrava it tôt, et resolv.conf était généré avec un serveur injoignable.
La « correction » n’était pas de lutter contre la synchronisation. C’était de désactiver la génération et d’utiliser des IP DNS d’entreprise stables joignables via le tunnel.

Ils ont poussé une mise à jour du bootstrap : mettre generateResolvConf = false, déployer un template de resolv.conf,
et inclure une étape de vérification rapide. L’incident est devenu une nuisance mineure, surtout parce que la pratique était répétable et terne.
Terne gagne quand il s’agit de livrer.

Erreurs fréquentes : symptôme → cause racine → correction

1) « Ça marche jusqu’à ce que je redémarre WSL »

Symptôme : Vous éditez /etc/resolv.conf, le DNS fonctionne, puis ça casse après le redémarrage.

Cause racine : WSL régénère automatiquement resolv.conf au démarrage et écrase vos modifications.

Correction : Ajoutez generateResolvConf = false dans /etc/wsl.conf, puis écrivez votre propre resolv.conf.

2) « Les domaines publics se résolvent, les domaines internes échouent »

Symptôme : example.com fonctionne ; git.corp.example renvoie NXDOMAIN ou timeout.

Cause racine : Vous utilisez des serveurs DNS publics qui ne connaissent pas les zones internes, ou votre politique split DNS n’est pas reproduite dans WSL.

Correction : Pointez WSL vers les résolveurs d’entreprise (accessibles via VPN) ou utilisez systemd-resolved avec des domaines de routage (~corp.example).

3) « Le FQDN interne fonctionne, le nom court non »

Symptôme : getent hosts git.corp.example fonctionne ; getent hosts git échoue.

Cause racine : Domaine de recherche manquant ou incorrect dans resolv.conf (ou la config de resolved).

Correction : Ajoutez search corp.example (ou définissez Domains=corp.example dans resolved).

4) « Le DNS est lent, les builds bloquent, mais finissent par réussir »

Symptôme : Les commandes se mettent en pause plusieurs secondes par lookup ; parfois des minutes lors d’installations.

Cause racine : Timeouts longs du résolveur, trop de serveurs de noms, premier serveur injoignable, ou délais de fallback TCP.

Correction : Utilisez 1–2 serveurs de noms joignables, définissez options timeout:2 attempts:2. Assurez la joignabilité du port 53 vers les serveurs choisis.

5) « Ça a cassé après connexion au VPN »

Symptôme : Le DNS échoue immédiatement après la connexion/déconnexion du VPN.

Cause racine : Le DNS Windows a changé pour des serveurs/proxys fournis par le VPN ; resolv.conf de WSL n’a pas mis à jour correctement ou a été mis à jour vers un proxy injoignable.

Correction : Désactivez la génération automatique et définissez explicitement des serveurs DNS appropriés pour le mode VPN ; envisagez systemd-resolved pour le split DNS.

6) « Ça ne tombe en panne qu’après mise en veille/reprise »

Symptôme : Réveil du laptop le matin = fête des timeouts DNS dans WSL.

Cause racine : La VM WSL reprend avec un état réseau périmé ; resolv.conf pointe vers une passerelle/proxy qui n’est pas prête.

Correction : wsl.exe --shutdown et redémarrer ; correction long terme = config DNS stable non liée à une passerelle/proxy transitoire.

7) « J’ai mis chattr +i et maintenant rien ne peut changer resolv.conf »

Symptôme : Les mises à jour ou scripts échouent à éditer resolv.conf ; vous obtenez des erreurs de permission même en root.

Cause racine : Attribut immuable défini.

Correction : sudo chattr -i /etc/resolv.conf, puis gérez resolv.conf proprement via /etc/wsl.conf et la stratégie choisie.

8) « nslookup marche mais apt échoue encore »

Symptôme : Un outil résout ; un autre timeoute.

Cause racine : Chemins de résolveur différents (NSS vs requêtes directes), couches de cache, ou préférences IPv6/IPv4 différentes.

Correction : Utilisez getent pour le chemin système ; vérifiez que /etc/nsswitch.conf inclut dns pour hosts ; validez A et AAAA avec dig.

Listes de contrôle / plan étape par étape

Checklist 1 : Le plan « arrêter les pannes après redémarrage » (DNS statique)

  1. Inspecter /etc/resolv.conf actuel et noter l’IP du serveur de noms.
  2. Tester la joignabilité de ce serveur sur TCP 53. Si timeout, arrêtez de blâmer apt.
  3. Créer /etc/wsl.conf avec generateResolvConf = false.
  4. Remplacer /etc/resolv.conf par deux serveurs stables et votre domaine de recherche.
  5. Redémarrer WSL avec wsl.exe --shutdown.
  6. Valider : résoudre un domaine public et un domaine interne. Répéter après un autre redémarrage.

Checklist 2 : Le plan « je suis en VPN d’entreprise et le split DNS importe » (systemd-resolved)

  1. Confirmer que systemd est PID 1 (ou accepter d’utiliser le DNS statique).
  2. Désactiver la génération de resolv.conf par WSL.
  3. Configurer /etc/systemd/resolved.conf avec le DNS d’entreprise en DNS=, le public en FallbackDNS=, et le domaine de routage ~corp.example.
  4. Syzlinker /etc/resolv.conf vers /run/systemd/resolve/stub-resolv.conf.
  5. Redémarrer systemd-resolved et retester avec dig pour les noms internes et publics.
  6. Lors du debug : vider les caches (redémarrer resolved) et relancer les requêtes pour confirmer le comportement.

Checklist 3 : Le plan « il est 2h du matin et je veux que ça marche maintenant »

  1. Exécuter getent ahosts example.com. Si ça échoue, c’est un DNS global.
  2. Vérifier l’IP du nameserver dans /etc/resolv.conf et tester la connectivité TCP 53.
  3. Si injoignable : définir temporairement resolv.conf sur un DNS connu joignable (public ou d’entreprise) et terminer l’incident.
  4. Après l’incident : implémenter proprement la Stratégie A ou B pour ne pas répéter la panne la semaine suivante.

FAQ

1) Pourquoi WSL2 réécrit‑il sans cesse /etc/resolv.conf ?

Parce qu’par défaut WSL2 considère Windows comme l’autorité réseau et génère resolv.conf au démarrage de l’instance.
Vous le désactivez avec generateResolvConf = false dans /etc/wsl.conf.

2) Quelle est la correction la plus sûre « set and forget » ?

Stratégie A : désactiver la génération automatique et pointer vers des serveurs de noms stables que vous contrôlez et pouvez joindre.
Ajoutez des timeouts raisonnables. Validez après plusieurs redémarrages.

3) Dois‑je pointer le DNS de WSL2 vers 8.8.8.8 ou 1.1.1.1 ?

Seulement si vous n’avez pas besoin des zones internes d’entreprise, et si votre organisation l’autorise.
Si vous avez besoin des noms internes, utilisez les résolveurs d’entreprise (ou le split DNS avec systemd-resolved).

4) Mon /etc/resolv.conf contient une adresse 172.x. Est‑ce mauvais ?

Pas automatiquement. C’est souvent la passerelle WSL2 ou un forwarder DNS.
Ça devient « mauvais » quand c’est injoignable, périmé, ou qu’il ne relaie pas correctement sous VPN.
Testez la joignabilité du port 53 et la résolution réelle, pas les impressions.

5) Pourquoi je vois des timeouts au lieu de NXDOMAIN ?

Timeout signifie que votre résolveur n’a pas pu contacter un serveur DNS. C’est un problème de chemin réseau ou de politique firewall.
NXDOMAIN signifie que vous avez atteint un serveur DNS qui vous a répondu que le nom n’existe pas (ou n’est pas dans cette vue DNS).

6) Puis‑je résoudre ça en redémarrant WSL à chaque fois ?

Vous pouvez, et des gens le font. C’est aussi comme conserver du savoir tribal au lieu d’un système.
Redémarrer est une étape de diagnostic ; la config stable est la solution.

7) systemd-resolved aide‑t‑il, ou ajoute‑t‑il juste de la complexité ?

Les deux. Il aide quand vous avez besoin du split DNS ou d’un comportement de cache cohérent. Il ajoute de la complexité quand tout ce dont vous aviez besoin était deux serveurs statiques.
Utilisez‑le intentionnellement, pas parce que vous avez lu un billet de blog.

8) Et Docker dans WSL2 — ça change le DNS ?

Ça peut. Les conteneurs ont leur propre comportement DNS et peuvent hériter du résolveur hôte ou utiliser un DNS embarqué dans le réseau du conteneur.
Corrigez d’abord le DNS de l’hôte WSL2. Puis validez la résolution dans les conteneurs séparément si les problèmes persistent.

9) Pourquoi ça casse seulement sur un réseau Wi‑Fi ?

Les réseaux différents fournissent des serveurs DNS différents, des paramètres IPv6 différents, et des comportements de portail captif différents.
Le resolv.conf auto‑généré peut récupérer une configuration « fonctionne pour Windows, étrange pour WSL ». Un DNS explicite et stable évite ça.

10) Si je désactive la génération, WSL2 ignorera‑t‑il les changements DNS Windows pour toujours ?

Oui. C’est le but. Si vous naviguez entre réseaux et dépendez d’un DNS qui s’adapte automatiquement, vous devrez mettre en place une stratégie pour mettre à jour votre configuration délibérément
(ou utiliser un résolveur capable d’ingérer des politiques), pas le faire par accident.

Conclusion : prochaines étapes à réaliser aujourd’hui

Si le DNS de WSL2 casse après les redémarrages, ce n’est pas un « problème Linux ». C’est un problème de propriété.
WSL génère /etc/resolv.conf à partir d’une vue réseau Windows qui change sous vos pieds.
Vos modifications disparaissent parce qu’elles n’étaient jamais aux commandes.

Faites ceci ensuite, dans l’ordre :

  1. Exécutez le playbook de diagnostic rapide une fois. Confirmez si le serveur de noms est périmé/injoignable ou si le domaine est en split‑DNS.
  2. Mettez en œuvre la Stratégie A (resolv.conf statique) si vous pouvez utiliser des serveurs DNS stables et joignables. C’est le moins de pièces mobiles.
  3. Mettez en œuvre la Stratégie B (systemd-resolved) si vous avez besoin du split‑horizon DNS. Routez explicitement les domaines internes.
  4. Testez après wsl.exe --shutdown deux fois. Si ça ne marche que « parfois », vous n’avez pas terminé.

L’objectif n’est pas d’avoir le DNS « qui marche maintenant ». L’objectif est d’avoir le DNS qui marche demain matin après la mise en veille, après le VPN, après la prochaine mise à jour,
sans que vous effectuiez des rituels. Les systèmes de production n’acceptent pas les rituels. Votre environnement dev non plus.

← Précédent
Points de restauration manquants : le paramètre que Windows désactive sans cesse
Suivant →
Mythes sur l’affectation CPU dans Proxmox — Le réglage qui aggrave la latence

Laisser un commentaire