redirection de port vers l'application dans l'espace de noms du réseau avec vpn

J'ai pu mettre en place un espace de noms réseau, établir un tunnel avec openvpn et démarrer une application qui utilise ce tunnel à l'intérieur de l'espace de noms. Jusqu'ici tout va bien, mais cette application peut être accessible via une interface web et je ne peux pas comprendre comment router les requests vers l'interface web à l'intérieur de mon réseau local.

J'ai suivi un guide de @schnouki expliquant comment mettre en place un espace de noms réseau et lancer OpenVPN à l'intérieur

ip netns add myvpn ip netns exec myvpn ip addr add 127.0.0.1/8 dev lo ip netns exec myvpn ip link set lo up ip link add vpn0 type veth peer name vpn1 ip link set vpn0 up ip link set vpn1 netns myvpn up ip addr add 10.200.200.1/24 dev vpn0 ip netns exec myvpn ip addr add 10.200.200.2/24 dev vpn1 ip netns exec myvpn ip route add default via 10.200.200.1 dev vpn1 iptables -A INPUT \! -i vpn0 -s 10.200.200.0/24 -j DROP iptables -t nat -A POSTROUTING -s 10.200.200.0/24 -o en+ -j MASQUERADE sysctl -q net.ipv4.ip_forward=1 mkdir -p /etc/netns/myvpn echo 'nameserver 8.8.8.8' > /etc/netns/myvpn/resolv.conf 

Après cela, je peux vérifier mon ip externe et get des résultats différents à l'intérieur et à l'extérieur de l'espace de noms, comme prévu:

 curl -s ipv4.icanhazip.com <my-isp-ip> ip netns exec myvpn curl -s ipv4.icanhazip.com <my-vpn-ip> 

L'application est démarrée, j'utilise déluge pour cet exemple. J'ai essayé plusieurs applications avec une interface web pour m'assurer que ce n'est pas un problème spécifique au déluge.

 ip netns exec myvpn sudo -u <my-user> /usr/bin/deluged ip netns exec myvpn sudo -u <my-user> /usr/bin/deluge-web -f ps $(ip netns pids myvpn) PID TTY STAT TIME COMMAND 1468 ? Ss 0:13 openvpn --config /etc/openvpn/myvpn/myvpn.conf 9302 ? Sl 10:10 /usr/bin/python /usr/bin/deluged 9707 ? S 0:37 /usr/bin/python /usr/bin/deluge-web -f 

Je suis capable d'accéder à l'interface web sur le port 8112 à partir de l'intérieur de l'espace de noms et de l'extérieur si je spécifie l'IP de veth vpn1.

 ip netns exec myvpn curl -Is localhost:8112 | head -1 HTTP/1.1 200 OK ip netns exec myvpn curl -Is 10.200.200.2:8112 | head -1 HTTP/1.1 200 OK curl -Is 10.200.200.2:8112 | head -1 HTTP/1.1 200 OK 

Mais je veux redirect le port 8112 de mon server vers l'application dans l'espace de noms. L'objective est d'ouvrir un browser sur un ordinateur à l'intérieur de mon réseau local et d'get l'interface web avec http: // mon-server-ip: 8112 (ip-ip étant l'adresse IP statique du server qui instancie l'interface réseau)

EDIT: J'ai supprimé mes tentatives de création de règles iptables. Ce que j'essaye de faire est expliqué ci-dessus et les commands suivantes devraient produire un HTTP 200:

 curl -I localhost:8112 curl: (7) Failed to connect to localhost port 8112: Connection refused curl -I <my-server-ip>:8112 curl: (7) Failed to connect to <my-server-ip> port 8112: Connection refused 

J'ai essayé les règles DNAT et SNAT et jeté dans un MASQUERADE pour faire bonne mesure, mais comme je ne sais pas ce que je fais, mes tentatives sont vaines. Peut-être que quelqu'un peut m'aider à build cette construction.

EDIT: La sortie tcpdump de tcpdump -nn -q tcp port 8112 . Sans surprise, la première command renvoie un HTTP 200 et la deuxième command se termine par une connection refusée.

 curl -Is 10.200.200.2:8112 | head -1 listning on vpn0, link-type EN10MB (Ethernet), capture size 262144 bytes IP 10.200.200.1.36208 > 10.200.200.2.8112: tcp 82 IP 10.200.200.2.8112 > 10.200.200.1.36208: tcp 145 curl -Is <my-server-ip>:8112 | head -1 listning on lo, link-type EN10MB (Ethernet), capture size 262144 bytes IP <my-server-ip>.58228 > <my-server-ip>.8112: tcp 0 IP <my-server-ip>.8112 > <my-server-ip>.58228: tcp 0 

EDIT: @schnouki lui-même m'a pointé vers un article d'administration de Debian expliquant un proxy TCP iptables générique . Appliqué au problème actuel, leur script ressemblerait à ceci:

 YourIP=<my-server-ip> YourPort=8112 TargetIP=10.200.200.2 TargetPort=8112 iptables -t nat -A PREROUTING --dst $YourIP -p tcp --dport $YourPort -j DNAT \ --to-destination $TargetIP:$TargetPort iptables -t nat -A POSTROUTING -p tcp --dst $TargetIP --dport $TargetPort -j SNAT \ --to-source $YourIP iptables -t nat -A OUTPUT --dst $YourIP -p tcp --dport $YourPort -j DNAT \ --to-destination $TargetIP:$TargetPort 

Malheureusement, le trafic entre les interfaces veth saisies et rien d'autre n'est arrivé. Cependant, @schnouki a également suggéré l'utilisation de socat comme proxy TCP et cela fonctionne parfaitement.

 curl -Is <my-server-ip>:8112 | head -1 IP 10.200.200.1.43384 > 10.200.200.2.8112: tcp 913 IP 10.200.200.2.8112 > 10.200.200.1.43384: tcp 1495 

Je n'ai pas encore compris le brouillage étrange du port pendant que le trafic traverse les interfaces veth, mais mon problème est résolu maintenant.

J'ai toujours eu des problèmes avec les redirections d'iptables (probablement ma faute, je suis à peu près sûr que c'est faisable). Mais pour un cas comme le vôtre, il est plus facile de le faire en user-pays sans iptables.

Fondamentalement, vous devez avoir un démon dans votre espace de travail "par défaut" écoutant sur le port TCP 8112 et redirigeant tout le trafic vers le port 10.200.200.2 8112. C'est donc un simple proxy TCP.

Voici comment le faire avec socat :

 socat tcp-listn:8112,reuseaddr,fork tcp-connect:10.200.200.2:8112 

(L'option fork est nécessaire pour éviter que socat ne s'arrête après la socat de la première connection proxy).

EDIT : ajouté reuseaddr comme suggéré dans les commentaires.

Si vous voulez absolument le faire avec iptables, il existe un guide sur le site d' administration Debian . Mais je préfère toujours le socat pour des choses plus avancées – comme le proxy IPv4 vers IPv6, ou le dépouillement SSL pour permettre aux anciens programmes Java de se connecter à des services sécurisés …

Attention cependant que toutes les connections dans Deluge proviendront de l'adresse IP de votre server au lieu de l'adresse IP réelle du client. Si vous voulez éviter cela, vous devrez utiliser un proxy HTTP réel qui ajoute l'adresse IP d'origine à la requête proxy dans un en-tête HTTP.

L'interconnection de l'espace de noms du réseau avec l'espace de noms principal me dérange toujours. La raison pour laquelle je crée habituellement un espace de noms est parce que je le veux isolé. En fonction de ce que vous essayez d'get, les namespaces créant des interconnections peuvent vaincre cet objective.

Mais même isolé, je veux toujours le pousser sur le réseau, par commodité.

Cette solution vous permet de garder l'isolement et de transmettre certaines connections à tout moment. Vous n'avez pas besoin de créer tout ce réseau entre les deux namespaces réseau pour transférer un seul port. Exécuter ceci dans l'espace de noms où vous voulez accepter les connections. Doit être exécuté en tant que root pour que l' ip netns exec fonctionne.

 socat tcp-listn:8112,fork,reuseaddr \ exec:'ip netns exec myvpn socat STDIO tcp-connect\:127.0.0.1\:8112',nofork 

Il écoute les connections dans un espace de noms réseau où vous l'exécutez, sur le port 8112, puis client connecté obtient exec pour exécuter ip netns exec myvpn ... pour exécuter le rest dans l'espace de noms du réseau myvpn , puis une fois à l'intérieur de l'espace de noms du réseau myvpn deuxième connection à nouveau avec un autre socat .

Pour le déluge voici ma solution. Pas besoin d'iptables. Voici les étapes:

  1. Démarrer votre tunnel openvpn
  2. Créez un espace de noms et apportez votre tunnel openvpn là:
  ip netns append $ NS
 # Attendre que le TUN apparaisse
 tandis que [[$ (ip route | grep $ TUN | wc -l) == 0]];  Dors 1;  terminé
 MY_IP = $ (ip addr affiche $ TUN | grep inet | cut -d '' -f6 | cut -d '/' -f1)
 # La façon dont vous extrayez la passerelle IP peut être différente pour votre connection openvpn
 GATEWAY_IP = $ MY_IP
 # emprisonne mon $ TUN (interface VPN) dans l'espace de noms
 ip link set $ TUN netns $ NS
 # Apportez l'interface avec un sous-réseau (équivalent à celui qui m'a été donné par le server VPN)
 ip netns exec $ NS ifconfig $ TUN $ MY_IP / 24 up
 # Faire remonter la boucle
 ip netns exec $ NS ifconfig lo 127.0.0.1/8 up
 # Configurez la passerelle distante (votre adresse IP VPN pointtopoint)
 ip netns exec $ Route NS append par défaut gw $ GATEWAY_IP 
  1. Établissez veth connection entre votre espace de noms par défaut et celui que vous avez créé:
  # Configurer veth interfaces pour la communication entre les namespaces
 ip link append veth0 type veth nom d'homologue veth1
 # Déplacez le second veth dans votre espace de noms
 ip link set veth1 netns $ NS
 # donner une adresse IP de la plage IP inutilisée à la première veth
 ifconfig veth0 10.1.1.1/24 up
 # Et le second
 ip netns exec $ NS ifconfig veth1 10.1.1.2/24 up
 # TODO: configurez un pont entre veth1 et eth interface pour le laisser communiquer avec le LAN
 # Configurez le client DNS.  ip netns va émuler /etc/resolv.conf en utilisant ce file:
 mkdir -p / etc / netns / $ NS
 echo "nameserver 8.8.4.4"> /etc/netns/$NS/resolv.conf
  1. Exécutez votre deluge dans le file $ NS et votre deluge-web dans votre espace de noms par défaut. Point déluge-web à l'adresse IP 10.1.1.2 veth, où deluged sera à l'écoute de sa connection.

Voila! Vous avez délesté sécurisé derrière le VPN tandis que votre déluge-web est librement accessible sur votre réseau domestique