NAT bidirecional com iptables

1

Em suma, tenho um sistema de cluster em minhas mãos, para o qual tenho que rotear o tráfego por meio de seu mestre. O tráfego de roteamento dos nós para o mundo externo funciona, mas o tráfego de roteamento da sub-rede do nosso departamento para os nós falha. Infelizmente, adicionar os nós à nossa sub-rede está fora de questão.

A configuração

O cluster consiste em um mestre e vários nós, junto com alguma periferia. Os nós estão em uma rede interna, escondida de nossa intranet ou da internet. Um NAT já está em vigor no mestre, portanto, os nós têm acesso a servidores internos e externos. Esta parte funciona.

A interface externa do mestre está na mesma sub-rede que as nossas estações de trabalho, que compartilham um gateway fora de nosso controle.

Edit: O cluster roda o CentOS 7, os PCs executam uma distribuição baseada no xenial do Ubuntu.

A tarefa

Alguns de nossos pacotes de software precisam de acesso direto aos nós. Para isso, queríamos configurar o segundo NAT no mestre usando o iptables e adicionar uma rota ip nos computadores para enviar o tráfego para 10.10.1.0/24 pelo mestre.

A configuração

master: ip route

default via 123.45.67.254 dev eth0 proto static metric 100
10.10.0.0/16 dev eth1 proto kernel scope link src 10.10.0.1
123.45.67.0/23 dev eth0 proto kernel scope link src 123.45.67.204 metric 100

master: iptables -vnL -t nat

Chain PREROUTING (policy ACCEPT 7356 packets, 880K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 4884 packets, 687K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 3445 packets, 225K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 3445 packets, 225K bytes)
 pkts bytes target     prot opt in     out     source               destination
  439 33324 MASQUERADE  all  --  *     eth0    10.10.1.0/24         0.0.0.0/0
61828 3710K MASQUERADE  all  --  *     eth1    123.45.67.0/23       10.10.1.0/24

Usar SNAT em vez de MASQUERADE não faz diferença.

node: ip route

default via 10.10.0.1 dev eth1
10.10.0.0/16 dev eth1 proto kernel scope link src 10.10.1.1

pc: ip route

default via 123.45.67.254 dev eth0  proto static  metric 100
10.10.0.0/16 via 123.45.67.204 dev eth0
123.45.67.0/23 dev eth0  proto kernel  scope link  src 123.45.67.191  metric 100

Diagnóstico até agora

  • NAT do node01 para internet / intranet / pcs funciona perfeitamente.
  • NAT de pc1 a node01 falha durante o handshake TCP:
    • SYN é passado pelo mestre para o nó01, é marcado como SYN_RECV no tcpdump
    • SYN + ACK é enviado do node01 para o master
    • SYN + ACK aparece no tcpdump no mestre, é passado para filtrar
    • O tcpdump mostra a passagem de SYN + ACK para filtrar
    • iptables mostra os pacotes SYN + ACK passando pelo filtro FORWARD, mangle FORWARD + POSTROUTING
    • Os pacotes SYN + ACK nunca passam por nat POSTROUTING (deveriam?)
    • Os pacotes SYN + ACK nunca chegam ao pc1
  • Claro que o aperto de mão falha
    • pc1 está preso em SYN_SENT
    • node01 está preso em SYN_RECV
    • eventualmente, a conexão expira
  • não tenho como monitorar pacotes no gateway

Meu melhor palpite é que um roteador com monitoração de estado no modo descarta o pacote SYN + ACK devido a seu endereço de origem ser reescrito no mestre, portanto, sua relação com o pacote SYN original é perdida.

Como podemos conseguir isso funcionar?

Deixe-me saber se configurações / registros adicionais são necessários.

    
por Erik E. Lorenz 16.02.2018 / 09:04

0 respostas