A solução foi ativar o encaminhamento na interface específica. Não foi ativado por algum motivo.
sudo sysctl net.ipv4.conf.wlp3s0.forwarding=1
sudo sysctl net.ipv4.conf.wlp0s20u1.forwarding=1
Eu tenho um dispositivo (IP 10.110.1.3) com a seguinte configuração de regra:
$ ip route
default via 10.110.1.4 dev wlan0 onlink
Eu tenho o encaminhamento de ipv4 ativado em ambas as máquinas. Ambas as máquinas podem conversar entre si.
Aqui estão meus iptables. Desejo rotear da interface wlp0s20u1 para wlp3s0:
$ iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
$ iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A POSTROUTING -o wlp3s0 -j MASQUERADE
Rotas no dispositivo "routing" 10.110.1.4:
$ ip route
default via 192.168.1.1 dev wlp3s0 proto static
10.110.1.0/24 dev wlp0s20u1 proto kernel scope link src 10.110.1.4
192.168.1.0/24 dev wlp3s0 proto kernel scope link src 192.168.1.110 metric 600
Usando a rota "if interface", é claro que isso nunca funcionará:
$ ip route get to 192.168.1.1 from 10.110.1.3 iif wlp0s20u1
RTNETLINK answers: No route to host
$ ip route get to 8.8.8.8 from 10.110.1.3 iif wlp0s20u1
RTNETLINK answers: No route to host
Eu observei o src 192.168.1.110
na rota 192.168.1.0
e tentei adicionar a rota a seguir para corrigir isso:
$ sudo ip route add 192.168.1.1/32 dev wlp3s0
Mas isso também não ajudou.
Eu usei o tcpdump para analisar o icmp para ver onde meus pings estão indo.
$ tcpdump -i wlp0s20u1 -n icmp
listening on wlp0s20u1, link-type EN10MB (Ethernet), capture size 262144 bytes
18:13:19.355166 IP 10.110.1.3 > 8.8.8.8: ICMP echo request, id 32366, seq 1, length 64
18:13:20.359770 IP 10.110.1.3 > 8.8.8.8: ICMP echo request, id 32366, seq 2, length 64
e
tcpdump -i wlp3s0 -n icmp
listening on wlp3s0, link-type EN10MB (Ethernet), capture size 262144 bytes
Nada na interface wlp3s0, a menos que eu faça o ping do computador "roteador".
Então, claramente, o problema aqui é que o kernel não sabe rotear pacotes de wlp0s20u1 para wlp3s0. Mas não tenho certeza de como fazer isso. Eu tentei adicionar explicitamente rotas para dizer isso, mas parece que não funciona.
Se eu spam o seguinte, somente os contadores de pacotes pré-formatados serão ativados (enquanto um ping estiver sendo tentado);
$ iptables -t nat -v -L -n
Chain PREROUTING (policy ACCEPT 775 packets, 50740 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 24 packets, 1920 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 95 packets, 23073 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 5 packets, 1000 bytes)
pkts bytes target prot opt in out source destination
90 22073 MASQUERADE all -- * wlp3s0 0.0.0.0/0 0.0.0.0/0
Qualquer ajuda é muito apreciada!
EDIT: Explicação Simplificada
Eu tenho três dispositivos:
Estou tentando permitir que o C converse com a internet (0.0.0.0/0) com dois saltos, primeiro para B, depois para A e depois para a Internet.
O problema é obter B para rotear pacotes de wlp3s20u1 para wlp3s0.
Tags networking iptables routing linux