web-dev-qa-db-fra.com

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

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?)

11
ddewaele

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 autre périphérique 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 définir le sysctl ip_forward sur 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 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 acheminé:

$ 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
7
Huygens