Se um pacote for enviado usando TCP e endereço de origem 127.1.1.1 (lo) e porta de destino 80, desejo ser enviado por eth0 e endereço de origem abcd.
Como posso fazer isso funcionar?
Tentei:
iptables -t nat -A POSTROUTING -s 127.1.1.1 -j SNAT --to-source a.b.c.d
No entanto, isso ainda está atingindo o tempo limite:
nc -s 127.1.1.1 <external IP> 80
Muito obrigado.
Presumo que você já tenha definido o
net.ipv4.conf.eth0.route_localnet
sysctl como1
, o que é necessário para o que você está fazendo. Caso contrárionc
, deverá falhar imediatamente ou apresentar umInvalid argument
erro, dependendo da variante do netcat que você está usando.Embora eu não tenha certeza do que você quer dizer com tempo limite quando não está usando o
-w
. Talvez você esteja se referindo ao fato de que ele fica parado para sempre? Nesse caso, AFAIK indica mais ou menos que o host de destino (ou um roteador intermediário) possui um firewall que descartou o pacote. (Sem esse firewall, normalmente o sistema operacional apenas redefiniria a conexão imediatamente quando fosse TCP, embora o GNU netcat pareça um pouco lento em "aceitar o fato", enquanto o OpenBSD netcat simplesmente sai imediatamente.)O problema é que o pacote pode não ter levado o link que você deseja (por exemplo, aquele
eth0
).A regra é válida, como se houver apenas um link que possa ser aquele que você deseja que o tráfego siga, e todos os endereços de destino possíveis forem cobertos por uma rota desse link, tudo bem.
O problema é:
Parece que existem vários links e, por algum motivo, você deseja que o endereço de origem escolhido seja o que determina qual link determinados tráfegos levariam. (E por algum motivo peculiar, você decidiu usar o bloco de endereço de loopback para a tarefa.)
No entanto,
SNAT
não afeta o roteamento, pois é aplicado após a decisão de roteamento ter sido tomada (notaPOSTROUTING
).Normalmente o roteamento funciona assim: seria usada uma rota na tabela de rotas principal com o comprimento de prefixo mais longo que cobre o endereço de destino; se houver mais de uma rota (com o mesmo comprimento de prefixo mais longo), aquela com métrica menor será usada. (Não sei o que aconteceria se a métrica deles também fosse a mesma; pessoalmente , considero apenas que isso resultaria em um comportamento não determinístico e em algo a ser evitado.)
Como você pode ver, além dos fatores do próprio mecanismo de roteamento, o endereço de destino é a única coisa que importa.
Se precisar levar em consideração o endereço de origem, você precisará de roteamento baseado em política, também conhecido como regra IP + tabela de rotas alternativa.
Por exemplo:
Observe que
iif lo
a regra não tem nada a ver com o fato de você querer de alguma forma aproveitar o bloco de endereço de loopback. Apenas "apertou" a regra para que ela fosse aplicada apenas a tráfegos originados do próprio host (ou seja, caso este host esteja funcionando como roteador para algum outro host).Observe também que a
from
correspondência deve ter o endereço de origem "original", e não o endereço de origem "destino" definido porSNAT
.Existem mais alguns "seletores" que você pode usar para "restringir" ainda mais a regra, como
ipproto tcp dport 80
.PS Escrever esta resposta não significa que eu ache que o que você está tentando fazer (como sua abordagem) faz sentido. Só que não estou interessado em descobrir se é um XYProblem, pelo menos não até/a menos que você apresente ativamente todo o contexto por trás de sua ideia.
Pense em POSTROUTING como o que fazer na volta (o processo inverso). Você também precisa disso. Mas o que você está procurando é PREROUTING. Isso é usado para definir o que acontece com os pacotes antes de serem enviados ou para onde encaminhá-los. O verdadeiro problema é que, se o tráfego se originar no host local, o NAT PREROUTING não terá efeito. Neste caso, você deseja apenas usar a tabela OUTPUT para -j DNAT para encaminhar pacotes de saída para outro IP. O DNAT também mascarará o IP de origem conforme você desejar. Se o tráfego vier de fora e você deseja DNAT, adicione-o ao NAT PREROUTING (iptables -t nat -I PREROUTING… -j DNAT —-to…). A tabela IUTOUT está na cadeia de filtros padrão, então apenas: iptables -I OUTPUT… -j DNAT —-to…). Você desejará a regra POSTROUTING ou INPUT na direção oposta, pois precisará reverter o NAT do IP (reescrevendo o IP de origem/destino). É para isso que serve o SNAT aqui (fonte nat) - para pacotes que voltam.
Estou me perguntando um pouco sobre o que você deseja alcançar.
Se for apenas a porta 80 em um único endereço IP ao qual você precisa acessar, o encaminhamento de porta é de longe o caminho mais fácil.
No entanto, o endereço IP selecionado na sua pergunta sugere que você deseja utilizar vários endereços IP na
localnet
sub-rede (127.0.0.0/8).Nesse caso, acho que você está pensando em implementar um arquivo
1:1 NAT
.Isso requer uma sub-rede disponível
10.1.0.0/16
e, em seguida, usa o roteamento de origem e destino para que qualquer pacote IP127.1.x.x
pareça originar-se de10.1.x.x
.Da mesma forma, você deseja que todos os pacotes IP destinados sejam
10.1.x.x
encaminhados para127.1.x.x
.Resumindo:
10.1.1.1
mapeia para127.1.1.1
.10.1.1.2
mapeia para127.1.1.2
.Fiz uma pergunta semelhante em 2021 e acredito que ela também pode ser usada nesta questão.
Isso significaria que você precisa usar os seguintes comandos:
Isso também significaria que você precisa de uma rota estática para o seu roteador informando que a sub-rede
10.1.0.0/16
pode ser acessada através do endereço IP do seu servidor.Como por exemplo o comando:
ip route add 10.1.0.0/16 via A.B.C.D
, onde ABCD é o endereço IP que você usa para se comunicar com o servidor.Esta resposta atende às suas necessidades?