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
tap
, locotun
, he estado trabajando en eso durante más de 12 horas sin éxito hasta ahora.