Quindi, nella tua configurazione, tutti i pacchetti che provi a inviare alla rete originariamente originari 10.0.0.1(perché stanno attraversando l' tun0interfaccia e il suo indirizzo locale è 10.0.0.1). Catturi i pacchetti, tutto va bene finora.
Ora tun0invia ulteriormente i pacchetti. L'indirizzo di origine è 10.0.0.1e vuoi che i pacchetti escano attraverso un'interfaccia diversa ( wlp2s0nel tuo caso). Questo è il routing, quindi abilitiamo prima il routing:
sysctl -w net.ipv4.ip_forward=1
Dopo di che, se si guarda a tcpdumpper wlp2s0è possibile notare i pacchetti in uscita con indirizzo sorgente 10.0.0.1e non con l'indirizzo sorgente dell'interfaccia wlan (quello che ti aspetteresti credo). Quindi dobbiamo cambiare l'indirizzo di origine e si chiama sorgente NAT . In linux è facile con l'aiuto di netfilter / iptables :
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE
Controlla anche che la tua FORWARDcatena abbia una ACCEPTpolitica o che dovresti consentire l'inoltro con qualcosa come:
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
Ora tutto dovrebbe funzionare: il kernel Linux esegue il routing, sta spostando i pacchetti tun0dall'interfaccia a wlp2s0. netfilter dovrebbe cambiare l'IP di origine 10.0.0.1al vostro wlp2s0interfaccia indirizzo assegnato per i pacchetti in uscita. Memorizza tutte le connessioni e quando i pacchetti di risposta tornano (se presenti) cambia l'indirizzo di destinazione dell'indirizzo wlp2s0assegnato all'interfaccia in 10.0.0.1(la funzione "conntrack").
Bene, dovrebbe ma non lo fa. Sembra che netfilter si confonda con questa complicata configurazione di routing e con il fatto che lo stesso pacchetto passa prima attraverso la OUTPUTcatena e poi viene instradato e arriva alla PREROUTINGcatena. Almeno su Debian 8 box non funziona.
Il modo migliore per risolvere netfilter è la TRACEfunzione:
modprobe ipt_LOG
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE
Abilito solo la traccia per i pacchetti ICMP, è possibile utilizzare altri filtri per il debug.
Mostrerà quali tabelle e catene attraversa il pacchetto. E vedo che il pacchetto non va oltre la FORWARDcatena (e non viene catturato dalla nat/POSTROUTINGcatena che effettivamente lo fa SNAT).
Di seguito sono riportati diversi approcci per farlo funzionare.
APPROCCIO # 1
Il modo migliore per annullare la confusione di netfilter è cambiare l'indirizzo IP di origine dei pacchetti tun0.cnell'applicazione. È anche il modo più naturale. Dobbiamo cambiare da 10.0.0.1 a 10.0.0.2 sulla strada verso l'esterno e da 10.0.0.2 a 10.0.0.1 sulla via del ritorno.
Ho modificato tun0.ccon il codice di modifica dell'indirizzo di origine. Ecco il nuovo file ed ecco il file di patch per il tuo tun0.c. Le modifiche all'intestazione IP implicano anche la correzione del checksum , quindi ho preso del codice dal progetto OpenVPN . Ecco l'elenco completo dei comandi che eseguo dopo un riavvio pulito e tun0_changeip.clancio:
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
In questo caso non è necessario disattivare il filtro del percorso inverso , poiché tutto è legale: tun0riceve e invia solo pacchetti che appartengono alla sua sottorete. Inoltre è possibile eseguire un routing basato sull'origine anziché basato sull'interfaccia.
APPROCCIO # 2
È possibile farlo SNATprima che l' tun0interfaccia del pacchetto raggiunga . Non è molto corretto però. In questo caso dovrai sicuramente disattivare il filtro del percorso inverso :
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
Ora, SNATesegui: iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT - to-source ip.address.of.your.wlan.interface
Qui cambiamo l'indirizzo sorgente appena prima che i pacchetti raggiungano il tun0dispositivo. tun0.cil codice invia nuovamente questi pacchetti "così come sono" (con l'indirizzo di origine modificato) e vengono instradati correttamente attraverso l'interfaccia wlan. Ma potresti avere un IP dinamico sull'interfaccia wlan e vuoi usarlo MASQUERADE(per non specificare esplicitamente l'indirizzo dell'interfaccia). Ecco come è possibile utilizzare 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
Si prega di notare l '" 10.0.55.1" indirizzo IP - è diverso. Puoi usare qualsiasi IP qui, non importa. I pacchetti raggiungono la nat/POSTROUTINGcatena wlp2s0sull'interfaccia se prima cambiamo l'IP di origine. E ora non dipende da un IP statico per l'interfaccia wlan.
APPROCCIO # 3
Puoi anche usare fwmark. In questo modo non è necessario SNATma dovrete catturare i pacchetti solo in uscita:
In primo luogo abbiamo bisogno di disabilitare il percorso inverso di filtraggio per tun0perché sarà inoltrare i pacchetti che appartengono a un'altra rete:
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
Questo è un altro "hack" per routing e netfilter che funziona sul mio Debian 8 box, ma consiglio comunque di adottare il primo approccio in quanto è più naturale e non usa alcun hack.
Puoi anche considerare di creare la tua applicazione come proxy trasparente . Penso che sarebbe molto più semplice invece di analizzare i pacchetti dal dispositivo tun.
-j SNAT, non-s SNAT