Une application dans un espace de noms VPN est injoignable depuis le LAN
Un espace de noms réseau donne à un programme son propre tunnel et sa propre boucle locale. Ne publiez que son port avec un saut socat ou une paire veth plutôt que l’hôte.
Votre service fonctionne sur la machine, le tunnel est monté, et pourtant le navigateur de votre bureau attend toujours une réponse. Rien n’est cassé au sens habituel : l’application écoute dans un espace de noms réseau, et cette pile est invisible pour le LAN. Sa boucle locale appartient à l’espace de noms, donc un client sur une autre machine n’a aucune adresse qui atteint le port. Un saut délibéré, ou une paire veth, corrige cela sans déplacer le reste de l’hôte.
Pourquoi rien ne répond à l’adresse du LAN
Un espace de noms est une pile réseau complète : interfaces, routes, règles de pare-feu et une boucle locale privée. Un processus lancé via ip netns exec ne voit que cette pile, donc l’adresse à laquelle il se lie n’est résolue qu’à l’intérieur de l’espace de noms. Le 127.0.0.1 de l’hôte est une boucle locale entièrement différente.
C’est pourquoi curl échoue sur l’hôte alors que la même commande réussit dans l’espace de noms. L’application est saine ; l’adresse n’existe simplement pas dans la pile de l’hôte.
Publier un seul port avec un saut socat
socat fait le pont entre les deux piles dans l’espace utilisateur, ce qui suffit quand un seul port TCP doit traverser. Le côté hôte écoute sur le LAN et, pour chaque connexion acceptée, lance un second socat dans l’espace de noms qui se connecte à la boucle locale de l’application. Le processus interne atteint l’application exactement comme le ferait un client local. Rien ne change dans le routage de l’espace de noms, donc l’application continue d’utiliser le tunnel comme unique sortie.
socat TCP-LISTEN:9100,reuseaddr,fork EXEC:'ip netns exec vpn socat STDIO tcp-connect:127.0.0.1:9100',nofork
Le processus externe a besoin de root ou de la capacité d’entrer dans l’espace de noms. Si le VPN tombe, l’application perd son chemin et le port publié échoue fermé, ce qui est le comportement attendu d’une prison.
Utiliser une paire veth quand plusieurs ports traversent
Une paire veth est la bonne réponse quand plusieurs ports ou protocoles doivent traverser, ou quand d’autres hôtes doivent initier des connexions. Une extrémité reste dans l’hôte, l’autre passe dans l’espace de noms, et un petit /30 donne aux deux côtés une adresse stable. Une route d’hôte envoie ensuite l’adresse de l’espace de noms par la paire.
ip link add veth0 type veth peer name veth1
ip link set veth1 netns vpn
ip addr add 10.77.0.1/30 dev veth0
ip link set veth0 up
ip netns exec vpn ip addr add 10.77.0.2/30 dev veth1
ip netns exec vpn ip link set veth1 up
N’ajoutez pas de route par défaut via l’hôte, sauf si vous voulez briser la prison. Le tunnel doit rester la sortie, donc seule l’adresse du service publié est joignable par la paire. Donnez aussi à l’espace de noms son propre fichier de résolution, car ip netns exec lit /etc/netns/vpn/resolv.conf et sans lui la résolution de noms dans la prison est vide.
Testez depuis une autre machine, pas depuis l’hôte
Lancez le test depuis une seconde machine, car l’hôte peut atteindre un écouteur local par des chemins qui ne disent rien du LAN. Vérifiez d’abord ce à quoi l’application s’est réellement liée dans l’espace de noms, puis connectez-vous depuis l’extérieur à l’adresse publiée. Se lier à toutes les adresses ici n’élargit pas la prison, car le joker appartient toujours à l’espace de noms et le LAN ne peut pas le voir.
ip netns exec vpn ss -lntp
Si la connexion depuis l’hôte fonctionne et que celle depuis le LAN échoue, la pièce manquante est le saut ou la route, pas l’adresse de liaison. Démarrez OpenVPN dans l’espace de noms au lieu d’y déplacer un périphérique tun actif, car déplacer l’interface la coupe et peut effacer des routes que vous ne pourrez plus réparer de l’extérieur. Gardez les commandes de récupération sur la console, pas dans la prison.