Sie können ein Programm nicht von einem WireGuard-Host mit vollem Tunnel ausnehmen, indem Sie Routen bearbeiten. Routen wählen einen Pfad nach Ziel, und was Sie ausnehmen wollen, ist ein Prozess, also hat der Kernel nichts, womit er abgleichen könnte. Der gangbare Weg ist, diesem Prozess einen eigenen Netzwerkkontext zu geben: ein Namespace mit eigener Schnittstelle, eigenen Adressen und eigener Standardroute, über ein veth-Paar mit dem Host verbunden. Ich habe das unter Ubuntu 24.04 mit wireguard-tools 1.0.20210914 ausgeführt, und der Namespace war nie das Problem — die Weiterleitungsrichtlinie des Hosts und die Markierungsregeln des Tunnels waren es.

Wählen Sie zuerst die Art von Kontext, die Sie brauchen

In der Praxis kommen zwei Formen vor. Läuft auf dem Host ein voller Tunnel und soll ein Programm über den ISP-Pfad hinaus, bauen Sie einen zweiten Namespace, verbinden ihn mit dem Host und lassen den Host für ihn weiterleiten und übersetzen. Trägt ein Namespace bereits eine VPN-Schnittstelle und brauchen Sie nur einen darin gestarteten Befehl, ist das der gewöhnliche ip netns exec-Fall, und die meiste Routing-Arbeit ist schon erledigt.

Keine der beiden Formen gibt Ihnen eine Regel, die auf eine einzelne Prozess-ID beschränkt ist. Netfilter gleicht Adressen, Ports, Markierungen und Schnittstellen ab; eine Routing-Tabelle pro Prozess gibt es nicht. Markierungen können Verkehr lenken, aber die Markierung muss auf Pakete gesetzt werden, die Sie bereits identifiziert haben, und das ist dasselbe Problem eine Ebene tiefer. Ein Namespace trennt den gesamten Stack für diesen Prozessbaum, und deshalb ist er die übliche Antwort.

Wenn die Anforderung wirklich lautet, dass nichts den Tunnel verlässt, stoppen Sie stattdessen den Tunnel. Der Namespace existiert für den gemischten Fall: ein Programm hinaus, alles andere hinein, auf derselben Maschine, zur selben Zeit.

Bauen Sie den zweiten Kontext und verbinden Sie ihn mit dem Host

Ein illustratives Layout: Der Host hat eine WireGuard-Schnittstelle, die die Standardroute trägt, und einen Netzwerk-Namespace namens clearnet der über ein veth-Paar mit dem Host verbunden ist. Die Adressen unten sind Beispiele.

ip netns add clearnet
ip link add veth-clear-out type veth peer name veth-clear-in
ip addr add 192.168.100.1/24 dev veth-clear-out
ip link set veth-clear-out up
ip link set veth-clear-in netns clearnet
ip netns exec clearnet ip addr add 192.168.100.2/24 dev veth-clear-in
ip netns exec clearnet ip link set veth-clear-in up
ip netns exec clearnet ip route add default via 192.168.100.1

Dieser Namespace kann jetzt den Host erreichen und sonst nichts. Der Host muss den Verkehr weiterleiten und die Quelladresse umschreiben, denn 192.168.100.0/24 ist privat, und der Upstream-Router hat keine Route dorthin zurück:

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o <wan-interface> -j MASQUERADE

Bestätigen Sie die Namespace-Seite, bevor Sie weitermachen.ip netns exec clearnet ip route sollte die veth-Route und die Standardroute über 192.168.100.1 zeigen, und ein Ping auf diese Adresse sollte antworten. Schlägt der Ping auf die Host-Adresse fehl, sind die Adressen oder der Link-Zustand falsch, und keine Firewall-Regel hilft.

Wenn Namen aufgelöst werden, aber nichts zurückkommt, lesen Sie FORWARD

Der klassische Fehler sieht wie ein Routing-Bug aus: Der Namespace löst einen Namen auf, das Paket geht hinaus, und es kommt nie eine Antwort an. Auf Hosts mit einer FORWARD-Policy DROP — das tun mehrere Distributionen und die meisten gehärteten Images — wird das Paket unterwegs verworfen, und die Fehlermeldung der Anwendung sagt nichts über Filterung.

Lesen Sie die Kette, bevor Sie etwas hinzufügen:

iptables -S FORWARD
nft list chain inet filter forward

Lassen Sie den Verkehr dann in beide Richtungen zu, mit Zählern, damit Sie sehen, ob die Regel je getroffen hat:

iptables -A FORWARD -i veth-clear-out -o <wan-interface> -j ACCEPT
iptables -A FORWARD -i <wan-interface> -o veth-clear-out -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
watch -n1 'iptables -L FORWARD -v -n'

Eine Regel mit einem Paketzähler von null ist nicht im Pfad. Entweder weichen die Schnittstellennamen von Ihrer Annahme ab, oder eine frühere Regel in der Kette hat das Paket zuerst akzeptiert, verworfen oder zurückgegeben. Korrigieren Sie die Reihenfolge, nicht den Regeltext.

Antwortverkehr ist die Hälfte, die man vergisst. Die Rückregel braucht denselben veth-Namen plus einen Verbindungszustands-Abgleich oder eine einfache Schnittstellen-Annahme, wenn Sie die Policy offen halten. Fügen Sie nur die ausgehende Regel hinzu, und das ursprüngliche Symptom ist zurück, während Ihre neue Regel dort steht und korrekt aussieht.

Halten Sie die Markierungsregeln des Tunnels vom neuen Pfad fern

Dieser Schritt macht aus einem funktionierenden Namespace einen leckenden. WireGuard-Setups installieren üblicherweise eine Firewall-Markierungsrichtlinie samt eigenen Routing-Regeln und einer eigenen Tabelle, sodass unmarkierte Pakete auf die Haupttabelle zurückfallen, während markierte Pakete die Tunnel-Tabelle nutzen. Weitergeleiteter Verkehr aus dem Namespace wird beim Hinausgehen gegen Policy-Routing geprüft und kann, je nachdem wie diese Regeln geschrieben wurden, in der Tunnel-Tabelle landen.

Zwei Ergänzungen trennen die Pfade. Kehren Sie in der mangle-Kette für das Namespace-Subnetz früh zurück, und fügen Sie eine quellenbasierte Regel hinzu, die dieses Subnetz in die Haupttabelle legt:

iptables -t mangle -I PREROUTING -s 192.168.100.0/24 -j RETURN
ip rule add from 192.168.100.0/24 lookup main priority 100

Priorität 100 sortiert auf meinem Host vor den Tunnelregeln, also entscheidet die gewöhnliche Tabelle für diese Quelle. Kopieren Sie die Zahl nicht blind: Die Prioritäten, die wg-quick installiert, unterscheiden sich zwischen Versionen und zwischen den IPv4- und IPv6-Setups, führen Sie also ip rule show aus und wählen Sie eine Priorität, die auf Ihrer Maschine vor den Tunnelregeln liegt.

Prüfen Sie mit einer quellenspezifischen Abfrage statt der Regelliste zu vertrauen:

ip route get 1.1.1.1 from 192.168.100.2
ip netns exec clearnet ip route get 1.1.1.1

Wenn der erste Befehl die WireGuard-Schnittstelle meldet, ist die neue Regel noch nicht vor der Tunnel-Policy. Wenn er die WAN-Schnittstelle meldet, während der zweite noch die veth-Standardroute zeigt, sind Host und Namespace uneinig, und Sie sollten beide Routing-Tabellen erneut lesen.

Starten Sie den Prozess, der die Verbindung öffnet

Den Befehl zu starten ist eine Zeile, aber starten Sie den Prozess, der den Socket tatsächlich erzeugt.ip netns exec clearnet curl -s https://ifconfig.me ist der kleinste ehrliche Test: Er zeigt die Adresse, die der Namespace der Welt präsentiert, nicht die, die der Host verwenden würde.

Binden Sie den Namespace bei einem Dienst über den Pfad ein, damit der Prozess sein ganzes Leben darin bleibt:

[Service]
NetworkNamespacePath=/run/netns/clearnet

Grafische Anwendungen sind der Ort, an dem der Ein-Zeilen-Ansatz still scheitert. Ein aus einem Menü gestarteter Browser übergibt die Anfrage oft an eine Instanz, die bereits außerhalb des Namespace läuft, sodass das neue Fenster erscheint und der Verkehr trotzdem durch den Tunnel geht. Geben Sie ihm ein eigenes Profil, damit wirklich eine neue Instanz entsteht, und prüfen Sie dann den Prozesskontext, statt zu raten:

readlink /proc/$(pgrep -f clearnet-profile | head -1)/ns/net
readlink /run/netns/clearnet

Die beiden Ausgaben müssen übereinstimmen. Dieselbe Prüfung funktioniert für jedes lang laufende Programm, und es lohnt sich, sie einmal pro Anwendung zu machen, statt anzunehmen, der Starter habe getan, was Sie meinten.

Namensauflösung braucht eine eigene Entscheidung. Einen Namespace anzulegen gibt ihm keine Resolver-Konfiguration; Dateien pro Namespace werden über /etc/netns/<name>/resolv.conf unterstützt, und ohne eine erben Sie ein Verhalten, das leicht falsch gelesen wird. IPv6 braucht dieselbe Behandlung: Hat der Namespace keine v6-Standardroute, während die Anwendung v6 bevorzugt, können Anfragen hängen bleiben, bevor sie zurückfallen, was wie ein kaputter Tunnel aussieht.

Prüfen Sie den Rahmen, nicht nur die Ausgangsadresse

Eine funktionierende öffentliche Adresse beweist die Route, nicht die ganze Anforderung. Gehen Sie den Rest in dieser Reihenfolge durch:

  • ip netns exec clearnet ip route get 1.1.1.1 zeigt die veth-Standardroute, nicht die WireGuard-Schnittstelle.
  • Die FORWARD-Zähler beider Regeln steigen, während eine Anfrage läuft.
  • Der Anwendungsprozess meldet den Namespace-Inode, den Sie erwarten.
  • Nach einem Neustart existiert der Namespace, bevor der Dienst startet; eine Unit, die früher läuft, scheitert oder, schlimmer, läuft außerhalb des Namespace.

Entscheiden Sie dann, was passieren soll, wenn der Tunnel wegfällt. Der Namespace funktioniert weiter, was der Sinn der Übung und zugleich das Risiko ist: Das ausgenommene Programm bleibt verbunden, während alles andere stoppt. Halten Sie das als Richtlinienentscheidung fest und seien Sie klar darüber, was die Ausnahme nicht abdeckt — Kontoidentität, gespeicherter Browserzustand und Ihr DNS-Anbieter liegen alle außerhalb des Geltungsbereichs eines Netzwerk-Namespace, und die Ausnahme als Anonymität zu behandeln ist der Fehler, der die Konfiguration überlebt.

Ähnliche Artikel