So leiten Sie den gesamten Datenverkehr in Linux über eine einzige Schnittstelle

So leiten Sie den gesamten Datenverkehr in Linux über eine einzige Schnittstelle

Ich habe einselbstgeschriebene Schnittstelle tun0(TUN/TAPbasiert), das ausgibt, was es empfängt.
Ich brauche den gesamten Datenverkehr des Systems, der über diese Schnittstelle fließt.
Die Rolle der Schnittstelle ist:

  1. Um wahrscheinlich zensierte Pakete zu erkennen und zu tunneln.
  2. Fahren Sie am restlichen Verkehr unbehelligt vorbei.

Wie Sie sich vorstellen können, versuche ich, ein Antizensur-Tool zu entwickeln.
Die Entscheidung über das Tunneln muss im tun0-Prozess getroffen werden,
da wir nur dort vertrauenswürdiges DNS verwenden können.

Ich brauche Ihre Hilfe, um mir zu zeigen, wie ich den gesamten Datenverkehr über eine selbstgeschriebene Schnittstelle tun0 fließen lassen kann. Wenn tun0 Änderungen benötigt, bitte ich Sie, mir diese Änderungen bereitzustellen.

Unten sehen Sie, wie ich versucht habe, den gesamten Datenverkehr über tun0 laufen zu lassen, was mir nicht gelungen ist (Pings schlagen fehl).

Kompilieren

  1. gcc tun0.c
  2. sudo ./a.out

Konfigurieren

  1. sudo ip addr add 10.0.0.1/24 dev tun0
  2. Tabelle erstellen John

    $ cat /etc/iproute2/rt_tables 
    #
    # reserved values
    #
    255     local
    254     main
    253     default
    0       unspec
    #
    # local
    #
    #1      inr.ruhep
    
    200 John
    

Reihenfolge ist wichtig:

  1. sudo ip rule add from all lookup John
  2. sudo ip route add default dev tun0 table John
  3. 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 
    

Fehlerbehebung

  1. sudo tcpdump -i wlp2s0 -qtln icmpund dann ping -I tun0 8.8.8.8wird angezeigt, dass keine Pakete erfasst wurden. Dies bedeutet, dass per Regel keine Pakete von tun0 an wlp2s0 übertragen werden iif tun0 lookup main.

  2. Als ich es tun0durch lo„überall“ ersetzt habe, hat es bei mir funktioniert.

Auch versucht

  1. Deaktivieren der Rückpfadfilterung rp_filter=0in/etc/sysctl.conf

Antwort Fehlerbehebung

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

Modifizierte Quellen aus der Antwort sind auchHier.

Antwort1

In Ihrer Konfiguration stammen also alle Pakete, die Sie an das Netzwerk senden möchten, ursprünglich von 10.0.0.1(weil sie durch die Schnittstelle gehen tun0und deren lokale Adresse lautet 10.0.0.1). Sie erfassen die Pakete, soweit ist alles in Ordnung.
Jetzt tun0sendet er die Pakete weiter.Quelladresseist 10.0.0.1und Sie möchten, dass die Pakete über eine andere Schnittstelle (in Ihrem Fall) gehen wlp2s0. Das istRoutenplanungAktivieren wir also zuerst das Routing:

sysctl -w net.ipv4.ip_forward=1

tcpdumpWenn Sie danach nachsehen, wlp2s0können Sie feststellen, dass die Pakete mit der Quelladresse 10.0.0.1und nicht mit der Quelladresse der WLAN-Schnittstelle abreisen (was Sie wohl erwarten würden). Wir müssen also die Quelladresse ändern und sie heißtQuell-NAT. Unter Linux ist es einfach mit Hilfe vonNetzfilter/iptables:

iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE

Bitte prüfen Sie auch, ob Ihre FORWARDKette ACCEPTRichtlinien hat, sonst müssen SieWeiterleitung zulassenmit etwas wie:

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

Jetzt sollte alles funktionieren:Linux Kernelführt das Routing durch, es verschiebt Pakete von tun0der Schnittstelle zur wlp2s0.Netzfilter10.0.0.1sollte die Quell-IP in die Ihrer Schnittstelle zugewiesene Adresse für Ausgabepakete ändern wlp2s0. Es merkt sich alle Verbindungen und wenn die Antwortpakete zurückgehen (falls sie es tun), ändert es die Zieladresse der der wlp2s0Schnittstelle zugewiesenen Adresse in 10.0.0.1(die „Conntrack“-Funktion).
Nun, es sollte, tut es aber nicht. Es scheint,Netzfilterwird durch diese komplizierte Routing-Konfiguration und die Tatsache, dass dasselbe Paket zuerst durch die OUTPUTKette geht und dann geroutet wird und zur PREROUTINGKette kommt, verwirrt. Zumindest auf meiner Debian 8-Box funktioniert es nicht.
Der beste Weg zur FehlerbehebungNetzfilterist die TRACEFunktion:

modprobe ipt_LOG
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE

Ich aktiviere nur die Ablaufverfolgung für ICMP-Pakete. Sie können zum Debuggen auch andere Filter verwenden.
Es wird angezeigt, welche Tabellen und Ketten das Paket durchläuft. Und ich kann sehen, dass das Paket die FORWARDKette nicht weiter durchläuft (und es wird nicht von der nat/POSTROUTINGKette abgefangen, die es tatsächlich durchläuft SNAT).
Im Folgenden finden Sie mehrere Ansätze, um dies zum Laufen zu bringen.

Ansatz Nr. 1

Der beste Weg, Verwirrung zu beseitigenNetzfilterist, die Quell-IP-Adresse von Paketen in der Anwendung zu ändern tun0.c. Das ist auch der natürlichste Weg. Wir müssenÄndern Sie 10.0.0.1 in 10.0.0.2auf dem Weg nach draußen und10.0.0.2 bis 10.0.0.1auf dem Rückweg.
Ich habe es tun0.cmit dem Quelladressenänderungscode geändert.Hier ist die neue DateiUndhier ist die Patchdateifür Ihre tun0.c. Änderungen am IP-Header beinhalten auchPrüfsummenkorrektur, also habe ich etwas Code vonOpenVPN-Projekt. Hier ist die vollständige Liste der Befehle, die ich nach einem sauberen Neustart und tun0_changeip.cStart ausführe:

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

Bitte beachten Sie, dass Sie denRückwärtspfadfilterungin diesem Fall ist alles legal – tun0empfängt und sendet nur Pakete, die zu seinem Subnetz gehören. Außerdem können Sie ein quellbasiertes Routing anstelle eines schnittstellenbasierten Routings durchführen.

Ansatz Nr. 2

Dies ist möglich, SNATbevor das Paket tun0die Schnittstelle erreicht. Es ist jedoch nicht sehr korrekt. Sie müssen auf jeden Fall dieRückwärtspfadfilterungin diesem Fall:

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

Führen Sie nun Folgendes aus SNAT: iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source ip.address.of.your.wlan.interface

Hier ändern wir einfach die QuelladresseVordie Pakete erreichen das tun0Gerät. tun0.cDer Code sendet diese Pakete „wie sie sind“ (mit geänderter Quelladresse) erneut und sie werden erfolgreich durch die WLAN-Schnittstelle geleitet. Möglicherweise haben Sie jedoch eine dynamische IP auf der WLAN-Schnittstelle und möchten diese verwenden MASQUERADE(um die Schnittstellenadresse nicht explizit anzugeben). So können Sie Folgendes nutzen 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

Bitte beachten Sie die " 10.0.55.1" IP-Adresse - sie ist anders. Sie können hier jede beliebige IP verwenden, es spielt keine Rolle. Die Pakete erreichen nat/POSTROUTINGdie Kette auf wlp2s0der Schnittstelle, wenn wir die Quell-IP vorher ändern. Und jetzt ist es nicht mehr von einer statischen IP für die WLAN-Schnittstelle abhängig.

Ansatz Nr. 3

Sie können auch verwenden fwmark. Auf diese Weise brauchen Sie nicht, SNATaber Sie erfassen nur ausgehende Pakete:
Zuerst müssen wir deaktivierenRückwärtspfadfilterungweil tun0es Pakete weiterleitet, die zu einem anderen Netzwerk gehören:

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

Das ist ein weiterer "Hack" fürRoutenplanungUndNetzfilterdas funktioniert auf meiner Debian 8-Box, aber ich empfehle trotzdem den ersten Ansatz, da dieser natürlicher ist und keine Hacks verwendet.


Sie können Ihre Anwendung auch alstransparenter Proxy. Ich denke, es wäre viel einfacher, als Pakete vom Tun-Gerät zu analysieren.

verwandte Informationen