Ainsi, dans votre configuration, tous les paquets que vous essayez d'envoyer au réseau proviennent initialement de 10.0.0.1(car ils passent par l' tun0interface et son adresse locale est 10.0.0.1). Vous capturez les paquets, tout va bien jusqu'à présent.
Maintenant, tun0envoie les paquets plus loin. L'adresse source est 10.0.0.1et vous voulez que les paquets partent via une interface différente ( wlp2s0dans votre cas). C'est le routage, alors activons d'abord le routage:
sysctl -w net.ipv4.ip_forward=1
Après cela, si vous regardez tcpdumppour wlp2s0vous pouvez remarquer les paquets partent avec adresse source 10.0.0.1et non pas avec l'adresse source de l'interface wlan (ce que vous attendez , je suppose). Nous devons donc changer l'adresse source et cela s'appelle NAT source . Sous Linux, c'est facile avec l'aide de netfilter / iptables :
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE
Veuillez également vérifier que votre FORWARDchaîne a une ACCEPTpolitique ou vous devez autoriser le transfert avec quelque chose comme:
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
Tout devrait fonctionner maintenant: le noyau linux fait le routage, il déplace les paquets de l' tun0interface vers wlp2s0. netfilter devrait changer l'adresse IP source en l' adresse assignée 10.0.0.1à votre wlp2s0interface pour les paquets de sortie. Il mémorise toutes les connexions et lorsque les paquets de réponse reviennent (s'ils le sont), il change l'adresse de destination de l' wlp2s0adresse affectée à l' interface en 10.0.0.1(la fonction "conntrack").
Eh bien, cela devrait, mais ce n'est pas le cas. Il semble que netfilter soit confondu avec cette configuration de routage compliquée et le fait que le même paquet passe d'abord par la OUTPUTchaîne, puis est routé et arrive en PREROUTINGchaîne. Au moins sur Debian 8, cela ne fonctionne pas.
La meilleure façon de dépanner netfilter est la TRACEfonctionnalité:
modprobe ipt_LOG
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE
J'active uniquement le traçage pour les paquets ICMP, vous pouvez utiliser un autre filtre pour déboguer.
Il montrera quelles tables et chaînes le paquet traverse. Et je peux voir que le paquet ne va pas plus loin dans la FORWARDchaîne (et qu'il n'est pas attrapé par la nat/POSTROUTINGchaîne qui le fait SNAT).
Vous trouverez ci-dessous plusieurs approches pour que cela fonctionne.
APPROCHE # 1
La meilleure façon de ne pas confondre netfilter est de changer l'adresse IP source des paquets dans l' tun0.capplication. C'est aussi le moyen le plus naturel. Nous devons changer 10.0.0.1 en 10.0.0.2 à l'aller et 10.0.0.2 à 10.0.0.1 au retour.
J'ai modifié tun0.cavec le code de changement d'adresse source. Voici le nouveau fichier et voici le fichier patch pour votre tun0.c. Les modifications apportées à l'en-tête IP impliquent également une correction de la somme de contrôle , j'ai donc pris du code du projet OpenVPN . Voici la liste complète des commandes que j'exécute après un redémarrage et un tun0_changeip.clancement propres :
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
Veuillez noter que vous n'avez pas besoin de désactiver le filtrage de chemin inverse dans ce cas, car tout est légal - tun0ne reçoit et n'envoie que les paquets qui appartiennent à son sous-réseau. Vous pouvez également faire un routage basé sur la source au lieu d'une interface.
APPROCHE # 2
Il est possible de le faire SNATavant que l' tun0interface atteigne le paquet . Ce n'est pas très correct cependant. Vous devrez certainement désactiver le filtrage de chemin inverse dans ce cas:
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
Maintenant, faites SNAT: iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source ip.address.of.your.wlan.interface
Ici, nous changeons l'adresse source juste avant que les paquets n'atteignent l' tun0appareil. tun0.cle code renvoie ces paquets "tels quels" (avec l'adresse source modifiée) et ils sont correctement acheminés via l'interface WLAN. Mais vous pourriez avoir une IP dynamique sur l'interface wlan et vouloir utiliser MASQUERADE(afin de ne pas spécifier l'adresse d'interface explicitement). Voici comment vous pouvez utiliser 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
Veuillez noter l' 10.0.55.1adresse IP " " - c'est différent. Vous pouvez utiliser n'importe quelle adresse IP ici, peu importe. Les paquets atteignent la nat/POSTROUTINGchaîne sur l' wlp2s0interface si nous changeons l'IP source avant. Et maintenant, il ne dépend pas d'une adresse IP statique pour l'interface WLAN.
APPROCHE # 3
Vous pouvez également utiliser fwmark. De cette façon , vous n'avez pas besoin SNATmais vous capturer des paquets sortants seulement:
nous devons d'abord désactiver chemin inverse filtrage pour , tun0car il transmet des paquets qui appartiennent à un autre réseau:
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
C'est un autre "hack" pour le routage et le netfilter qui fonctionne sur ma boîte Debian 8, mais je recommande quand même de prendre la première approche car elle est plus naturelle et n'utilise pas de hacks.
Vous pouvez également envisager de créer votre application en tant que proxy transparent . Je pense que ce serait beaucoup plus facile au lieu d'analyser les paquets du périphérique tun.
-j SNAT, pas-s SNAT