Contêiner do Docker atinge o iptables como proxy

2

Eu tenho dois VPSs, a primeira máquina ( proxy a partir de agora) é para proxy e a segunda máquina ( dock a partir de agora) é o host do docker. Eu quero redirecionar todo o tráfego gerado dentro de um container docker sobre o proxy , para não expor o IP público das máquinas dock .

Como a conexão entre VPSs é pela Internet, nenhuma conexão local, criou um túnel entre eles por túnel ip da seguinte forma:

Em proxy :

ip tunnel add tun10 mode ipip remote x.x.x.x local y.y.y.y dev eth0
ip addr add 192.168.10.1/24 peer 192.168.10.2 dev tun10
ip link set dev tun10 mtu 1492
ip link set dev tun10 up

Em doca :

ip tunnel add tun10 mode ipip remote y.y.y.y local x.x.x.x dev eth0
ip addr add 192.168.10.2/24 peer 192.168.10.1 dev tun10
ip link set dev tun10 mtu 1492
ip link set dev tun10 up

PS: Não sei se o ip tunnel pode ser usado para produção, é outra questão, de qualquer forma planejando usar libreswan ou openvpn como um túnel entre VPSs.

Depois, adicionamos regras SNAT ao iptables em ambos os VPSs e em algumas regras de roteamento da seguinte forma:

Em proxy :

iptables -t nat -A POSTROUTING -s 192.168.10.2/32 -j SNAT --to-source y.y.y.y

Em doca :

iptables -t nat -A POSTROUTING -s 172.27.10.0/24 -j SNAT --to-source 192.168.10.2
ip route add default via 192.168.10.1 dev tun10 table rt2
ip rule add from 192.168.10.2 table rt2

Por último, mas não menos importante, criamos uma rede docker com um contêiner de teste anexado a ela da seguinte maneira:

docker network create --attachable --opt com.docker.network.bridge.name=br-test --opt com.docker.network.bridge.enable_ip_masquerade=false --subnet=172.27.10.0/24 testnet
docker run --network testnet alpine:latest /bin/sh

Infelizmente, tudo isso acabou sem sucesso. Então a questão é como depurar isso? É o caminho correto? Como você faria o redirecionamento via proxy?

Algumas palavras sobre teoria: O tráfego proveniente da sub-rede 172.27.10.0/24 atinge a regra SNAT do iptables, o IP da fonte muda para 192.168.10.2. Pela regra de roteamento ele roteia o dispositivo tun10, é o túnel. E atinge outra regra SNAT do iptables que muda o IP para y.y.y.y e finalmente vai para o destino.

    
por teeper 25.07.2018 / 08:06

1 resposta

1

I want to redirect all traffic generated inside a docker container itself over proxy, to not exposure dock machines public IP.

Se isso é tudo que você quer, não é necessário NAT entre as duas instâncias do docker.

Você precisa ativar o encaminhamento na instância proxy (por exemplo, via sysctl).

Se o IP público de proxy for visible dentro de proxy , será necessário fazer SNAT com esse IP público dentro de proxy (não em dock ). Isso também é chamado de MASQUERADE. É uma configuração padrão, google de "masquerade".

Se o IP público de proxy for não visível dentro de proxy (ou seja, listado quando você faz ip addr ), porque o host de proxy (ou até mesmo algum outro host mais acima) faz o NAT, então você deve evitar o NAT duplo e fazer com que dock apareça como outro container para o host. Os detalhes dependem de como a rede está configurada no host (o que você não disse), mas basicamente o final do túnel em dock terá que ter um IP na mesma sub-rede que os contêineres no host proxy . / p>

Um túnel ipip não é criptografado; você não deve usar este túnel a menos que o transporte esteja totalmente dentro de uma rede confiável (o que provavelmente não é o caso, porque você parece querer endereços IP públicos diferentes). Portanto, use OpenVPN ou fácil de configurar alternativas como tinc . Libreswan não é tão fácil de configurar.

Editar

Passo-a-passo:

1) Verifique se o túnel funciona. Em proxy , faça ping 192.168.10.2 . Em dock , faça ping 192.168.10.1 . Depure com tcpdump em todas as interfaces de rede que você tem acesso. Se o ipip-tunnel não funcionar, use um túnel diferente e faça-o funcionar.

2) Remova todas as regras iptables em dock . Definir a rota padrão através do túnel. Teste com ip route get 8.8.8.8 se a rota funcionar.

3) Supondo que eth0 on proxy tenha o IP público, exclua todas as regras iptables , do:

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o tun10 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -o eth0 -i tun10 -j ACCEPT

Isso diz "encaminhar pacotes, mascarar todos os pacotes encaminhados saindo em eth0 dando a eles o endereço IP público em eth0 como endereço de origem e conexão rastreá-los. Pacotes de tun10 sempre podem ser encaminhados para eth0 , os pacotes recebidos em eth0 somente serão encaminhados para tun10 se a conexão foi estabelecida por dock . "

Teste fazendo ping 8.8.8.8 em dock , enquanto executa tcpdump em tun10 e eth0 on proxy . Você deve ver os pacotes encaminhados e a fonte sendo reescrita.

4) Quando tudo estiver funcionando, torne-o permanente: Edite /etc/sysctl.conf ou um arquivo em /etc/sysctl.d para ter net.ipv4.ip_forward = 1 . Use um script de inicialização para adicionar as regras iptables ou use qualquer pacote que sua distribuição forneça para salvar as regras.

    
por 25.07.2018 / 09:01