Estou tentando entender as limitações de usar o iptables DNAT com endereços de loopback. Considere que temos um aplicativo que pode se conectar apenas a 127.0.0.1; A solução óbvia para fazer com que o servidor e o cliente funcionem em nós diferentes é usar o NAT da seguinte forma:
Certifique-se de que todos os pacotes de saída tenham o endereço IP do host principal do cliente:
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source <CLIENT_IP>
Agora vamos tentar enganar o cliente e a DNAT como uma conexão com o mundo exterior:
iptables -t nat -A OUTPUT -d 127.0.0.1/32 -p tcp -m tcp --dport <SERVICE_PORT> -j DNAT --to-destination <SERVER_IP>
Infelizmente, isso simplesmente não funciona. Ao tentar se conectar ao programa 127.0.0.1:<SERVICE_PORT>
, apenas fica pendurado em connect
syscall. O interessante é que não consigo ver nenhum pacote SYN em nenhuma interface ( tcpdump -qn -i any port <SERVICE_PORT>
), no entanto, vejo os contadores de pacotes aumentarem ao olhar para as estatísticas do iptables ( iptables -nvL -t nat
).
Pesquisando na solução Encontrei uma opção de compilação do kernel CONFIG_IP_NF_NAT_LOCAL
, que foi usada nos kernels 2.6.0-2.6.10 para resolver o problema de usar o NAT com conexões localmente originadas. Infelizmente, a atual árvore do kernel git contém informações para as versões 2.6.11 e posteriores, então eu acabei aqui.
Olhando ainda, encontrei este tópico , referente a correções de algum DNAT em problemas de loopback em 2.6.11; um dos patches remove a opção CONFIG_IP_NF_NAT_LOCAL
build e ativa o código incondicionalmente ( aqui está o diff real ).
No entanto, o estado atual deste problema não é claro para mim. Eu gostaria de encontrar algumas explicações ou referências provando que isso é um bug do kernel ou algum recurso não tão bem documentado. Eu sei que o roteamento de rede 127.0.0.0/8 é tratado pelo kernel de uma maneira especial, mas a partir da documentação do iptables é claro que a cadeia de saída de tabela nat é o único lugar que faz sentido para esse tipo de regras e não declara exceções ou qualquer tipo de notas sobre a rede 127/8.
Por favor, abstenha-se de aconselhar algumas soluções alternativas com ferramentas de terceiros, eu já tenho alguns, eu só quero ter alguma explicação porque esta configuração exata não funciona e porque não deve funcionar. Qualquer exemplo de como este DNAT pode ser feito com qualquer outra regra do iptables é bem-vindo.
A configuração acima foi testada no Debian squeeze e wheezy, com kernels 2.6.32, 3.1.0, 3.2.0.