Ermöglichen Sie Docker-Containern, eine Verbindung zu OpenVPN-Clients auf der Host-Tunnel-Schnittstelle herzustellen


10

Ich habe folgendes Setup:

  • Ein CentOS-Host, auf dem der Docker-Dienst ausgeführt wird
  • Ein benutzerdefiniertes Docker-Bridge-Netzwerk
  • 2 Docker-Container, die mit diesem benutzerdefinierten Bridge-Netzwerk verbunden sind
  • Eine OpenVPN-Installation (wird derzeit auf dem Host ausgeführt. Kann auch in einem Docker-Container ausgeführt werden.)
  • Einige mit OpenVPN verbundene Clients

Wie kann ich zulassen, dass Docker-Container im Docker-Bridge-Netzwerk mit den openvpn-Clients im tun0-Netzwerk kommunizieren?

Ich möchte eine TCP-basierte Kommunikation zwischen Docker1 (10.10.0.3) und Clients, die auf transparente Weise mit dem VPN (Bereich 172.19.0.x) verbunden sind, ermöglichen.

Was muss ich auf der Docker-Seite (Netzwerk / iptables / ...) und auf dem Host (iptables?) Einrichten?


1
Vielleicht zu spät, aber in Ihrem Fall glaube ich, dass Sie es brauchen tap, Nuss tun, ich habe mehr als 12 Stunden daran gearbeitet, ohne Erfolg bis jetzt.
Mohammed Noureldin

@MohammedNoureldin habt ihr eine Lösung gefunden? Ich denke auch darüber nach, jetzt auf Gerät zu tippen. Was frustrierend ist, ist, dass ich aus dem OVN-Container heraus auf die VPN-Clients zugreifen kann. Und von VPN-Clients aus kann ich auf die anderen Container im selben Docker-Netzwerk zugreifen. Die Weiterleitung zwischen "eth0" und "tun0" im ovpn-Container funktioniert jedoch nicht. Ich denke, es liegt an tun0 nature vs. tap.
Huygens

@Huygens, ja, ich habe es gelöst, bitte stellen Sie eine separate Frage und geben Sie einen Hinweis auf mich und ich werde mein Bestes tun, um Ihnen zu helfen.
Mohammed Noureldin

1
Hallo @MohammedNoureldin Ich habe die 2 fehlenden Anweisungen gefunden, damit es funktioniert. Sie waren in offenen Manpages 👍. Ich werde bald eine Antwort auf diese Frage für andere veröffentlichen.
Huygens

1
@Huygens, gut zu wissen, eigentlich hatte ich noch keine Zeit, die Antwort zu posten, aber ich bin interessiert zu sehen, was für Ihren Fall funktioniert hat.
Mohammed Noureldin

Antworten:


7

Kontext

Ich habe den sehr guten Docker-Container von Kyle Manna ( https://github.com/kylemanna/docker-openvpn ) verwendet. Ich verwende die sogenannte "paranoide" Dokumentation, um meinen OpenVPN-Server einzurichten, aber meiner Ansicht nach sollte dies der Standardweg und nicht der paranoide Weg sein.

Aufbau

Um eine bidirektionale Verbindung zwischen ausgewählten Docker-Containern und den VPN-Clients zu ermöglichen, müssen Sie ein Docker-Netzwerk erstellen, an das Sie einen Container anhängen, auf den die VPN-Clients zugreifen dürfen. Der VPN-Server wird einer dieser Container sein.

Der VPN - Server sollte die client-to-client, topology subnet, dev tun0(oder andere tun Device) und push "route <docker net IP> <docker net mask>"konfiguriert.

Der Host des VPN-Servers sollte so konfiguriert sein, dass er die Weiterleitung von IP-Paketen von einem Subnetz in ein anderes unterstützt. Dies bedeutet, dass sysctl ip_forward auf 1 gesetzt wird (dies sollte der Fall sein, wenn Docker installiert ist), damit Pakete vom Tun-Gerät die iptables FORWARD-Kette durchlaufen und das richtige Routing festlegen können. Dies kann mit den folgenden Befehlen zusammengefasst werden:

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

Hier sind die Optionen, mit denen ich den Server eingerichtet habe:

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

Dies sollte eine Serverkonfigurationsdatei generieren, die der folgenden ähnelt:

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

Konkretes Beispiel

Ich werde jetzt ein konkretes Beispiel nehmen. In diesem Beispiel werde ich den oben erwähnten OpenVPN-Server in Docker auf dem Host vpn.example.com ausführen. Dieser Container ist an das Docker-Netzwerk docker-net-vpn angehängt. Hier sind die Befehle (in diesem Beispiel generiere ich die Serverkonfiguration direkt auf dem Server und überspringe die CA-Generierung. Befolgen Sie stattdessen die paranoide Dokumentation des oben genannten Projekts):

$ 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

Der erste Befehl erstellt ein dediziertes neues Docker-Netzwerk, das ein neues Subnetz definiert. Wir werden den OpenVPN-Server an dieses Netzwerk anschließen.

Der zweite erstellt die OpenVPN-Konfiguration mit demselben Subnetz wie im ersten Befehl definiert.

Der dritte erstellt den OpenVPN-Server. Es ist an das neu erstellte Docker-Netzwerk angeschlossen und verwendet eine feste IP.

Der vierte und fünfte Befehl konfigurieren die IP-Weiterleitung.

Der letzte Befehl fügt eine neue Route zur VPN-Client-Konfiguration über die feste IP des OpenVPN-Containers hinzu.

Hinweis

Ich habe es nicht ausprobiert, aber es sollte möglich sein, die FORWARD-Regel für iptables einzuschränken. Bei der Erstellung des Docker-Netzwerks wurde ein neues Bridge-Gerät erstellt. Diese Brücke wird benannt, br-<ID>wobei die ID die ersten 12 Zeichen der Docker-Netzwerk-ID sind. Diese ID erhalten Sie mit docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12. Daher ist der folgende Befehl möglicherweise restriktiver (also in Bezug auf die Sicherheit besser), sollte jedoch weiterhin die Weiterleitung unseres Datenverkehrs ermöglichen:

$ 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

Hey, ich kann das nicht zum Laufen bringen, ich kann auf 192.168.255.6 zurückgreifen und ich bekomme : 1 gnet (172.20.20.1) 1966.269 ms !H 1966.248 ms !H 1966.239 ms !H, aber ich kann nicht pingen oder offene Ports erreichen.
GuySoft

Hallo @GuySoft, was Traceroute meldet, ist, dass Ihr letzter Hop (172.20.20.1) den Host 192.168.255.6 nicht erreichen kann. Dies bedeutet, dass Ihre Routing-Tabelle wahrscheinlich falsch ist. Können wir uns unterhalten, um zu sehen, wo das Problem liegt?
Huygens

Es hat angefangen zu funktionieren. Ich denke, es ist passiert, dass auf beiden Computern Docker installiert war und auf beiden ein Subnetz 172.20.20.1 installiert war, das zu Konflikten führte. Ich muss einen Weg finden, um Docker dazu zu bringen, kein Subnetz zu erstellen, das auf dem Clientcomputer zusammenstößt .
GuySoft

Wenn Sie Docker Compose verwenden, können Sie den IP-Adressbereich angeben, den das Netzwerk verwenden soll. Siehe die Dokumentation zum Verfassen. Es ist auch möglich, dies über die Befehlszeile mit zu tun docker network….
Huygens

Ich denke, ich bekomme nicht den Teil, in dem eine Verbindung zum Host (Host-IP + OpenVPN-Port) an den OpenVPN-Container (172.20.20.2) weitergeleitet wird
jtomasrl
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.