Contexto
Estou usando o muito bom contêiner Docker da Kyle Manna ( https://github.com/kylemanna/docker-openvpn ). Estou usando a documentação chamada "paranóica" para configurar meu servidor OpenVPN, mas, na minha opinião, essa deve ser a maneira padrão e não a paranóica.
Configuração
Para permitir a conexão bidirecional entre os contêineres selecionados do Docker e os clientes VPN, é necessário criar uma rede Docker na qual você conectará o contêiner, que deverá ter acesso permitido pelos clientes VPN. O servidor VPN será um desses contêineres.
O servidor VPN deve ter o client-to-client
, topology subnet
, dev tun0
(ou outro dispositivo de tun) e push "route <docker net IP> <docker net mask>"
configurado.
O host do servidor VPN deve ser configurado para oferecer suporte ao encaminhamento de pacotes IP de uma sub-rede para outra. Isso significa definir o sysctl ip_forward como 1 (deve ser o caso se você tiver o Docker instalado), permitindo que os pacotes do dispositivo tun passem pela cadeia iptables FORWARD e definindo o roteamento adequado. Isso pode ser resumido com estes 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 qualquer forma, aqui estão as opções que usei para configurar o 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"
Isso deve gerar um arquivo de configuração do servidor semelhante 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
Exemplo concreto
Agora vou dar um exemplo concreto. Neste exemplo, executarei o servidor OpenVPN mencionado acima no Docker no host vpn.example.com. Esse contêiner está anexado à rede do Docker docker-net-vpn. Aqui estão os comandos (neste exemplo, eu gero a configuração do servidor diretamente no servidor e pulo a geração da CA, siga a documentação paranóica do projeto de menção acima):
$ 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
O primeiro comando cria uma nova rede Docker dedicada que define uma nova sub-rede. Vamos conectar o servidor OpenVPN a esta rede.
O segundo cria a configuração do OpenVPN usando a mesma sub-rede definida no 1º comando.
O terceiro cria o servidor OpenVPN. Ele está conectado à rede Docker recém-criada e usa um IP fixo.
O quarto e o quinto comando configuram o encaminhamento de IP.
O último comando adiciona uma nova rota para a configuração do cliente VPN por meio do IP fixo do contêiner OpenVPN.
Nota
Eu não tentei, mas deve ser possível restringir a regra FORWARD para iptables. A criação da rede do Docker criou um novo dispositivo de ponte. Essa ponte é nomeada br-<ID>
com o ID sendo os primeiros 12 caracteres do ID da rede do Docker. Este ID pode ser obtido com docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12
. Portanto, o comando a seguir é talvez mais restritivo (melhor em termos de segurança), mas ainda deve permitir que nosso tráfego seja roteado:
$ 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
, malucotun
, estou trabalhando nisso há mais de 12 horas sem sucesso até agora.