Soit le script suivant (inspiré de cet article sur Stackoverflow)
Contenu
Utiliser un named pipe combiné à un serveur netcat pour écouter des messages sur localhost
Si vous n’êtes pas familier des named pip, lisez cet article sur les named pipe
#!/bin/sh
request=pipe
rm "$request"
mkfifo "$request"
HandleCommand () {
echo "received command: $1"
[ "$1" = "exit" ] && return 1
return 0
}
while :; do
while read line; do
HandleCommand "$line" || break
done <"$request" | nc -l -p 5000 >"$request"
done
Pour la première démonstration de ce script on se mettra en wsl dans le répertoire /home/refschool pour faire fonctionner le script, car il faut veiller à ce qu’on soit dans un système de fichier Linux pour pouvoir créer un named pipe.
De plus on utilisera le tutoriel Tmux pour avoir un multifenêtrage dans une seule console.
Le script ci-dessus va effacer un named pipe appelé « pipe », et aussitôt en recréer un, puis entre dans une boucle infinie pour écouter sur le port 5000 du serveur netcat (nc)
On va ouvrir tmux et créer deux panneaux verticaux avec le raccourcis CTRL + B puis « % », et pour basculer d’un panneau à l’autre, utiliser le raccourcis CTRL +B puis « o », le premier panneau servira à exécuter le script shell, et le second servira à entrer des messages au serveur netcat.
Donc dans le premier panneau on va lancer le script shell, et on bascule vers le second panneau avec le raccourci CTRL + B puis « o », une fois dans le second panneau, on va se connecter au serveur netcat sur le port 5000
nc localhost 5000 // ensuite dans le même panneau entrez des textes hello bonjour puis entrez exit qui sera interprété par le script shell comme une interruption du programme.
Dans ce qui a précédé, le serveur netcat écoutait sur la boucle locale localhost, ou 127.0.0.1 ou loopback. Mais un autre ordinateur sur le même réseau LAN ou WIFI ne peut pas s’y connecter. Pour ce faire il faudrait démarrer netcat pour écouter sur 0.0.0.0 (tous les interfaces du LAN), mais pas d’Internet bien sûr et ce pour plusieurs raisons :
- votre ordinateur est derrière un routeur (votre box si vous êtes chez vous), il faut utiliser le port forwarding
- il se peut aussi que le firewall de Windows bloque le port 5000 (hypothétique)
Vous pouvez utiliser un tunnel pour créer une connexion avec le monde extérieur.
Ecouter les messages d’ordinateur du même réseau domestique
Votre serveur netcat va démarrer sur votre poste, donc il est utile de connaitre son adresse IP dans le LAN avec cette commande
ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1404 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:d9:5f:23 brd ff:ff:ff:ff:ff:ff
inet 172.18.104.160/20 brd 172.18.111.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::215:5dff:fed9:5f23/64 scope link
valid_lft forever preferred_lft forever
Remarquez que l’adresse IP affichée ici (en rapport avec eth0) es 172.18.104.160, vous vous attendez à une adresse du type 192.168.1.xx, c’est parce que on est à l’intérieur de WSL, et que cette adresse est interne à WSL.
Pour connaitre l’adresse IP de l’hôte avec ipconfig:
C:\Users\admin>ipconfig Configuration IP de Windows Carte Ethernet Ethernet 2 : Suffixe DNS propre à la connexion. . . : lan Adresse IPv4. . . . . . . . . . . . . .: 192.168.1.151 Masque de sous-réseau. . . . . . . . . : 255.255.255.0 Passerelle par défaut. . . . . . . . . : 192.168.1.254 Carte inconnue Connexion au réseau local : Statut du média. . . . . . . . . . . . : Média déconnecté Suffixe DNS propre à la connexion. . . : Carte Ethernet vEthernet (Default Switch) : Suffixe DNS propre à la connexion. . . : Adresse IPv6 de liaison locale. . . . .: fe80::302e:b41d:9890:f78f%41 Adresse IPv4. . . . . . . . . . . . . .: 172.25.144.1 Masque de sous-réseau. . . . . . . . . : 255.255.240.0 Passerelle par défaut. . . . . . . . . : Carte Ethernet vEthernet (WSL) : Suffixe DNS propre à la connexion. . . : Adresse IPv6 de liaison locale. . . . .: fe80::94b8:a9bc:705a:2d44%55 Adresse IPv4. . . . . . . . . . . . . .: 172.18.96.1 Masque de sous-réseau. . . . . . . . . : 255.255.240.0 Passerelle par défaut. . . . . . . . . :
Maintenant nous allons corriger le script shell pour que netcat écoute sur toutes les interfaces, j’appelle ce fichier
#!/bin/sh
request=pipe
rm "$request"
mkfifo "$request"
HandleCommand () {
echo "received command: $1"
[ "$1" = "exit" ] && return 1
return 0
}
while :; do
while read line; do
HandleCommand "$line" || break
done <"$request" | nc -l -p 5000 -s 0.0.0.0 >"$request"
done
A la ligne 15, nc (netcat) écoute sur toutes les interfaces, donc les ordinateurs du réseau local vont pouvoir communiquer avec mon serveur nc
Je vais utiliser mon Macbook pour faire la commande nc pour me connecter au serveur netcat.
nc 172.18.104.160 5000 mais rien ne se passe !
Souvenez vous que 172.18.104.160 est une adresse IP de WSL, ce n’est pas l’hôte (Windows) qui a l’adresse 192.168.1.151. Donc il faut que le Macbook se connect à cette dernière adresse. Mais ce n’est pas tout, le Macbook se connectant à 192.168.1.151, il faut que le message parviennet au 172.18.104.160. On obtient cette redirect par ce qu’on appelle la redirection de port, port forwarding de Windows à WSL. Pour ce faire il faut s’aider de Powershell en mode administrateur
Redirection de port avec Powershell
Ajout d’une règle de port forwarding
Powershell est asse imbittable comme syntaxe !
netsh interface portproxy add v4tov4 listenport=5000 listenaddress=0.0.0.0 connectport=5000 connectaddress=172.18.104.160
Ensuite nous allons agir sur le firewall pour autoriser les connexions sur le port 5000.
Autoriser le port 5000 en écoute sur Windows
New-NetFirewallRule -DisplayName "Allow Port 5000" -Direction Inbound -Protocol TCP -LocalPort 5000 -Action Allow

Je vous conseille de redémarrer le script shell sous WSL et de tester d’abord en local puis depuis le Mac. Si vous ne faites pas le redémarrage, ça ne marche pas.
Pour confirmer le port forwarding sous Windows
netsh interface portproxy show all Listen on IPv4: Connect to IPv4: Address Port Address Port --------------- ---------- --------------- ---------- 0.0.0.0 5000 172.18.104.160 5000
En mpeme temps depuis votre WSL confirmez que le script shell écoute aussi sur le port 5000
ss -tlnp | grep 5000
LISTEN 0 128 0.0.0.0:5000 0.0.0.0:* users:(("nc",pid,fd))
Normalement ça marche depuis le Macbook maintenant ! Mais si nous essayons en même temps de le faire depuis un autre panneau de WSL ça ne marche pas. Par contre coupez toutes les connexions, puis commencez sur WSL ça marche ! mais ensuite vous basculez sur Macbook ça ne marche pas !
Limites de nc et socat à la rescousse
Hé oui nc n’écoute qu’une seule communication à la fois ! nc -l est en mono connexion, il accepte une connexion puis se ferme. Il faudrait une boucle infinie qui lance en continue nc du type
while true; do nc -l -p 5000 -s 0.0.0.0 done
Mais il n’y a pas de parallélisme véritable, c’es séquentiel, donc un peu de lag au final.
Pour avoir du vrai parallélisme, il faut utiliser socat pour faire ce boulot. Donc on va l’installer
sudo apt install socat
// fonctionnement de socat
socat lance un fichier que vous désignez qui va prendre en charge les requêtes, un peu comme >> node server.js
La manipulation consiste à écrire un script shell qui va lire en entrée et faire quelque chose avec ce qui est lu,voici le script handler.sh
#!/bin/bash
echo "Bienvenue sur le serveur !"
while read line; do
echo "Tu as dit : $line"
done
Ensuite nous allons lancer le serveur socat :
socat TCP-LISTEN:5000,reuseaddr,fork EXEC:./handler.sh
En une ligne nous lançons le serveur socat, qui grâce aux paramétrage précédent de Windows (Firewall et translation d’adresse IP) va écouter sur tout le réseau local, depuis le Macbook, je lance
nc 192.168.1.151 5000
bienvenue sur le serveur !
Et on peut envoyer des messages au serveru socat depuis plusieurs clients !
On peut pousser plus loin la chose en mettant la ligne de lancement de socat dans un fichier shell, et consigner les messages dans un fichier de log personnalisé à chaque client.