Permitir que contêineres do Docker se conectem a clientes OpenVPN na interface do túnel do host

11

Eu tenho a seguinte configuração:

  • Um host CentOS executando o serviço docker
  • Uma rede de ponte docker definida pelo usuário
  • 2 contêineres do Docker conectados a essa rede de ponte definida pelo usuário
  • Uma instalação do OpenVPN (atualmente em execução no host. Também pode ser executada em um contêiner de docker)
  • Alguns clientes conectados ao OpenVPN

Como posso permitir que os contêineres do docker na rede de ponte do docker se comuniquem com os clientes openvpn na rede tun0?

Eu gostaria de poder ter uma comunicação baseada em tcp entre o docker1 (10.10.0.3) e os clientes conectados ao vpn (intervalo 172.19.0.x) de maneira transparente.

O que preciso configurar no lado do docker (rede / iptables / ...) e no host (iptables?)

ddewaele
fonte
1
Talvez esteja atrasado, mas no seu caso, acredito que você precisa tap, maluco tun, estou trabalhando nisso há mais de 12 horas sem sucesso até agora.
Mohammed Noureldin
@MohammedNoureldin vocês encontraram uma solução? Também estou pensando em ir para o dispositivo. O que é frustrante é que, a partir do contêiner ovpn, eu posso acessar os clientes vpn. E de clientes VPN, posso acessar os outros contêineres na mesma rede Docker. Mas o encaminhamento entre "eth0" e tun0 dentro do contêiner ovpn não está funcionando. Eu acho que é devido à natureza tun0 vs. torneira.
Huygens
@ Huygens, sim, eu resolvi, faça uma pergunta separada e faça uma referência a mim e farei o meu melhor para ajudá-lo.
Mohammed Noureldin
1
Oi @MohammedNoureldin Encontrei as 2 instruções que faltam para que ele funcione. Eles estavam nas páginas de manual do openvpn. Postarei uma resposta em breve para esta pergunta para outras pessoas.
Huygens
1
@ Huygens, bom saber, na verdade ainda não tive tempo de postar a resposta, mas estou interessado em ver o que funcionou no seu caso.
Mohammed Noureldin

Respostas:

7

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
Huygens
fonte
Ei, não consigo fazer isso funcionar, posso fazer o tracerote para 192.168.255.6 e recebo:, 1 gnet (172.20.20.1) 1966.269 ms !H 1966.248 ms !H 1966.239 ms !Hmas não consigo executar ping ou acessar portas abertas.
GuySoft
Olá @GuySoft, o que o traceroute está relatando é que seu último salto (172.20.20.1) não pode alcançar o host 192.168.255.6. Portanto, isso significa que sua tabela de roteamento provavelmente está incorreta. Podemos conversar para ver onde está o problema?
Huygens
Começou a funcionar, acho que o que aconteceu foi que as duas máquinas tinham o docker instalado e as duas tinham uma sub-rede 172.20.20.1, que fez as coisas entrarem em conflito, preciso encontrar uma maneira de fazer o docker não criar uma sub-rede que entraria em conflito na máquina cliente .
GuySoft 1/01/19
Se você usar o Docker Compose, poderá especificar o intervalo de endereços IP que a rede deve usar. Consulte a documentação de composição. Também é possível fazer isso a partir da linha de comando docker network….
Huygens
Eu acho que eu não estou recebendo a parte onde uma conexão com o anfitrião (host ip + openvpn porto) está sendo encaminhado para o recipiente openvpn (172.20.20.2)
jtomasrl