WSL 2 Port Forwarding : comment accéder à sa machine virtuelle à distance ?

I. Présentation

Dans ce tutoriel, je vais vous expliquer comment configurer Windows 10 pour faire du port forwarding avec WSL 2 et permettre l'accès à distance à notre machine virtuelle Linux.

Comme les autres épisodes, celui-ci est disponible au format vidéo :

Le passage de WSL 1 à WSL 2 s'accompagne de différents changements comme le précise Microsoft sur son site. Parmi ces changements, il y a la manière dont la distribution Linux va accéder au réseau, que ce soit le réseau local ou Internet. Par défaut, on ne peut pas accéder à distance à notre machine virtuelle WSL 2, peu importe la distribution que l'on utilise. Autrement dit, depuis un autre poste de notre réseau local, on ne peut pas se connecter sur notre machine, ni même tester l'accès à un service.

Nous partons du principe que notre distribution Linux gérée par WSL 2 est accessible via RDP sur le port 3390. Pour le moment, cet accès fonctionne uniquement depuis notre machine Windows, en local. L'idée, c'est que l'accès fonctionne à partir d'une autre machine de notre réseau local.

II. Le réseau avec WSL 2

Avant de partir dans la configuration et la résolution de ce problème, faisons un point sur le fonctionnement du réseau avec WSL 2. Lorsqu'une distribution Linux est connectée au réseau via WSL 2, nous obtenons le schéma suivant :

Le réseau avec WSL 2

Un réseau virtuel et privé est créé entre la VM WSL 2 et l'hôte Windows 10. Pour accéder à Internet, la machine Linux passe par l'hôte Windows 10 et le réseau virtuel s'appuie sur du NAT. Sans le NAT, la machine Linux ne pourrait pas accéder à Internet car le routeur ne connaît pas le réseau virtuel.

Dans l'exemple ci-dessus, ma machine Windows 10 bénéficie de l'adresse IP 172.23.240.1/20 tandis que la machine Linux dispose de l'adresse IP 172.23.254.29/20. Les deux machines sont bien sur le même réseau (merci au masque de sous-réseau /20).

Ma machine Windows 10 est également connectée à mon réseau local, via Wi-Fi mais ça pourrait être en câble, dans le but d'avoir Internet.

Pour vérifier ce que je viens de dire, il suffit d'ouvrir une console PowerShell (ou Invite de commande) sur la machine Windows 10 et de regarder les adresses IP.

La carte réseau principale de ma machine (c'est un pont réseau car elle est bridgée et partagée avec Hyper-V) me permettant d'accéder à Internet :

Ma machine Windows 10 bénéficie d'un adaptateur réseau virtuel pour communiquer avec ma machine Linux. Cette carte est créée automatiquement et se nomme "Carte Ethernet vEthernet (WSL)".

Enfin, la machine Linux quant à elle dispose bien d'une adresse IP sur le réseau virtuel évoqué. On peut le vérifier en ligne de commande :

ip add | grep "eth0"

Depuis la machine Windows 10, je peux communiquer avec ma machine WSL. A partir d'une autre machine connectée à mon réseau local, je ne peux pas joindre ma machine WSL 2. Pour le ping, ce n'est pas bien grave, mais c'est plus gênant car on ne peut pas tester une page Web, ou se connecter en RDP. Nous allons apporter une réponse à ce problème.

III. Créer une règle de port forwarding pour WSL 2

Pour le moment, la solution proposée par Microsoft pour répondre à cette problématique consiste à créer une règle de redirection de ports (port forwarding) de la machine Windows 10 vers la machine WSL 2. Cette opération s'effectue avec la commande netsh et les paramètres qui vont bien.

Les commandes qui suivent sont à exécuter en tant qu'administrateur.

Voici la syntaxe de cette commande :

netsh interface portproxy add v4tov4 listenport=<port d'écoute sur la machine Windows 10> listenaddress=0.0.0.0 connectport=<port de destination sur la machine Linux> connectaddress=<adresse IP machine Linux>

Par exemple, si l'on veut que les connexions qui arrivent sur le port d'écoute 3390 (listenport) de notre machine Windows 10 soient redirigés vers le port 3390 (connectport) de notre machine Linux (connectaddress), cela donne :

netsh interface portproxy add v4tov4 listenport=3390 listenaddress=0.0.0.0 connectport=3390 connectaddress=172.23.254.29

Note : le fait d'indiquer "listenaddress=0.0.0.0" permet à notre machine Windows 10 d'écouter sur toutes ses adresses IP. Sinon, il faudrait modifier la règle à chaque fois que la machine Windows 10 change d'adresse IP. A moins que vous utilisiez toujours la même adresse IP sur votre réseau local, mais ce ne sera pas forcément le cas en déplacement.

On peut s'assurer que la règle est bien créée avec la commande suivante :

netsh interface portproxy show v4tov4

D'ailleurs, le résultat retourné est facilement compréhensible.

WSL 2 netsh interface portproxy

A tout moment, vous pouvez supprimer l'ensemble des règles avec la commande ci-dessous :

netsh interface portproxy reset

Il nous reste une dernière étape avant de tester la connexion : créer une règle de pare-feu.

IV. Créer une règle de pare-feu pour autoriser le flux WSL 2

Le flux entrant et sortant sur notre machine Windows 10, avec le port 3390, n'est pas autorisé par défaut par le pare-feu Windows (ou le pare-feu de votre antivirus). Nous devons créer une règle entrante et une règle sortante au sein du pare-feu. Voici les deux commandes à exécuter pour créer ces règles (le port 3390 peut être modifié) :

Les commandes qui suivent sont à exécuter en tant qu'administrateur.

New-NetFireWallRule -DisplayName 'WSL 2' -Direction Outbound -LocalPort "3390" -Action Allow -Protocol TCP
New-NetFireWallRule -DisplayName 'WSL 2' -Direction Inbound -LocalPort "3390" -Action Allow -Protocol TCP

Ces règles seront ensuite visibles via l'interface graphique de Windows 10, dans les paramètres avancés du pare-feu.

Tout est prêt, il ne reste plus qu'à tester une connexion RDP depuis un hôte distant vers notre machine WSL.

Je n'avais pas d'autre PC sous la main pour tester, je l'ai fait directement avec mon smartphone connecté au même Wi-Fi. On peut voir que ça fonctionne parfaitement ! Au niveau de la connexion RDP, j'ai indiqué l'adresse IP de ma machine Windows 10 et le port, ce qui donne : 192.168.5.56:3390.

Pour finir, intéressons-nous à une problématique vous allez forcément rencontrer. 🙂

V. Gérer les règles de pare-feu et redirection automatiquement

A chaque fois que vous allez redémarrer la machine virtuelle WSL 2 ou votre machine hôte, la machine Linux va changer d'adresse IP. C'est contraignant car cela signifie qu'il faudra modifier notre règle de redirection de ports à chaque redémarrage, ainsi que notre règle de pare-feu. Mais rassurez-vous, il existe une solution à l'aide d'un script.

Ce script va venir récupérer l'adresse IP de la carte eth0 de la machine Linux et générer la règle de redirection de ports avec la bonne adresse IP de destination. Les règles de pare-feu sont également créées. A chaque fois que le script est exécuté, toutes les règles sont supprimées et recréées. On retrouve ce script sur certains posts du GitHub WSL, notamment celui-ci.

Voici le script ci-dessous avec des commentaires en français. En fait, il faut modifier la liste des ports ($ports) que vous souhaitez rediriger vers votre machine WSL.

# Récupérer l'adresse IP de la machine Linux WSL
$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';

if( $found ){
  $remoteport = $matches[0];
} else{
  echo "Le script va se fermer car l'adresse IP de la machine WSL 2 est introuvable.";
  exit;
}

# Tous les ports forwarder vers votre machine WSL 2
[email protected](80,443,3390);

# Adresse IP sur laquelle écouter au niveau de la machine Windows 10
$addr='0.0.0.0';
$ports_a = $ports -join ",";

# Supprimer la règle de pare-feu "WSL 2 Firewall Unlock"
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";

# Créer les règles de pare-feu (flux entrant et sortant) avec chacun des ports de $ports
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $ports_a -Action Allow -Protocol TCP";

# Créer les règles de redirection de ports pour chacun des ports ($ports)
for( $i = 0; $i -lt $ports.length; $i++ ){
  $port = $ports[$i];
  iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
  iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
}

Note : si vous utilisez Ubuntu (ou certaines autres distributions), il faudra penser à installer le paquet net-tools pour bénéficier de la commande ifconfig : sudo apt install net-tools

Dans le pare-feu, on voit bien la règle créée par le script, comme toute à l'heure quand on l'a fait manuellement.

Deux options avec ce script : le lancer en tant qu'administrateur à chaque fois que vous avez besoin d'utiliser la machine WSL 2 à distance, ou le mettre dans une tâche planifiée directement. A vous de choisir.

Voilà ! Vous avez entre vos mains toutes les informations nécessaires pour que votre machine Linux WSL 2 soit disponible à distance sur votre réseau local !

N'hésitez pas à poster un commentaire si vous avez une question ou tout simplement pour confirmer que cela a bien fonctionné chez vous. 😉

Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Partager sur Google+ Envoyer par mail

Florian Burnel

Ingénieur système et réseau et cofondateur d'IT-Connect. Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.

florian a publié 3118 articlesVoir toutes les publications de cet auteur

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

 

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.