eu tenho uminterface autoescrita tun0(TUN/TAPbaseado) que produz o que recebe.
Preciso que todo o tráfego do sistema flua através desta interface.
A função da interface é:
- Para descobrir pacotes que provavelmente serão censurados e tunelá-los.
- Passe todos os outros tráfegos intactos.
Como você deve imaginar, estou tentando construir uma ferramenta anticensura.
A decisão sobre o tunelamento deve ser tomada dentro do processo tun0
porque somente aí podemos usar DNS confiável.
Preciso da sua ajuda para me mostrar como fazer todo o tráfego fluir por meio de uma interface autoescrita tun0. Se o tun0 precisar de alterações, peço que você forneça essas alterações.
Abaixo está como tentei fazer todo o tráfego passar por tun0 e falhar (falha nos pings).
Compilando
gcc tun0.c
sudo ./a.out
Configurando
sudo ip addr add 10.0.0.1/24 dev tun0
criar mesa João
$ cat /etc/iproute2/rt_tables # # reserved values # 255 local 254 main 253 default 0 unspec # # local # #1 inr.ruhep 200 John
A ordem é importante:
sudo ip rule add from all lookup John
sudo ip route add default dev tun0 table John
sudo ip rule add iif tun0 lookup main priority 500
$ ip rule 0: from all lookup local 500: from all iif tun0 lookup main 32765: from all lookup John 32766: from all lookup main 35000: from all lookup default
Solução de problemas
sudo tcpdump -i wlp2s0 -qtln icmp
e entãoping -I tun0 8.8.8.8
não mostra nenhum pacote capturado, significa que nenhum pacote é transmitido de tun0 para wlp2s0 viaiif tun0 lookup main
regra.Quando substituí
tun0
porlo
todos os lugares, funcionou para mim.
Também tentei
- Desativando a filtragem de caminho reverso,
rp_filter=0
em/etc/sysctl.conf
Solução de problemas de resposta
iptables -I FORWARD -j LOG --log-prefix "filter/FORWARD "
iptables -t nat -I OUTPUT -j LOG --log-prefix "nat/OUTPUT "
iptables -t nat -I PREROUTING -j LOG --log-prefix "nat/PREROUTING "
iptables -t nat -I POSTROUTING -j LOG --log-prefix "nat/POSTROUTNG "
tail -f /var/log/syslog
Fontes modificadas da resposta também sãoaqui.
Responder1
Portanto, na sua configuração, todos os pacotes que você tenta enviar para a rede inicialmente originados 10.0.0.1
(porque estão passando pela tun0
interface e seu endereço local é 10.0.0.1
). Você captura os pacotes, está tudo bem até agora.
Agora, tun0
envia os pacotes ainda mais.Endereço de Origemé 10.0.0.1
e você deseja que os pacotes saiam por uma interface diferente ( wlp2s0
no seu caso). Isso éroteamentoentão vamos ativar o roteamento primeiro:
sysctl -w net.ipv4.ip_forward=1
Depois disso, se você observar, tcpdump
poderá wlp2s0
notar que os pacotes saem com o endereço de origem 10.0.0.1
e não com o endereço de origem da interface wlan (o que você esperaria, eu acho). Então precisamos mudar o endereço de origem e ele se chamafonte NAT. No Linux é fácil com a ajuda defiltro de rede/iptables:
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE
Verifique também se sua FORWARD
rede possui ACCEPT
uma política ou você precisarápermitir encaminhamentocom algo como:
iptables -A FORWARD -i tun0 -o wlp2s0 -s 10.0.0.1 -j ACCEPT
iptables -A FORWARD -i wlp2s0 -o tun0 -d 10.0.0.1 -j ACCEPT
Tudo deve funcionar agora:núcleo do Linuxfaz o roteamento, está movendo pacotes da tun0
interface para wlp2s0
.filtro de rededeve alterar o IP de origem 10.0.0.1
para wlp2s0
o endereço atribuído à sua interface para pacotes de saída. Ele memoriza todas as conexões e quando os pacotes de resposta retornam (se retornarem) ele altera o endereço de destino do wlp2s0
endereço atribuído à interface 10.0.0.1
(o recurso "conntrack").
Bem, deveria, mas não acontece. Parece,filtro de redefica confuso com essa complicada configuração de roteamento e com o fato de que o mesmo pacote passa primeiro pela OUTPUT
cadeia e depois é roteado e chega à PREROUTING
cadeia. Pelo menos na caixa do Debian 8 não funciona.
A melhor maneira de solucionar problemasfiltro de redeé o TRACE
recurso:
modprobe ipt_LOG
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE
Eu habilito apenas o rastreamento para pacotes ICMP, você pode usar outro filtro para depurar.
Ele mostrará por quais tabelas e cadeias o pacote passa. E posso ver que o pacote não avança na FORWARD
cadeia (e não está sendo capturado pela nat/POSTROUTING
cadeia que realmente o faz SNAT
).
Abaixo estão várias abordagens para fazer isso funcionar.
ABORDAGEM #1
A melhor maneira de desfazer a confusãofiltro de redeé alterar o endereço IP de origem dos pacotes no tun0.c
aplicativo. É também a maneira mais natural. Precisamosmude 10.0.0.1 para 10.0.0.2no caminho para fora e10.0.0.2 a 10.0.0.1no caminho de volta.
Modifiquei tun0.c
com o código de alteração do endereço de origem.Aqui está o novo arquivoeaqui está o arquivo de patchPara o seu tun0.c
. Mudanças no cabeçalho IP também envolvemcorreção de soma de verificação, então peguei um código deProjeto OpenVPN. Aqui está a lista completa de comandos que executo após uma reinicialização e tun0_changeip.c
inicialização limpas:
ifconfig tun0 inet 10.0.0.1/30 up
sysctl -w net.ipv4.ip_forward=1
ip route add default dev tun0 table John
ip rule add from all lookup John
ip rule add from 10.0.0.2 lookup main priority 500
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.2 -j MASQUERADE
Observe que você não precisa desligar ofiltragem de caminho reversonesse caso, porque tudo é legal - tun0
só recebe e envia pacotes que pertencem à sua sub-rede. Além disso, você pode fazer um roteamento baseado na origem em vez de baseado na interface.
ABORDAGEM #2
É possível fazer isso SNAT
antes que o pacote alcance tun0
a interface. Mas não é muito correto. Você definitivamente precisará desligar ofiltragem de caminho reversonesse caso:
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Agora faça SNAT
: iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source ip.address.of.your.wlan.interface
Aqui mudamos o endereço de origem apenasantesos pacotes chegam ao tun0
dispositivo. tun0.c
o código reenvia esses pacotes "como estão" (com endereço de origem alterado) e eles são roteados com sucesso através da interface wlan. Mas você pode ter um IP dinâmico na interface wlan e querer usar MASQUERADE
(para não especificar explicitamente o endereço da interface). Veja como você pode usar MASQUERADE
:
iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source 10.0.55.1
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.55.1 -j MASQUERADE
Observe o " 10.0.55.1
" endereço IP - é diferente. Você pode usar qualquer IP aqui, não importa. Os pacotes alcançam nat/POSTROUTING
a cadeia na wlp2s0
interface se alterarmos o IP de origem antes. E agora não depende de um IP estático para interface wlan.
ABORDAGEM #3
Você também pode usar fwmark
. Dessa forma você não precisa SNAT
, mas irá capturar apenas pacotes de saída:
Primeiro precisamos desabilitarfiltragem de caminho reversopois tun0
encaminhará pacotes que pertencem a outra rede:
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Now let's alter the routing rules a bit:
# Delete old rules
ip rule del iif tun0 lookup main
ip rule del from all lookup John
# Packets will start going from wlan interface so they will have source address of it
iptables -t mangle -A OUTPUT -o wlp2s0 -j MARK --set-mark 1
ip rule add fwmark 0x1 lookup John
Esse é outro "hack" pararoteamentoefiltro de redeisso funciona na minha caixa Debian 8, mas ainda assim recomendo adotar a primeira abordagem, pois é mais natural e não usa nenhum hacks.
Você também pode considerar construir seu aplicativo como umproxy transparente. Acho que seria muito mais fácil em vez de analisar pacotes do dispositivo tun.