Digamos que tenha a seguinte topologia de rede:
O gateway NAT linux-router
tem a seguinte regra SNAT em vigor:
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 10.99.99.50 anywhere to:1.1.1.6
Além disso, como visto no desenho, o 1.1.1.6
endereço é configurado na lo
interface. Tecnicamente, isso não é necessário, ou seja, pode-se excluí-lo e linux-svr
ainda tem a conectividade. Assim, há um ponto para configurar o endereço de origem SNAT no gateway NAT? Apenas para fins de solução de problemas, pois é mais fácil associar e 1.1.1.6
rastrear linux-svr
?
netfilter é agnóstico de rota. Essa é a coisa importante que explica o que acontece abaixo. O tratamento de NAT do netfilter altera os endereços e, em alguns casos, quando isso é feito antes de uma decisão de rota, isso por sua vez altera a decisão de rota. O netfilter não toma decisões de rota por si mesmo: esse é apenas o papel da pilha de roteamento.
Estou assumindo abaixo que o linux-router não possui regra de firewall adicional (na tabela de filtros padrão do iptables ), porque nunca foi mencionado na pergunta. Além disso, para evitar a multiplicação de casos para endereçar, estou assumindo que não há outro sistema a ser considerado além de linux-srv (e linux-router ) na LAN 10.99.99.0/24 (não seria difícil resolvê-los também).
Sobre como remover 1.1.1.6
O SNAT acontece no POSTROUTING, após qualquer decisão de roteamento. Se o SNAT encontrar um IP que corresponda aos critérios fornecidos, ele adicionará uma entrada conntrack para lidar com as respostas. Algo semelhante a isso acontece no roteador linux (usando
conntrack -E -e NEW
):Não é trabalho do netfilter garantir que as respostas realmente voltem. Esse é novamente o trabalho da pilha de roteamento (incluindo roteamento externo onde o linux-router não tem controle).
Antes de ser deletado, 1.1.1.6 era um IP de linux-router . A interface onde este IP foi adicionado não importa muito, pois o Linux está seguindo o modelo de host fraco : ele pode responder a consultas a este IP recebidas em qualquer interface. A remoção desta entrada não impedirá o recebimento de pacotes para 1.1.1.6, pois o M10i tem uma rota específica para chegar a 1.1.1.6: usando 1.1.215.48 que pertence ao linux-router . Portanto , o roteador linux nunca recebe uma solicitação ARP para este IP: a solicitação ARP vinda de M10i é sempre 1.1.215.48 (e para dizer o mesmo, a tabela ARP de M10i terá armazenado em cache apenas 1.1.215.48, não 1.1.1.6). Isso significa que a existência deste IP não importa: linux-routersempre receberá tráfego para 1.1.1.6. Mas agora há uma diferença:
Se o pacote não estiver relacionado à atividade anterior do linux-srv , este pacote alcançará a primeira decisão de rota , como visto neste esquema . De acordo com sua tabela de roteamento atual, deve ser isso:
Se tivesse sido M10i (ou qualquer sistema na LAN 1.1.215.32/27), o linux-router também teria adicionado redirecionamentos ICMP de tempos em tempos, como isso pode dizer:
De qualquer forma, para pacotes vindos da internet, os pacotes serão enviados de volta para M10i , que provavelmente está implementando Strict Reverse Path Forwarding : este pacote roteado de volta será descartado por M10i , já que sua fonte (198.51.100.101) está no lado errado de sua tabela de roteamento e, portanto, filtrada por Strict Path Forwarding. Sem o Strict Reverse Path Forwarding, isso teria causado um loop entre o M10i e o roteador linux até que o TTL do pacote fosse decrementado para 0 e o pacote também fosse descartado.
Exemplo anterior: um pacote de resposta recebido de 8.8.8.8 tcp porta 80 para 1.1.1.6 porta 57490, que seria rastreado por
conntrack -E
:Em algum ponto de pré-roteamento, conntrack irá lidar com "de-SNAT" (como um lembrete, este pacote nunca irá atravessar novamente a tabela nat do iptables , isso também está escrito no esquema anterior: tabela "nat" consultada apenas para "NEW "conexões ). O IP de destino agora é alterado para 10.99.99.50, e o pacote atinge a primeira decisão de rota: ele é roteado para linux-srv . Tudo funciona bem.
Então eu expliquei o que acontece quando você remove o 1.1.1.6: não afeta o linux-srv como um cliente de internet, mas cria uma pequena interrupção entre o M10i e o linux-router para pacotes de entrada não relacionados.
Se você quiser que alguns clientes na internet alcancem linux-srv usando uma regra DNAT no linux-router , então para as conexões afetadas (por exemplo: um servidor web na porta tcp linux-srv 80), tudo funcionará sem interrupção. Para outras tentativas, novamente há o pequeno problema entre M10i e linux-router .
Sobre a remoção do seletor/filtro de IP de origem para a regra SNAT
Não foi fornecida uma informação: se também existe um seletor/filtro na interface de saída, ou não. As duas regras abaixo obteriam a mesma saída de
iptables -t nat -n -L
(mas não deiptables -t nat -n -v -L
ou melhoriptables-save
):ou
Na verdade, não importa neste caso se você agora usar um desses dois comandos:
Como um endereço de destino IP privado não pode ser visto vindo do lado de eth0, o linux-router pode efetivamente rotear apenas um endereço IP: linux-srv 's 10.99.99.50 e esse roteamento só pode acontecer quando é iniciado a partir de 10.99.99.50 primeiro , para que seja SNAT para um IP público. Como o iptables criará uma nova entrada conntrack apenas na conexão inicial (estado NOVO), depois disso a entrada conntrack não será mais alterada e tudo funcionará bem.
com 1.1.1.6 removido do roteador linux
Para linux-srv , tudo ainda funcionará como esperado quando se conectar à Internet: a explicação anterior também se aplica.
Para qualquer conexão de entrada desconhecida de fora para 1.1.1.6 (por exemplo, de 198.51.100.101):
A pilha de roteamento determina que 1.1.1.6 deve ser roteado para M10i (veja explicação feita anteriormente). Uma entrada tentativa de conntrack é adicionada no estado NEW e o pacote atinge nat/POSTROUTING: o pacote é SNATed para 1.1.1.6 e enviado de volta para M10i . O M10i tem uma rota para 1.1.1.6 e envia novamente o pacote alterado para o linux-router com IP de origem e destino como 1.1.1.6 (como a origem está no lado correto de suas tabelas de roteamento, ele nem é descartado pelo Strict Reverse Path Forwarding ). linux-router recebe um pacote ... de lá eu não posso dizer se é um bug ou não, mas aqui está o que é capturado em um experimento reproduzindo seu caso com
conntrack -E
, com um único pacote TCP SYN recebido de 198.51.100.101:Mesmo que o comportamento do netfilter não seja normal, há realmente um loop acontecendo entre o M10i e o linux-router (até que o TTL caia para 0).
Conclusão
Não remova o endereço IP local 1.1.1.6. Você está criando problemas de roteamento, e não é função do netfilter corrigir esses problemas de roteamento. Mesmo se você adicionar regras de firewall impedindo esses loops, não é um comportamento sensato usar rotas incorretas.
Da mesma forma, você pode optar por remover o seletor de IP de origem para a regra SNAT, mas é melhor não se também não houver nenhuma interface selecionada: (ou seja, se você escolher esta regra:
iptables -t nat -A POSTROUTING -j SNAT --to-source 1.1.1.6
). só está funcionando porque existem endereços IP privados, não roteáveis na Internet, em jogo. Se não fosse esse o caso, qualquer conexão de fora tentando alcançar a LAN atrás da interface eth2 do roteador linux seria SNATed para 1.1.1.6.Isso também seria o caso, por exemplo, se você adicionasse uma regra DNAT para ter alguns serviços do linux-srv acessíveis pela Internet, impedindo que o linux-srv veja um endereço de origem diferente de 1.1.1.6. Aqui está um exemplo concreto em uma simulação (com uma restauração sã de 1.1.1.6 para linux-router ):
Embora possa não estar claro, isso significa que as respostas esperadas são de 10.99.99.50 a 1.1.1.6 (não a 198.51.100.101): linux-srv permanece cego em qual endereço IP realmente conectado a ele, ele sempre verá 1.1.1.6 .