Permitir que los contenedores Docker se conecten a clientes OpenVPN en la interfaz del túnel host

11

Tengo la siguiente configuración:

  • Un host CentOS que ejecuta el servicio acoplable
  • Una red de puente acoplable definida por el usuario
  • 2 contenedores Docker conectados a esa red puente definida por el usuario
  • Una instalación de OpenVPN (actualmente se ejecuta en el host. También se puede ejecutar en un contenedor acoplable)
  • Algunos clientes conectados a OpenVPN

¿Cómo puedo permitir que los contenedores docker en la red del puente docker se comuniquen con los clientes openvpn en la red tun0?

Me gustaría poder tener una comunicación basada en TCP entre docker1 (10.10.0.3) y los clientes conectados a vpn (rango 172.19.0.x) de manera transparente.

¿Qué necesito configurar en el lado del acoplador (red / iptables / ...) y en el host (iptables?)

ddewaele
fuente
1
Tal vez tarde, pero en su caso creo que necesita tap, loco tun, he estado trabajando en eso durante más de 12 horas sin éxito hasta ahora.
Mohammed Noureldin
@MohammedNoureldin, ¿encontraron una solución? También estoy considerando ir a tocar el dispositivo. Lo frustrante es que desde el contenedor ovpn puedo acceder a los clientes vpn. Y desde los clientes vpn puedo acceder a los otros contenedores en la misma red Docker. Pero el reenvío entre "eth0" y tun0 dentro del contenedor ovpn no está funcionando. Supongo que se debe a tun0 nature vs. tap.
Huygens
@Huygens, sí, lo resolví, haz una pregunta por separado y dame una referencia y haré todo lo posible para ayudarte.
Mohammed Noureldin
1
Hola @MohammedNoureldin He encontrado las 2 instrucciones que faltan para que funcione. Estaban en páginas de manual de openvpn 👍. Pronto publicaré una respuesta a esta pregunta para otros.
Huygens
1
@Huygens, es bueno saberlo, en realidad aún no he tenido tiempo de publicar la respuesta, pero estoy interesado en ver qué funcionó para su caso.
Mohammed Noureldin el

Respuestas:

7

Contexto

He estado usando el muy buen contenedor Docker de Kyle Manna ( https://github.com/kylemanna/docker-openvpn ). Estoy usando la llamada documentación "paranoica" para configurar mi servidor OpenVPN, pero en mi opinión, esta debería ser la forma estándar y no la paranoica.

Configuración

Para permitir la conexión bidireccional entre los contenedores Docker seleccionados y los clientes VPN, debe crear una red Docker en la que vaya a conectar el contenedor al que los clientes VPN deben poder acceder. El servidor VPN será uno de esos contenedores.

El servidor VPN debe tener el client-to-client, topology subnet, dev tun0(u otro dispositivo tun) y push "route <docker net IP> <docker net mask>"configurado.

El host del servidor VPN debe configurarse para admitir el reenvío de paquetes IP de una subred a otra. Esto significa establecer sysctl ip_forward en 1 (debería ser el caso si tiene la instalación de Docker), permitiendo que los paquetes del dispositivo tun pasen por la cadena FORWARD de iptables y estableciendo el enrutamiento adecuado. Esto se puede resumir con estos comandos:

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

De todos modos, estas son las opciones que he usado para configurar el servidor:

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

Esto debería generar un archivo de configuración del servidor similar a:

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

Ejemplo concreto

Ahora tomaré un ejemplo concreto. En este ejemplo, ejecutaré el servidor OpenVPN mencionado anteriormente dentro de Docker en el host vpn.example.com. Este contenedor está conectado a la red Docker docker-net-vpn. Estos son los comandos (en este ejemplo, genero la configuración del servidor directamente en el servidor y omito la generación de CA; en su lugar, siga la documentación paranoica del proyecto mencionado anteriormente):

$ 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

El primer comando crea una nueva red Docker dedicada que define una nueva subred. Adjuntaremos el servidor OpenVPN a esta red.

El segundo crea la configuración de OpenVPN utilizando la misma subred definida en el primer comando.

El tercero crea el servidor OpenVPN. Está conectado a la red Docker recién creada y utiliza una IP fija.

Los comandos cuarto y quinto configuran el reenvío de IP.

El último comando agrega una nueva ruta hacia la configuración del cliente VPN a través de la IP fija del contenedor OpenVPN.

Nota

No lo he probado, pero debería ser posible restringir la regla ADELANTE para iptables. La creación de la red Docker creó un nuevo dispositivo puente. Este puente se nombra br-<ID>con ID siendo los primeros 12 caracteres de la ID de red Docker. Esta identificación se puede obtener con docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12. Por lo tanto, el siguiente comando es quizás más restrictivo (por lo que es mejor en términos de seguridad) pero aún debería permitir que nuestro tráfico se enrute:

$ 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
fuente
Oye, no puedo hacer que esto funcione, puedo rastrear a 192.168.255.6 y obtengo:, 1 gnet (172.20.20.1) 1966.269 ms !H 1966.248 ms !H 1966.239 ms !Hpero no puedo hacer ping ni alcanzar puertos abiertos.
GuySoft
Hola @GuySoft, lo que traceroute informa es que su último salto (172.20.20.1) no puede llegar al host 192.168.255.6. Por lo tanto, significa que su tabla de enrutamiento probablemente sea incorrecta. ¿Podemos chatear para ver dónde está el problema?
Huygens
Comenzó a funcionar, creo que lo que sucedió es que ambas máquinas tenían docker instalado, y ambas tenían una subred 172.20.20.1, lo que hizo que las cosas chocaran, necesito encontrar una manera de hacer que docker no cree una subred que choque en la máquina del cliente .
GuySoft
Si usa Docker Compose, puede especificar el rango de direcciones IP que debe usar la red. Consulte la documentación de redacción. También es posible hacerlo desde la línea de comandos con docker network….
Huygens
Creo que no estoy obteniendo la parte donde una conexión al host (host ip + puerto openvpn) se enruta al contenedor openvpn (172.20.20.2)
jtomasrl