iptables NAT com bridge de rede, containers e systemd-networkd: sem encaminhamento

1

Eu tenho alguns problemas na configuração de um iptables NAT no CentOS 7. Atualmente, o cliente por trás do NAT pode alcançar o IP externo, mas não a rede externa.

Eu segui este tutorial para configurar meu NAT, sabendo que funcionou bem no Gentoo e no Arch:

link

para esquematizar meu problema:

  • eth0 (externo) = 192.168.1.1/24
  • eth1 (interno) = 192.168.2.1/24

quando eu faço ping de 192.168.2.2:

  • ping 192.168.1.1: OK
  • ping 192.168.1.2: NOK
  • ping 8.8.8.8: NOK

Observe que também configuro uma regra de encaminhamento de porta de 192.168.1.1:80 para 192.168.2.2:80. Este trabalho bem, de acordo com o Wireshark meus pacotes são encaminhados com sucesso para 192.168.2.2. Então 192.168.2.2 resposta, mas o pacote é descartado, então eu vejo múltiplos retransmissões TCP. Não há mensagens de "host administrativamente proibido".

Aqui estão as mensagens do dropwatch quando tento me conectar ao 192.168.2.2:80 do lado de fora:

1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_rcv_state_process+1b0 (0xffffffff815e5030)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_rcv_state_process+1b0 (0xffffffff815e5030)
1 drops at ip_error+68 (0xffffffff815c47d8)
2 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
1 drops at ip_error+68 (0xffffffff815c47d8)
2 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
2 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
1 drops at ip_error+68 (0xffffffff815c47d8)

Por favor, alguém tem uma ideia do que eu fiz de errado? Obrigado a todos.

EDITAR:

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth1 -o eth0 -j ACCEPT
-A FORWARD -d 192.168.2.2/32 -p tcp -m tcp --dport 80 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

Chain PREROUTING (policy ACCEPT 1270 packets, 123K bytes)
 pkts bytes target     prot opt in     out     source               destination         
   30  1696 DNAT       tcp  --  eth0 any     anywhere             anywhere             tcp dpt:http to:192.168.2.2:80

Chain INPUT (policy ACCEPT 347 packets, 42272 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 6 packets, 431 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 30 packets, 1696 bytes)
 pkts bytes target     prot opt in     out     source               destination                                             
    6   431 MASQUERADE  all  --  any    eth0  anywhere             anywhere 

EDITAR:

Sim, o encaminhamento de IP está definido corretamente. Quando eu faço ping de 192.168.2.2 para 192.168.1.2, não consigo ver nenhum pacote recebido com o Wireshark em 192.168.1.2. Também não vejo nenhum pacote saindo da eth0 ao usar o Wireshark.

Curiosamente, quando eu pinguei com sucesso 192.168.1.1 de 192.168.2.2, não consigo ver nenhum pacote ICMP que entra na eth0 também.

Acho que devo acrescentar algo que não divulguei porque não achei relevante. Na realidade, estou tentando NAT uma ponte de rede chamada br0 (my eth1 aqui) para a LAN local. Meu servidor 192.168.2.2 está em um contêiner com um veth conectado à ponte.

Não sei se devo editar todas as minhas postagens para refletir melhor a situação. Eu pensei que meu problema era puramente um erro de iptable, mas parece que algo está errado na pilha de rede, porque eu deveria ver os pacotes ICMP de entrada ao pingar 192.168.1.1.

Quando eu disse que já fiz essa configuração no Gentoo e no Arch, também era com containers, usando o LXC. Agora eu tento usar o systemd-nspawn. Selinux é definido como permissivo. Ping 192.168.2.2 do meu host CentOS está ok, forçando-o a usar eth0 não funciona, mas é o comportamento normal.

host de rotas:

default via 192.168.1.254 dev eth0 proto static metric 100 
192.168.2.0/24 dev br0 proto kernel scope link src 192.168.2.1 
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.1 metric 100

contêiner de rotas:

default via 192.168.2.1 dev host0 proto static 
192.168.2.0/24 dev host0 proto kernel scope link src 192.168.2.2
    
por MathieuR 06.11.2017 / 13:05

1 resposta

1

Finalmente encontrei a solução depois de muita dor de cabeça ...

Eu estava usando o systemd-networkd para configurar minha ponte. Enquanto o net.ipv4.ip_forward foi corretamente configurado para 1 e eu também configurei o net.ipv4.conf.all.forwarding para 1, parece que o systemd-networkd não levou em conta o meu padrão enquanto consolava a bridge.

Si acabou que net.ipv4.conf.br0.forwarding foi definido como 0. Eu apenas configurei para 1 e agora funciona.

Para todos que tiverem um problema semelhante, execute este comando:

sysctl -a | grep "\.forwarding" | grep ipv4

Garanta que todas as suas interfaces tenham o encaminhamento ativado.

Tenha um bom dia.

    
por 07.11.2017 / 15:29