ebtables / iptables / bridge-utils: problema de PREROUTING / FORWARD na ponte de um único NIC

1

Temos várias regras de iptables para o encaminhamento de conexões, que são sólidas e funcionam bem.

Por exemplo, a porta 80 encaminha para a porta 8080 na mesma máquina (o servidor da web). Quando um determinado servidor da Web está sendo reiniciado, encaminhamos solicitações para outro IP na porta 8080, que exibe uma Página de Manutenção. Na maioria dos casos, esse outro IP está em um servidor separado.

Isso tudo funcionou perfeitamente até que nós instalamos o bridge-utils e mudamos para o uso de uma ponte br0 em vez de eth0 como interface.

O motivo pelo qual convertemos o uso de uma interface de ponte é obter acesso aos recursos MAC SNAT / DNAT dos ebtables. Não temos outro motivo para adicionar uma interface de ponte nos servidores, pois eles não conectam as conexões em várias interfaces.

Eu sei que este é um motivo estranho para adicionar uma ponte aos servidores, mas estamos usando as capacidades MAC SNAT / DNAT em um novo projeto e ebtables parecia ser o caminho mais seguro, rápido e fácil desde que já estamos tão familiarizado com o iptables.

O problema é que, desde a conversão para uma interface br0, o iptables PREROUTING encaminhando para servidores externos não está mais funcionando.

O encaminhamento de PREROUTING interno funciona bem (por exemplo: a solicitação chega na porta 80 e encaminha para a porta 8080).

A cadeia OUTPUT também funciona (por exemplo: podemos nos conectar para fora da caixa através de um IP de destino local: 8080, e a cadeia OUTPUT mapeia para o IP do Servidor de Manutenção em um servidor diferente, porta 8080 e retorna uma página da Web) .

No entanto, qualquer tráfego que chega à caixa parece morrer depois da regra PREROUTING, se o IP de destino for externo.

Aqui está um exemplo da nossa configuração:

Configuração antiga:

iptables -t nat -A PREROUTING -p tcp --dport 9080 -j DNAT --to-destination $MAINTIP:8080
iptables -a FORWARD --in-interface eth0 -j ACCEPT
iptables -t nat -A POSTROUTING --out-interface eth0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

Nova configuração: (a configuração antiga em vários formatos também foi tentada ..., tentando registrar pacotes eth0 e br0)

iptables -t nat -A PREROUTING -p tcp --dport 9080 -j DNAT --to-destination $MAINTIP:8080
iptables -a FORWARD --in-interface br0 -j ACCEPT
iptables -t nat -A POSTROUTING --out-interface br0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

Antes de mudar para br0, o pedido do cliente iria para o servidor A na porta 9080 e, em seguida, seria MASQUERADED para outro servidor $ MAINTIP.

Como explicado acima, isso funciona bem se $ MAINTIP estiver na mesma máquina, mas se estiver em outro servidor, o pacote nunca será enviado para $ MAINTIP sob a nova configuração br0.

Queremos que os pacotes saiam da mesma interface em que vieram, MASQUERADED, como faziam antes de usarmos uma ponte NIC única (br0 / bridge-utils).

Eu tentei adicionar log em todos os estágios do iptables. Por alguma razão, o alvo TRACE do iptables não funciona nesta configuração, então eu não consigo pegar um log TRACE, mas o pacote aparece na tabela PREROUTING, mas parece que ele caiu silenciosamente depois disso.

Eu passei por este excelente documento e compreendi melhor o fluxo entre o iptables e ebtables: link

Pelo que entendi, parece que a bridge não está encaminhando os pacotes pela mesma interface em que eles entraram e os está soltando. Se tivéssemos uma segunda interface adicionada, imagino que ela estaria sendo encaminhada para essa interface (o outro lado da ponte) - que é a maneira como as pontes funcionam, -

É possível fazer isso funcionar da maneira que queremos, e PROMETAMOS / FORNECER esses pacotes na mesma interface em que eles vieram, como costumávamos fazer?

Espero que haja algumas regras de ebtables que possam trabalhar em conjunto com as regras do iptables PREROUTING / FORWARD / POSTROUTING para fazer o trabalho de encaminhamento do iptables da maneira usual, e enviar os pacotes roteados br0 (eth0) em vez de soltando-os.

Comentários, chamas, todo e qualquer conselho bem-vindo!

Atenciosamente, Neale

    
por Neale Rudd - Metawerx Java 14.06.2013 / 23:59

1 resposta

0

Ao filtrar uma bridge, acho que você precisa usar uma correspondência diferente para a interface in / out, no seu caso, entendo sua configuração corretamente, algo como

iptables -t nat -A PREROUTING -p tcp --dport 9080 -j DNAT --to-destination $MAINTIP:8080
iptables -a FORWARD -m physdev --physdev-in eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -m physdev --physdev-out eth0 -j MASQUERADE

Eu não acho que você precise habilitar o ip_forward ... isso é uma ponte depois

por último mas não menos importante

echo 1 > net.bridge.bridge-nf-call-iptables

verifique se isso está ativado, mas por padrão.

    
por 15.06.2013 / 03:05

Tags