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

6

Eu tenho a seguinte configuração:

  • Um host do CentOS que executa o serviço de encaixe
  • Uma rede de ponte de encaixe 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 do docker)
  • Alguns clientes conectados ao OpenVPN

Como posso permitir contêineres docker na rede da ponte docker para se comunicar com os clientes openvpn na rede tun0?

Gostaria de poder ter uma comunicação baseada em tcp entre o docker1 (10.10.0.3) e os clientes conectados ao vpn (172.19.0.x range) de forma transparente.

O que eu preciso configurar no docker (networking / iptables / ...) e no host (iptables?)

    
por ddewaele 12.09.2016 / 00:09

1 resposta

1

Contexto

Eu tenho usado o excelente contêiner Docker de Kyle Manna ( link ). Estou usando a chamada documentação "paranóica" para configurar meu servidor OpenVPN, mas, a meu ver, essa deve ser a maneira padrão e não a maneira paranoica.

Configuração

Para permitir a conexão bidirecional entre os contêineres selecionados do Docker e os clientes VPN, você precisa criar uma rede do Docker na qual você irá anexar o contêiner que deve ter permissão para ser acessado 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 tun) e push "route <docker net IP> <docker net mask>" configurado.

O host do servidor VPN deve ser configurado para suportar o 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 a instalação do Docker), permitindo que os pacotes do dispositivo tun passem pela cadeia FORWARD do iptables 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>

Enfim, 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 de menção acima dentro do Docker no host vpn.example.com. Este contêiner é anexado à docker-net-vpn da rede do Docker. Aqui estão os comandos (neste exemplo eu gero a configuração do servidor diretamente no servidor e eu pulo a geração CA, por favor siga a documentação paranóica do projeto acima mencionado):

$ 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 anexar o servidor OpenVPN a esta rede.

O segundo cria a configuração do OpenVPN usando a mesma sub-rede definida no primeiro comando.

O terceiro cria o servidor OpenVPN. Ele é anexado à recém-criada rede Docker e usa um IP de correção.

O quarto e quinto comandos configuram o encaminhamento de IP.

O último comando adiciona uma nova rota para a configuração do cliente VPN através do IP fixo do container OpenVPN.

Nota

Eu não tentei, mas deveria ser possível restringir a regra FORWARD para iptables. A criação da rede do Docker criou um novo dispositivo de ponte. Essa ponte é denominada br-<ID> , com o ID sendo os primeiros 12 caracteres da ID de rede do Docker. Esse ID pode ser obtido com docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12 . Portanto, o comando a seguir é talvez mais restritivo (portanto, 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
    
por 23.10.2017 / 13:42