Vous avez lancé un service dans WSL, ouvert http://localhost:3000 dans un navigateur Windows, et ça a marché. Vous avez hoché la tête comme quelqu’un dont la vie est sous contrôle.
Puis vous avez redémarré, connecté un VPN, ou « optimisé » quelque chose, et localhost a commencé à se comporter comme s’il ne vous avait jamais rencontré.
Le réseau WSL n’est pas mystérieux. Il est simplement superposé. Le réseau Windows plus une VM Linux (WSL2), plus des tuyaux auxiliaires qui essaient de rendre le flux de travail dev natif.
Quand toutes les couches s’accordent, localhost paraît magique. Quand elles ne s’accordent pas, vous obtenez des timeouts, connection refused, ou pire : ça marche sur votre machine et échoue chez tout le monde.
Le modèle mental : ce que « localhost » signifie réellement dans WSL
« Localhost » n’est pas un lieu. C’est un nom d’interface qui s’expanse en une adresse IP — en général 127.0.0.1 pour IPv4 et ::1 pour IPv6.
Le détail opérationnel clé : 127.0.0.1 signifie toujours « ce namespace réseau ». Pas « cette machine ». Pas « ce laptop ». Pas « ce que je voulais dire émotionnellement ».
En Linux natif sur matériel, « ce namespace réseau » correspond à la pile réseau de l’hôte. Dans WSL2, Linux s’exécute à l’intérieur d’une VM légère avec sa propre pile réseau.
Cela implique :
- À l’intérieur de WSL :
localhostdésigne la VM WSL elle-même. - À l’intérieur de Windows :
localhostdésigne Windows lui-même.
La raison pour laquelle cela fonctionne souvent est que Windows ajoute de la colle : un transfert de port automatique pour l’accès de type « localhost », plus (dans les builds récentes) un mode réseau miroir qui réduit l’écart.
Votre travail en tant qu’opérateur est d’arrêter de penser en « machines » et de commencer à penser en stacks :
Qui est le client ? Quelle stack héberge le serveur ? Sur quelle interface le service écoute-t-il ? Quel pare-feu bloque ? Quel NAT ou proxy effectue la traduction ?
Faits intéressants et historique à utiliser
- WSL1 n’avait pas de VM. Il traduisait les appels système Linux en appels noyau NT, donc le réseau se comportait plus comme un « Windows natif avec une personnalité Linux ».
- WSL2 est passé à un vrai noyau Linux. Excellent pour la compatibilité ; le réseau est devenu du réseau de VM (NAT par défaut), d’où naissent la plupart des histoires « pourquoi localhost ne marche pas ».
- 127.0.0.1 est défini comme loopback. Les paquets vers cette adresse ne sortent jamais sur le câble ; ils bouclent au sein de la pile. C’est pourquoi les pare-feu et le routage peuvent se comporter différemment de ce que vous attendez.
- Hyper-V n’est plus réservé aux serveurs. WSL2 utilise des composants Hyper-V même sur les laptops, d’où la présence d’un adaptateur vEthernet et d’un commutateur virtuel.
- Windows a ajouté un forwarding localhost pour WSL2. Windows peut écouter sur un port Windows et transférer le trafic dans la VM WSL pour que
localhost:port« fonctionne simplement » depuis les applications Windows. - Ce forwarding est conditionnel. Il peut se casser à cause de la politique de pare-feu, des adresses bindées, des filtres VPN, ou si les services n’écoutent que sur
127.0.0.1dans WSL. - L’IPv6 est un perturbateur discret. Beaucoup d’outils préfèrent IPv6 quand il est disponible. Si votre service ne bind que l’IPv4 et que le client tente
::1, vous obtenez des échecs déroutants. - La DNS dans WSL est souvent auto-générée. WSL peut réécrire
/etc/resolv.conf. « Corriger le DNS » manuellement peut marcher jusqu’au prochain redémarrage, puis vous avez une panne déjà vue. - Le mode réseau miroir existe. Dans certaines versions Windows/WSL, vous pouvez mirrorer le réseau hôte dans WSL, réduisant les bizarreries NAT et rendant l’accès entrant plus prévisible.
WSL1 vs WSL2 : même terminal, planète différente
WSL1 : traduction d’appels système, pas de pile réseau séparée
Les processus WSL1 partagent la pile réseau Windows. Quand un processus WSL1 écoute sur 127.0.0.1:8000, c’est effectivement le même loopback que Windows.
Cela rendait « localhost » simple, et introduisait aussi certaines hypothèses Linux de manière subtilement incorrecte (parce que ce n’est pas vraiment Linux).
WSL2 : une VM avec NAT par défaut
WSL2 exécute un vrai noyau Linux dans une VM. La VM obtient sa propre IP, typiquement sur un sous-réseau privé derrière un commutateur virtuel.
Windows est l’hôte. Linux est l’invité. Le NAT est le comportement par défaut.
Cela implique :
- Depuis WSL, l’accès sortant (vers Internet ou le LAN) fonctionne généralement bien parce que le NAT est simple.
- De Windows vers WSL, l’accès entrant est le point délicat parce que vous traversez des stacks.
- Du LAN vers WSL, l’accès entrant est encore plus complexe car vous traversez des stacks puis un NAT.
Chemins du trafic : Windows → WSL, WSL → Windows, WSL → LAN
Client Windows → serveur WSL
Boucle de dev typique : vous lancez un serveur web dans WSL (python -m http.server), puis vous y accédez depuis Windows.
Cela peut marcher via le forwarding localhost ou via l’IP de la VM WSL directement.
Opérationnellement, vous devez savoir lequel vous utilisez :
- En utilisant
localhostdepuis Windows : vous comptez sur Windows qui effectue le transfert de ports vers WSL. - En utilisant l’IP de la VM WSL : vous contournez une partie de la magie, mais la gestion du pare-feu et les IP changeantes deviennent votre problème.
Client WSL → serveur Windows
Classique : outils WSL qui parlent à des services Windows (SQL Server, proxys locaux, agents d’entreprise).
WSL peut souvent atteindre Windows via un nameserver spécial ou la passerelle par défaut. Certains setups utilisent aussi des noms de type host.docker.internal (pas garanti partout).
Serveur WSL → clients LAN
C’est là que des « démos rapides » deviennent semi-production. Vous voulez que des collègues sur le LAN atteignent un service dans WSL.
Sous NAT, vous devez soit :
- Utiliser Windows comme ingress et transférer le trafic vers WSL (portproxy ou comportement de forwarding intégré), ou
- Passer en mode miroir (si disponible et adapté), ou
- Arrêter de faire semblant et exécuter le service sur une vraie VM/hôte/container prévu pour l’exposition au LAN.
Pourquoi localhost fonctionne (quand il fonctionne)
Quand vous tapez localhost:PORT dans un navigateur Windows et qu’un service WSL répond, vous bénéficiez généralement d’une fonctionnalité Windows qui détecte les ports écoutés dans WSL
et redirige les connexions depuis le loopback Windows vers la VM WSL.
Les conditions du chemin heureux ont tendance à être :
- Le service écoute sur une interface WSL accessible depuis Windows (souvent
0.0.0.0ou l’IP de la VM WSL ; parfois127.0.0.1fonctionne selon le forwarding et la version). - Aucune règle du pare-feu Windows ne bloque la connexion entrante sur ce port/interface.
- Aucun pilote de filtre VPN ne ntercepte ou n’altère le trafic loopback/VM d’une manière qui casse le forwarding.
- Le client et le serveur s’accordent sur IPv4 vs IPv6.
En mode miroir, l’histoire change : WSL peut partager le réseau de l’hôte plus directement, donc binder sur 0.0.0.0 dans WSL peut se comporter plus comme « binder sur l’hôte ».
C’est plus proche de ce que les gens supposent.
Blague #1 : Si vous vous sentez inutile, souvenez-vous qu’il y a des gens qui lient des services à 127.0.0.1 et se demandent pourquoi le LAN ne peut pas les atteindre.
Pourquoi localhost ne fonctionne parfois pas
Les échecs se regroupent en quelques catégories. La plupart sont auto-infligés. Le reste vient de « votre pile d’agent d’entreprise fait quelque chose de futé ».
1) Le service est lié à la mauvaise adresse
Lier sur 127.0.0.1 à l’intérieur de WSL signifie « seulement dans le namespace réseau WSL ».
Si le forwarding Windows n’est pas actif ou ne forwarde pas cette liaison, les applis Windows ne l’atteindront pas.
Lier sur 0.0.0.0 (toutes les interfaces) dans WSL est souvent la bonne démarche pour un accès inter-couches.
2) La préférence IPv6 transforme « localhost » en ::1
Certains clients résolvent localhost en ::1 et 127.0.0.1 et tentent IPv6 en premier.
Si votre service est uniquement IPv4, vous pouvez voir un « connection refused » instantané même si l’IPv4 fonctionnerait.
3) Pare-feu Windows (ou contrôles d’endpoint d’entreprise) le bloque
Beaucoup d’ingénieurs traitent le loopback comme « sans pare-feu ». C’est majoritairement vrai sur une seule stack. Mais le trafic WSL2 peut traverser des interfaces virtuelles où des profils de pare-feu s’appliquent.
Les politiques de domaine peuvent aussi restreindre le loopback et l’exposition des ports locaux de manière surprenante.
4) Les clients VPN et les pilotes de filtre rompent le routage/forwarding
Les VPN peuvent :
- Remplacer DNS et routes split-tunnel d’une manière que WSL ne suit pas automatiquement.
- Installer des filtres qui interfèrent avec le trafic du commutateur virtuel Hyper-V.
- Désactiver les comportements d’« accès LAN local » ou traiter les adaptateurs vEthernet comme non fiables.
5) L’IP de WSL a changé
Les IP de VM WSL2 peuvent changer après un redémarrage. Si vous codez en dur l’IP de la VM dans un client Windows, vous construisez une bombe à retardement.
Préférez le forwarding localhost (quand il est fiable), le mode miroir, ou des règles de forwarding stables côté Windows.
6) Vous avez « optimisé » la pile réseau
Désactiver des services, bidouiller la génération de resolv.conf, toucher iptables/nftables, ou modifier la config WSL peut produire un comportement localement cohérent mais globalement cassé.
Le débogage ultérieur ressemble à lire un roman où le méchant est votre ancien vous.
Playbook de diagnostic rapide
L’objectif n’est pas « tout comprendre ». L’objectif est de trouver le goulot d’étranglement en moins de cinq minutes, avec des preuves.
Première étape : identifier quelle stack est en échec
- Depuis WSL : pouvez-vous atteindre le service via le localhost WSL ?
- Depuis Windows : pouvez-vous atteindre le service via le localhost Windows ?
- Depuis Windows : pouvez-vous atteindre le service via l’IP de la VM WSL ?
Cela sépare le problème en « le service n’écoute pas » vs « problème de forwarding/pare-feu/NAT ».
Deuxième étape : confirmer l’adresse bindée et le listener
- Vérifiez l’adresse/port sur laquelle le serveur est lié dans WSL (sortie de
ss). - Vérifiez si Windows écoute/forwarde ce port (sortie
netstatsous Windows).
Troisième étape : vérifier les deux pare-feu et le VPN
- Règles de pare-feu dans WSL (iptables/nftables) si vous en utilisez.
- Profil/règles du pare-feu Windows pour le port et l’interface.
- VPN connecté ? Si oui, testez sans (ou sur un autre réseau) pour isoler.
Quatrième étape : DNS seulement après connectivité
Ne commencez pas par le DNS sauf si le symptôme est une résolution de nom qui échoue. Si la connectivité IP échoue, le DNS est hors sujet.
Tâches pratiques : commandes, sorties et la décision que vous prenez
Les commandes ci-dessous sont conçues pour être exécutables et diagnostiques. Chacune inclut ce que la sortie signifie et la décision à prendre.
Mixez et adaptez. C’est du SRE : mesurer, ne pas improviser.
Task 1: Confirmer si vous êtes sur WSL1 ou WSL2
cr0x@server:~$ uname -r
5.15.133.1-microsoft-standard-WSL2
Signification : Si la chaîne de noyau inclut microsoft-standard-WSL2, vous êtes en WSL2 avec réseau de VM.
Décision : Supposer que les comportements NAT/forwarding s’appliquent. Ne considérez pas localhost comme partagé avec Windows sans vérification.
Task 2: Trouver l’adresse IP de WSL
cr0x@server:~$ ip -brief addr show eth0
eth0 UP 172.24.85.101/20 fe80::215:5dff:fe12:3456/64
Signification : eth0 de WSL a une adresse IPv4 privée. C’est l’adresse que Windows peut utiliser pour atteindre WSL directement.
Décision : Utilisez cette IP pour un test direct depuis Windows. Ne la codez pas en dur pour des workflows à long terme sauf si vous acceptez les changements.
Task 3: Vérifier que le service écoute réellement (et où)
cr0x@server:~$ ss -ltnp | head
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.1:3000 0.0.0.0:* users:(("node",pid=2123,fd=19))
Signification : Le service n’écoute que sur 127.0.0.1:3000 à l’intérieur de WSL. C’est du loopback uniquement dans le namespace réseau de WSL.
Décision : Si Windows ne peut pas l’atteindre, reconfigurez le service pour binder sur 0.0.0.0 (ou sur l’IP de WSL) quand un accès inter-couches est requis.
Task 4: Rebinder un serveur dev sur toutes les interfaces (exemple)
cr0x@server:~$ python3 -m http.server 8000 --bind 0.0.0.0
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
Signification : Le serveur écoute sur toutes les interfaces IPv4, pas seulement le loopback.
Décision : Testez maintenant depuis Windows en utilisant l’IP de WSL et (si applicable) le forwarding localhost Windows.
Task 5: Tester depuis WSL en utilisant localhost
cr0x@server:~$ curl -sS -D- http://127.0.0.1:8000/ | head
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.10.12
Date: Tue, 06 Feb 2026 18:22:11 GMT
Content-type: text/html; charset=utf-8
Content-Length: 1093
Signification : Le service fonctionne à l’intérieur de WSL. L’application est saine.
Décision : Si Windows ne peut pas y accéder, concentrez-vous sur la frontière : forwarding, pare-feu, VPN, IPv6.
Task 6: Tester depuis WSL vers Windows via la passerelle par défaut
cr0x@server:~$ ip route | head -n 3
default via 172.24.80.1 dev eth0
172.24.80.0/20 dev eth0 proto kernel scope link src 172.24.85.101
Signification : La passerelle par défaut (souvent l’interface virtuelle côté hôte) est 172.24.80.1.
Décision : Quand WSL doit atteindre un service Windows, cette IP de passerelle est une première tentative utile.
Task 7: Vérifier la configuration DNS dans WSL
cr0x@server:~$ cat /etc/resolv.conf
nameserver 172.24.80.1
search corp.example
Signification : WSL pointe le DNS vers un résolveur fourni par l’hôte. Les changements VPN peuvent affecter la capacité de ce résolveur à atteindre les DNS d’entreprise.
Décision : Si la résolution de noms échoue mais que la connectivité IP fonctionne, corrigez le DNS (ou l’intégration VPN). Ne le touchez pas si la connectivité elle-même est cassée.
Task 8: Valider rapidement la résolution de noms
cr0x@server:~$ getent hosts github.com | head -n 1
140.82.121.4 github.com
Signification : La résolution DNS fonctionne au moins pour cette requête.
Décision : Si votre problème est « impossible d’atteindre le service par nom », essayez l’IP du service ensuite. Si cela échoue, concentrez-vous sur le DNS/VPN/resolv.conf.
Task 9: Vérifier si WSL peut atteindre le LAN (sanité routage/NAT)
cr0x@server:~$ ping -c 2 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=115 time=12.4 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=115 time=11.9 ms
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
Signification : La connectivité sortante fonctionne. Le NAT et le routage ne sont pas totalement cassés.
Décision : Si l’entrée Windows→WSL échoue alors que la sortie marche, vous avez probablement un problème de pare-feu/forwarding/bind.
Task 10: Confirmer l’état d’écoute côté Windows depuis WSL (sonde rapide)
cr0x@server:~$ nc -vz 172.24.80.1 445
Connection to 172.24.80.1 445 port [tcp/microsoft-ds] succeeded!
Signification : Vous pouvez atteindre un service Windows (SMB dans cet exemple) à l’IP passerelle.
Décision : Si WSL ne peut pas atteindre du tout les services Windows, suspectez des politiques VPN/pare-feu sur l’hôte ou un commutateur virtuel cassé.
Task 11: Vérifier les règles pare-feu WSL (iptables) si vous les utilisez
cr0x@server:~$ sudo iptables -S | head
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
Signification : Politiques par défaut ACCEPT ; WSL lui-même ne bloque pas l’entrée.
Décision : Si les politiques sont DROP/REJECT, corrigez-les ou videz temporairement les règles pendant le débogage. Si ACCEPT, passez au pare-feu/forwarding Windows.
Task 12: Vérifier écoute IPv6-only ou IPv4-only
cr0x@server:~$ ss -ltn | grep -E ':3000|:8000'
LISTEN 0 4096 0.0.0.0:8000 0.0.0.0:*
LISTEN 0 4096 [::1]:3000 [::]:*
Signification : Le port 8000 écoute sur IPv4 toutes interfaces ; le port 3000 écoute seulement sur le loopback IPv6.
Décision : Si un client Windows tente IPv4 et échoue, activez l’écoute IPv4 ou testez explicitement en IPv6 quand c’est pertinent.
Task 13: Inspecter le forwarding Windows→WSL en testant l’IP de WSL (du point de vue de WSL)
cr0x@server:~$ curl -sS -D- http://172.24.85.101:8000/ | head
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.10.12
Date: Tue, 06 Feb 2026 18:24:51 GMT
Content-type: text/html; charset=utf-8
Content-Length: 1093
Signification : Le service répond sur l’IP de la VM WSL. C’est bon pour l’accès direct depuis Windows et pour tout mécanisme de forwarding.
Décision : Si localhost:8000 depuis Windows échoue mais que l’IP de WSL fonctionne depuis Windows, le problème est spécifiquement le forwarding localhost.
Task 14: Attraper l’erreur « ça marche sur localhost WSL mais pas sur eth0 »
cr0x@server:~$ curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/
200
cr0x@server:~$ curl -sS -o /dev/null -w '%{http_code}\n' http://172.24.85.101:3000/
curl: (7) Failed to connect to 172.24.85.101 port 3000 after 0 ms: Connection refused
Signification : Le service n’écoute que sur le loopback. C’est pourquoi la connexion via l’IP de la VM échoue.
Décision : Reconfigurez l’adresse bindée du service. Ne « corrigez » pas les pare-feu pour un service qui n’écoute pas là où vous pensez.
Task 15: Identifier l’interface et le MTU (bizarreries liées au VPN)
cr0x@server:~$ ip link show eth0 | sed -n '1,2p'
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 00:15:5d:12:34:56 brd ff:ff:ff:ff:ff:ff
Signification : Le MTU est 1500. Si un VPN d’entreprise réduit le MTU et que WSL ne s’aligne pas, vous pouvez obtenir un comportement « certains sites marchent, d’autres se bloquent ».
Décision : Si vous suspectez des trous MTU, testez avec des paquets plus petits (ou ajustez le MTU) plutôt que de changer le DNS au hasard.
Task 16: Sanité rapide du chemin paquet avec traceroute
cr0x@server:~$ traceroute -n -m 3 1.1.1.1
traceroute to 1.1.1.1 (1.1.1.1), 3 hops max, 60 byte packets
1 172.24.80.1 0.295 ms 0.260 ms 0.250 ms
2 192.168.1.1 1.987 ms 1.912 ms 1.901 ms
3 1.1.1.1 9.812 ms 9.766 ms 9.742 ms
Signification : Vous voyez la passerelle hôte, puis la passerelle LAN, puis la destination. C’est attendu pour une connectivité de type NAT.
Décision : Si le saut 1 échoue, votre réseau virtuel WSL est cassé. Si le saut 2 échoue seulement avec le VPN, la routage/politique VPN est en cause.
Trois mini-récits d’entreprise tirés du terrain
Mini-récit 1 : L’incident causé par une fausse hypothèse
Une équipe produit a construit un environnement de démonstration interne sur des laptops Windows parce que le service des achats était lent et la date butoir approchait.
La stack était une petite API dans WSL2, un client desktop Windows et une UI admin basée navigateur. Ça fonctionnait parfaitement au bureau.
Puis l’équipe est allée chez un client. Le laptop a rejoint un réseau différent, le VPN d’entreprise s’est connecté, et l’UI admin est tombée.
L’API tournait toujours. curl à l’intérieur de WSL renvoyait des 200. Mais le navigateur Windows subissait des timeouts sur localhost.
La mauvaise hypothèse : « localhost est toujours local ». Ils ont supposé que comme Windows atteignait WSL via localhost dans un environnement, c’était un contrat stable.
En réalité, ils dépendaient d’un forwarding que le pilote de filtre VPN a partiellement cassé.
La correction n’était pas sophistiquée. Ils ont changé le serveur dev pour binder sur 0.0.0.0, validé l’accès via l’IP de WSL, et ajouté une règle portproxy côté Windows pour les ports de la démo.
Ils ont aussi documenté une solution de secours : si le VPN est requis, utiliser le mode miroir là où c’est supporté ou garder le navigateur dans WSL (navigateur Linux) pour éviter de traverser la frontière de stacks.
La vraie leçon : si votre système dépend d’une fonctionnalité de confort, traitez-la comme une dépendance. Testez-la sous VPN, politiques de pare-feu et changements réseau — sinon elle vous testera.
Mini-récit 2 : L’optimisation qui s’est retournée contre eux
Une autre équipe avait des téléchargements lents dans WSL. Quelqu’un a « optimisé le DNS » en hardcodant /etc/resolv.conf vers un résolveur public et en désactivant la génération automatique.
Les téléchargements sont devenus plus rapides. Tout le monde a applaudi et n’a plus pensé au reste. C’est comme ça qu’on sait que ça va faire mal plus tard.
Deux semaines plus tard, les ingénieurs ne pouvaient plus résoudre les noms internes depuis WSL lorsqu’ils étaient connectés au VPN d’entreprise.
Windows résolvait bien. WSL pouvait atteindre les IP. Mais tout ce qui nécessitait internal.service.corp échouait.
L’optimisation a échoué parce que WSL contournait désormais la voie DNS fournie par l’hôte/VPN. Le VPN attendait que les noms internes se résolvent via les résolveurs d’entreprise.
Windows obéissait. WSL ignorait. Résultat : une flotte de laptops où des services internes « échouaient aléatoirement ».
Le rollback a été simple : restaurer la génération automatique de /etc/resolv.conf et apprendre aux gens à mesurer au lieu de se lancer dans du cargo-cult.
Pour la performance, ils ont résolu le vrai problème : cache, miroirs d’artefacts, et sortir les téléchargements répétés du chemin critique.
Blague #2 : Rien n’est plus permanent qu’un tweak DNS temporaire qui « juste pour aujourd’hui » a accéléré les choses.
Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une équipe plateforme a standardisé le dev local pour un gros dépôt. Ils n’ont pas combattu WSL ; ils ont écrit un petit script de « sanity réseau » et l’ont intégré à l’onboarding.
Il vérifiait les binds d’écoute, affichait l’IP de WSL, validait que Windows pouvait atteindre les ports clés, et prévenait des listeners IPv6-seuls.
Des mois plus tard, une mise à jour Windows a modifié certains comportements autour de la virtualisation et des profils de pare-feu.
La moitié de l’organisation a commencé à signaler « l’API dev est en panne » parce que localhost depuis Windows ne joignait plus WSL pour certains.
L’autre moitié n’avait aucun problème, bien sûr c’était incohérent.
Le script de sanity a transformé le chaos en triage. Les ingénieurs pouvaient répondre, rapidement et de façon cohérente :
« Le service écoute uniquement sur le loopback WSL. » Ou « Le pare-feu Windows bloque le port forwardé. » Ou « Votre client VPN intercepte l’adaptateur vEthernet. »
L’équipe plateforme n’avait pas besoin d’héroïsme. Elle avait besoin de comparabilité : mêmes vérifications, mêmes sorties, mêmes décisions suivantes.
La correction a été déployée sous forme de changement de config (defaults de bind, plus fallback portproxy documenté) et d’une règle pare-feu Windows one-time pour les ports dev.
« Ennuyeux mais correct » s’échelonne. « Ça marche sur ma machine » n’est pas une stratégie ; c’est une confession.
Erreurs courantes : symptômes → cause racine → correction
1) Symptom : Le navigateur Windows n’atteint pas le service WSL sur localhost, mais curl dans WSL marche
- Cause racine : Service lié à
127.0.0.1dans WSL, et le forwarding Windows→WSL ne le gère pas (ou est bloqué). - Correction : Binder sur
0.0.0.0(ou l’IPeth0de WSL). Retester via l’IP de WSL depuis Windows. Si vous avez besoin de localhost, configurez explicitement un forwarding côté Windows (et la règle pare-feu).
2) Symptom : curl http://localhost:PORT échoue sur Windows, mais curl http://WSL_IP:PORT fonctionne
- Cause racine : Le chemin de forwarding localhost est cassé (mise à jour Windows, pare-feu, pilote filtre VPN, ou intégration désactivée).
- Correction : Utilisez l’IP de WSL pour les tests locaux, ou configurez un listener Windows stable qui forwarde vers WSL. Si le mode miroir est disponible et compatible, envisagez de l’activer.
3) Symptom : Ça marche jusqu’à la connexion VPN, puis WSL perd la résolution de noms
- Cause racine : WSL DNS pointe quelque part qui ne peut pas résoudre les zones internes sous la politique VPN, ou
resolv.confa été personnalisé en contournant le DNS d’entreprise. - Correction : Restaurez la génération automatique de
/etc/resolv.conf. Si la politique l’exige, utilisez le résolveur fourni par le VPN ou configurez le DNS par interface de façon supportée.
4) Symptom : Timeouts aléatoires, surtout pour de gros téléchargements, seulement sur certains réseaux
- Cause racine : Mismatch MTU ou problèmes de path MTU discovery dus au VPN, tunnels ou filtrage.
- Correction : Testez avec des paquets plus petits ; alignez les réglages MTU si possible. Si vous ne pouvez pas contrôler, contournez le problème (réseau différent, politique split tunnel, ou mode miroir si cela change le chemin).
5) Symptom : Les appareils du LAN ne peuvent pas atteindre un service dans WSL, mais Windows oui
- Cause racine : Frontière NAT. La VM WSL n’est pas directement joignable depuis le LAN, et Windows ne forwarde pas le port à l’extérieur.
- Correction : Exposez le port sur Windows (règle pare-feu entrante + forwarding vers WSL). Ou arrêtez d’utiliser WSL pour des services exposés au LAN et déployez dans un environnement approprié.
6) Symptom : « Connection refused » au lieu d’un timeout
- Cause racine : Pas de listener sur cet IP:port (mauvaise adresse bind, mauvais port, mismatch IPv6/IPv4).
- Correction : Vérifiez les listeners avec
ss -ltnp. Corrigez le bind. Si le listener existe seulement en IPv6, testez[::1]ou activez l’IPv4.
7) Symptom : « Timeout » au lieu de refused, alors que le service écoute
- Cause racine : Pare-feu qui droppe (pare-feu Windows, protection endpoint, politique VPN), ou chemin de routage cassé.
- Correction : Testez depuis Windows vers l’IP de WSL ; vérifiez les règles pare-feu ; déconnectez temporairement le VPN pour isoler. Ne touchez pas à l’appli tant que vous n’avez pas prouvé que les paquets atteignent la VM.
Listes de vérification / plan pas à pas
Checklist A : Vous voulez que les applis Windows atteignent un service WSL de manière fiable
- Binder raisonnablement : configurez le service WSL pour écouter sur
0.0.0.0(ou l’IP de WSL), pas seulement sur127.0.0.1. - Prouvez-le localement : depuis WSL,
curl http://127.0.0.1:PORTetcurl http://WSL_IP:PORT. - Test depuis Windows en utilisant l’IP de WSL : si cela échoue, vous avez un problème de pare-feu ou de routage. Corrigez-le avant de vous inquiéter de la magie localhost.
- Décidez de votre méthode d’accès :
- Privilégiez le forwarding localhost Windows quand il est stable dans votre environnement.
- S’il n’est pas stable, utilisez un forwarding explicite côté Windows et documentez-le.
- Renforcez pour la réalité d’entreprise : testez avec le VPN connecté et déconnecté ; testez aussi sur un réseau Wi‑Fi invité.
Checklist B : Vous voulez que des appareils LAN atteignent quelque chose tournant dans WSL
- Demandez-vous « devons-nous ? » Si c’est plus qu’une démo, déployez correctement.
- Si vous poursuivez : exposez un port sur Windows (règle pare-feu entrante + forwarding vers WSL).
- Choisissez un port stable : n’utilisez pas des ports éphémères élevés qui entrent en conflit avec des outils dev.
- Journalisez et surveillez : si le service compte, ajoutez au moins des logs d’accès et un endpoint de santé.
Checklist C : Problèmes DNS sous VPN
- Testez la connectivité IP en premier. Si vous ne pouvez pas pinguer une IP, le DNS n’est pas le principal souci.
- Vérifiez la génération de
/etc/resolv.conf. Si elle est manuellement fixée, attendez-vous à de la dérive et de la douleur. - Testez la résolution avec
getent. Cela teste le comportement du résolveur système, pas seulement un outil isolé. - Alignez-vous sur la politique. Si le VPN d’entreprise exige le DNS d’entreprise, ne « corrigez » pas avec des résolveurs publics en espérant le meilleur.
FAQ
1) WSL2 est‑il fondamentalement une VM ? Dois‑je le traiter comme tel ?
Oui. C’est une VM légère avec un vrai noyau Linux. Traitez le réseau comme du réseau de VM : pile séparée, NAT par défaut, et une frontière qui demande une gestion explicite.
2) Pourquoi Windows peut parfois atteindre les services WSL via localhost ?
Windows peut forwarder des connexions depuis son loopback vers WSL. Quand ça marche, on a l’impression d’un localhost partagé. Quand ça ne marche pas, on se rappelle que ce n’est pas le cas.
3) Pourquoi binder sur 127.0.0.1 dans WSL casse l’accès depuis Windows ?
Parce que 127.0.0.1 est le loopback du namespace réseau WSL, pas de Windows. Si le forwarding ne traduit pas cette liaison, Windows ne peut pas y accéder. Binder sur 0.0.0.0 pour un accès inter‑stack.
4) Dois‑je toujours binder les serveurs dev sur 0.0.0.0 dans WSL ?
Si vous avez besoin d’accès depuis Windows (ou le LAN), oui. Si vous n’avez besoin que d’un accès interne à WSL, liez sur le loopback pour réduire l’exposition. Décidez intentionnellement, pas par habitude.
5) Pourquoi ça ne marche que lorsque je me connecte au VPN ?
Les VPN changent routes, DNS, et parfois installent des pilotes de filtre qui perturbent les adaptateurs virtuels. Si la panne coïncide avec le VPN, isolez en testant sans VPN et comparez DNS et routes.
6) Pourquoi localhost se résout parfois en IPv6 et casse mon service ?
Beaucoup de clients préfèrent IPv6 et tentent ::1 en premier. Si votre service est IPv4-only, vous verrez des échecs même si IPv4 fonctionnerait. Assurez-vous que votre service écoute sur les deux ou testez explicitement avec 127.0.0.1.
7) Puis‑je rendre l’IP de WSL statique ?
Dans le modèle NAT par défaut, l’IP de la VM WSL peut changer. Vous pouvez automatiser la découverte, utiliser un forwarding côté Windows, ou passer en mode miroir où c’est pertinent. Une « IP WSL statique » est souvent un piège.
8) Pourquoi WSL peut atteindre Internet mais Windows ne peut pas atteindre WSL ?
Le NAT rend la sortie facile. L’entrée nécessite des listeners, les bons binds et des règles pare‑feu. Direction différente, règles différentes. Diagnostiquez l’entrée séparément.
9) Le mode miroir est‑il toujours meilleur ?
Il peut réduire la confusion et simplifier l’accès entrant, mais il change l’exposition et interagit différemment avec la politique réseau d’entreprise. Testez-le dans votre environnement avant de le standardiser.
10) Quelle habitude opérationnelle empêche la plupart des pannes réseau WSL ?
Vérifiez toujours « où j’écoute ? » en utilisant ss -ltnp et testez toujours des deux côtés (WSL et Windows) avant de déclarer victoire.
Conclusion : prochaines étapes pratiques
Le réseau WSL devient prévisible quand vous arrêtez d’anthropomorphiser localhost. Dans WSL2, vous traversez une frontière de VM.
Parfois Windows lisse la frontière. Parfois le VPN, la politique de pare‑feu, ou une adresse bind innocente ramènent la réalité.
Prochaines étapes qui tiennent en contexte production‑adjacent dev :
- Standardisez les binds des listeners : pour les services devant être accessibles depuis Windows, liez sur
0.0.0.0dans WSL et documentez‑le. - Adoptez le playbook de diagnostic rapide : WSL localhost, Windows localhost, IP de WSL. Ne vous improvisez pas.
- Testez sous VPN : si votre organisation l’utilise, c’est votre « normal », pas un cas marginal.
- Privilégiez les outils ennuyeux : un petit script de sanity qui affiche listeners, IPs et état DNS évite des heures d’archéologie Slack.
« L’espoir n’est pas une stratégie. » — General Gordon R. Sullivan