Autoriser les conteneurs Docker à se connecter aux clients OpenVPN sur l'interface du tunnel hôte

12

J'ai la configuration suivante:

  • Un hôte CentOS exécutant le service Docker
  • Un réseau de pont Docker défini par l'utilisateur
  • 2 conteneurs Docker connectés à ce réseau de ponts défini par l'utilisateur
  • Une installation OpenVPN (en cours d'exécution sur l'hôte. Peut également s'exécuter dans un conteneur Docker)
  • Certains clients connectés à OpenVPN

Comment puis-je autoriser les conteneurs Docker du réseau Docker Bridge à communiquer avec les clients OpenVPN sur le réseau Tun0?

Je voudrais pouvoir avoir une communication basée sur TCP entre Docker1 (10.10.0.3) et les clients connectés au VPN (gamme 172.19.0.x) de manière transparente.

Que dois-je configurer du côté docker (réseau / iptables / ...) et sur l'hôte (iptables?)

ddewaele
la source
1
Peut-être en retard, mais dans votre cas, je crois que vous avez besoin tap, écrou tun, je travaille dessus depuis plus de 12 heures sans succès jusqu'à présent.
Mohammed Noureldin
@MohammedNoureldin avez-vous trouvé une solution? J'envisage également d'aller appuyer sur l'appareil. Ce qui est frustrant, c'est que depuis le conteneur ovpn, je peux accéder aux clients vpn. Et à partir de clients VPN, je peux accéder aux autres conteneurs sur le même réseau Docker. Mais la transmission entre «eth0» et tun0 à l'intérieur du conteneur ovpn ne fonctionne pas. Je suppose que c'est dû à la nature de tun0 vs tap.
Huygens
@Huygens, oui je l'ai résolu, veuillez poser une question séparée et me donner une référence et je ferai de mon mieux pour vous aider.
Mohammed Noureldin
1
Salut @MohammedNoureldin J'ai trouvé les 2 instructions manquantes pour que cela fonctionne. Ils étaient dans les pages de manuel openvpn 👍. Je posterai bientôt une réponse à cette question pour les autres.
Huygens
1
@Huygens, bon à savoir, en fait, je n'ai pas encore eu le temps de poster la réponse, mais je suis intéressé de voir ce qui a fonctionné pour votre cas.
Mohammed Noureldin

Réponses:

7

Le contexte

J'utilise le très bon conteneur Docker de Kyle Manna ( https://github.com/kylemanna/docker-openvpn ). J'utilise la documentation dite "paranoïaque" pour configurer mon serveur OpenVPN, mais à mon avis, cela devrait être la méthode standard et non la méthode paranoïaque.

Configuration

Afin de permettre une connexion bidirectionnelle entre les conteneurs Docker sélectionnés et les clients VPN, vous devez créer un réseau Docker sur lequel vous allez attacher un conteneur auquel les clients VPN devraient pouvoir accéder. Le serveur VPN va être l'un de ces conteneurs.

Le serveur VPN doit avoir le client-to-client, topology subnet, dev tun0(ou tout autre dispositif de tun) et push "route <docker net IP> <docker net mask>"configuré.

L'hôte du serveur VPN doit être configuré pour prendre en charge le transfert de paquets IP d'un sous-réseau à un autre. Cela signifie mettre le sysctl ip_forward à 1 (ce devrait être le cas si vous avez installé Docker), autoriser les paquets du périphérique tun à passer par la chaîne iptables FORWARD et définir le routage approprié. Cela peut être résumé par ces commandes:

$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ sudo ip route add 192.168.255.0/24 via <IP address of OpenVPN server container>

Quoi qu'il en soit, voici les options que j'ai utilisées pour configurer le serveur:

$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://<FQDN> -N -d -c -p "route <docker net IP> <docker net range>" -e "topology subnet"

Cela devrait générer un fichier de configuration du serveur similaire à:

server 192.168.255.0 255.255.255.0
verb 3
key /etc/openvpn/pki/private/vpn.example.com.key
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/vpn.example.com.crt
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/pki/ta.key
key-direction 0
keepalive 10 60
persist-key
persist-tun

proto udp
# Rely on Docker to do port mapping, internally always 1194
port 1194
dev tun0
status /tmp/openvpn-status.log

user nobody
group nogroup
client-to-client

### Push Configurations Below
push "dhcp-option DNS 8.8.8.8"
push "route 172.20.20.0 255.255.255.0"

### Extra Configurations Below
topology subnet

Exemple concret

Je vais maintenant prendre un exemple concret. Dans cet exemple, je vais exécuter le serveur OpenVPN mentionné ci-dessus dans Docker sur l'hôte vpn.example.com. Ce conteneur est attaché au réseau Docker docker-net-vpn. Voici les commandes (dans cet exemple, je génère la configuration du serveur directement sur le serveur et j'ignore la génération CA, veuillez plutôt suivre la documentation paranoïaque du projet mentionné ci-dessus):

$ docker network create --attachable=true --driver=bridge --subnet=172.20.20.0/24 --gateway=172.20.20.1 docker-net-vpn
$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://vpn.example.com -N -d -c -p "route 172.20.20.0 255.255.255.0" -e "topology subnet"
$ docker run --detach --name openvpn -v $PWD/files/openvpn:/etc/openvpn --net=docker-net-vpn --ip=172.20.20.2 -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn:2.4
$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ sudo ip route add 192.168.255.0/24 via 172.20.20.2

La première commande crée un nouveau réseau Docker dédié qui définit un nouveau sous-réseau. Nous attacherons le serveur OpenVPN à ce réseau.

Le second crée la configuration OpenVPN en utilisant le même sous-réseau que celui défini dans la 1ère commande.

Le troisième crée le serveur OpenVPN. Il est attaché au réseau Docker nouvellement créé et utilise une adresse IP fixe.

Les quatrième et cinquième commandes configurent le transfert IP.

La dernière commande ajoute une nouvelle route vers la configuration du client VPN via l'IP fixe du conteneur OpenVPN.

Remarque

Je ne l'ai pas essayé, mais il devrait être possible de restreindre la règle FORWARD pour iptables. La création du réseau Docker a créé un nouveau périphérique de pont. Ce pont est nommé br-<ID>avec l'ID étant les 12 premiers caractères de l'ID réseau Docker. Cet ID peut être obtenu avec docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12. Par conséquent, la commande suivante est peut-être plus restrictive (donc meilleure sur le plan de la sécurité) mais devrait toujours permettre à notre trafic d'être routé:

$ NET_VPN_BRIDGE="br-$(docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12)"
$ sudo iptables -A FORWARD -i tun+ -o ${NET_VPN_BRIDGE} -j ACCEPT
Huygens
la source
Hé, je ne peux pas faire fonctionner cela, je peux tracerote à 192.168.255.6 et j'obtiens:, 1 gnet (172.20.20.1) 1966.269 ms !H 1966.248 ms !H 1966.239 ms !Hmais je ne peux pas cingler ou atteindre les ports ouverts.
GuySoft
Bonjour @GuySoft, ce que traceroute rapporte, c'est que votre dernier saut (172.20.20.1) ne peut pas atteindre l'hôte 192.168.255.6. Cela signifie donc que votre table de routage est probablement incorrecte. Pouvons-nous discuter pour voir où est le problème?
Huygens
Il a commencé à fonctionner, je pense que ce qui s'est passé, c'est que les deux machines avaient un docker installé, et les deux avaient un sous-réseau 172.20.20.1, ce qui faisait que les choses se heurtaient, je dois trouver un moyen de faire en sorte que docker ne crée pas un sous-réseau qui se heurterait sur la machine cliente .
GuySoft
Si vous utilisez Docker Compose, vous pouvez spécifier la plage d'adresses IP que le réseau doit utiliser. Voir la documentation Compose. Il est également possible de le faire à partir de la ligne de commande avec docker network….
Huygens
Je pense que je ne reçois pas la partie où une connexion à l'hôte (hôte IP + port openvpn) est acheminée vers le conteneur openvpn (172.20.20.2)
jtomasrl