Tráfego de saída em diferentes interfaces com base na porta de destino

23

Minha pergunta é basicamente a mesma que Permitir apenas determinado tráfego de saída em determinadas interfaces .

Eu tenho duas interfaces eth1(10.0.0.2) e wlan0(192.168.0.2). Minha rota padrão é para eth1. Digamos que eu queira que todo o tráfego https passe wlan0. Agora, se eu usar a solução sugerida na outra pergunta, o tráfego https passará wlan0, mas ainda terá o endereço de origem eth1(10.0.0.2). Como esse endereço não é roteável para o wlan0gateway, as respostas nunca voltarão. A maneira mais fácil seria simplesmente definir o bind-addr corretamente no aplicativo, mas, neste caso, não é aplicável.

Eu acho que preciso reescrever o src-addr:

# first mark it so that iproute can route it through wlan0
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# now rewrite the src-addr
iptables -A POSTROUTING -t nat -o wlan0 -p tcp --dport 443 -j SNAT --to 192.168.0.2

Agora, o tcpdump vê os pacotes de saída muito bem e os pacotes de entrada chegam para 192.168.0.2; no entanto, eles provavelmente nunca acabam no aplicativo, porque tudo que eu vejo é que o aplicativo está reenviando o pacote SYN, embora o SYN- ACK já foi recebido.

Então pensei: talvez seja necessário reescrever o endereço de entrada também:

iptables -A PREROUTING -t nat -i wlan0 -p tcp --sport 443 -j DNAT --to 10.0.0.2

mas isso também não funcionou. Então, eu estou meio que preso aqui. Alguma sugestão?

rumpel
fonte

Respostas:

24

Você está perto.

O motivo real pelo qual o aplicativo não está vendo o tráfego de retorno é por causa da proteção de falsificação de IP incorporada no kernel. Ou seja, o tráfego de retorno não corresponde à tabela de roteamento e, portanto, é descartado. Você pode corrigir isso desativando a proteção contra falsificação da seguinte maneira:

sudo sysctl net.ipv4.conf.wlan0.rp_filter=0

Mas eu não recomendaria. A maneira mais adequada é criar uma instância de roteamento alternativa.

  1. A marca é necessária. Mantê-la.
  2. O NAT de origem também é necessário.
  3. O DNAT final é desnecessário, portanto você pode removê-lo.

Verifique se você tem o iproutepacote instalado. Se você possui o ipcomando, está pronto (o que parece ser o seu caso, mas se não obtiver o primeiro).

Edite /etc/iproute2/rt_tablese adicione uma nova tabela anexando a seguinte linha:

200 wlan-route

Você precisa configurar sua nova tabela de roteamento nomeada wlan-routecom um gateway padrão e criar regras para enviar condicionalmente o tráfego para essa tabela. Assumirei que seu gateway padrão é 192.168.0.1. Naturalmente, isso precisa corresponder à sua rede real, e não apenas às minhas suposições.

ip route add default via 192.168.0.1 dev wlan0 table wlan-route
ip rule add fwmark 0x1 table wlan-route

Seu script anotado final ficaria assim:

# Populate secondary routing table
ip route add default via 192.168.0.1 dev wlan0 table wlan-route
# Anything with this fwmark will use the secondary routing table
ip rule add fwmark 0x1 table wlan-route
# Mark these packets so that iproute can route it through wlan-route
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# now rewrite the src-addr
iptables -A POSTROUTING -t nat -o wlan0 -p tcp --dport 443 -j SNAT --to 192.168.0.2
bahamat
fonte
Obrigado por reservar um tempo para analisar isso. No entanto, isso já é o que eu estava usando (como descrito na outra pergunta), então eu tenho a rota adicional configurada, mas ainda é a mesma. Os SYN-ACKs voltam para 192.168.0.2, mas aparentemente nunca chegam ao aplicativo.
rumpel
Volte e leia minha resposta novamente. Eu lidei com isso.
bahamat 20/09/11
A parte sobre a proteção contra falsificação? Nenhuma mudança, mesmo depois de tentar. Desculpe, leia isso várias vezes, mas ainda não conseguiu o que está faltando.
amigos estão
Você precisa adicionar uma srcopção aos ip routecomandos para especificar o endereço de origem correto.
David Schwartz
@ DavidSchwartz: o POSTROUTING SNATvai cuidar disso.
bahamat 23/09/11
8

a solução de bahamat está correta; no entanto, observe que a única maneira de fazer esse trabalho foi desabilitar o rp_filter para todas as interfaces do sistema, não apenas as duas (eth1 e wlan0, neste caso) envolvidas no NAT.

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; done
echo 1 > /proc/sys/net/ipv4/route/flush

(consulte a observação IMPORTANTE no final desta página: Howto de roteamento avançado - o link publicado não existe mais, mas eu o encontrei na máquina de wayback)

Davide C
fonte
Obrigado por essas respostas, eu também só consegui obter a solução bahamats funcionando, considerando sua resposta.
Dynalon 13/05
para mim em uma caixa LTS bastante padrão do ubuntu 12.04, além de desabilitar o rp_filter e liberar o cache da rota, também tive que retirar o nome da interface dos argumentos do iptables. não teve tempo suficiente para investigar o porquê.
Costin Gu
0

Uma sugestão: você deve sempre usar em --sportvez de --dportna cadeia de saída.

Os NATs mudam dporte isso tornará sua regra inaceitável.

user73451
fonte
2
Existe algo que eu não estou recebendo? A porta, como na porta de destino, não pode ser alterada. É a porta do serviço que a sessão está tentando acessar, por exemplo, http, ssh, smtp. Ou você confundiu esporte e esporte, ou estou perdendo algo óbvio. : P
Alguém
0

Eu acho que abaixo é necessário:

ip ru add from 192.168.0.2 table 3 prio 300
ip ro add table 3 default via 192.168.0.1 dev wlan0
user181234
fonte