Du fügst eine Regel für VPN-Verkehr in der FORWARD-Kette hinzu, startest die Anfrage von derselben Linux-Maschine, und der Zähler bleibt bei null. Die Regel ist wahrscheinlich korrekt. Das Paket hat diesen Pfad nie genommen, weil eine auf dem Rechner selbst erzeugte Anfrage von ihm nicht weitergeleitet wird. Der Weg des Pakets vom Socket bis zum Kabel erklärt, warum das so ist und wohin die Regel stattdessen gehört.

Finde heraus, wo das Paket entstanden ist

Die Hook-Reihenfolge von Netfilter trennt drei Fälle, und nur einer davon betrifft FORWARD:

OriginPathHook that sees it
Local processOUTPUT then POSTROUTINGOUTPUT, POSTROUTING
Addressed to a local servicePREROUTING then INPUTPREROUTING, INPUT
Received for another hostPREROUTING, FORWARD, POSTROUTINGFORWARD

Eine lokale Anwendung beginnt im OUTPUT-Pfad, weil der Kernel bereits festgestellt hat, dass das Paket hier entsteht und nie für die Weiterleitung in Frage kommt. Einen Tunnel aufzubauen ändert diese Einordnung nicht; der Tunnel ist ein Gerät, durch das ein Paket den Rechner verlassen kann, keine Stufe, die lokale Ausgabe in Transit verwandelt.

Zwei Pakete, eine Geschichte

Sobald der Tunnel steht, sind das innere Paket der Anwendung und das verschlüsselte äußere Paket verschiedene Objekte. Das innere Paket trägt das Ziel und die Nutzlast, die die App gewählt hat. Das äußere Paket trägt Chiffretext an Adresse und Port des Peers, und genau dieses überquert tatsächlich die physische Schnittstelle.

Deine Richtlinie betrifft eines von beiden, und das falsche zu wählen ist ein häufiger Grund, warum eine Regel scheinbar nichts bewirkt. Eine Regel, die auf die äußere Adresse des Peers passt, sieht jedes Tunnelpaket gleich, egal was die Anwendung darin tut. Eine Regel, die auf ein inneres Ziel passt, sieht den Verkehr, der dich interessiert, und sie greift nur, wenn dieses Paket den Hook erreicht, auf dem du die Regel installiert hast.

Namespaces verschieben die Grenze

Ein Container macht das schwieriger, ohne das Prinzip zu ändern. Die Anfrage der Anwendung ist lokale Ausgabe innerhalb des Netzwerk-Namespace des Containers. Der Host empfängt diesen Verkehr an einer virtuellen Ethernet-Schnittstelle und kann ihn weiterleiten, daher kann eine FORWARD-Regel auf dem Host sinnvoll sein, obwohl der Prozess, der die Anfrage erzeugte, nie die OUTPUT-Kette des Hosts berührt hat.

Bevor du einen Hook wählst, stelle fest, wo das Regelset und der Tunnel tatsächlich leben. Ein Tunnel im Container, ein Tunnel auf dem Host mit durch ihn geroutetem Container und ein Tunnel in einem separaten Namespace sind drei verschiedene Topologien mit drei verschiedenen Regelplatzierungen. Lies die Regeln in dem Namespace, dem das Gerät gehört, nicht nur im Standard-Namespace.

Frag, ob du überhaupt eine Markierung brauchst

Wenn das Ziel ist, ein Zielpräfix durch den Tunnel zu schicken, kann eine Route für dieses Präfix ausreichen. Prüfe zuerst die effektiven Routen, einschließlich allem, was der Server geschoben hat: eine umgeleitete Standardroute schickt weit mehr Verkehr durch das VPN als die enge Richtlinie, die du im Sinn hattest, und keine Menge an Markierung bringt das Ergebnis mit der Absicht in Einklang.

Klassifizierung ist nötig, wenn die Entscheidung von etwas abhängt, das eine Route nicht ausdrücken kann, etwa von der Quelle, dem Benutzer oder dem Prozess. Für empfangenen Verkehr funktioniert Markieren in PREROUTING. Für lokalen Verkehr muss die Markierung in einer Ausgabestufe geschehen, die nach dem Setzen der Markierung eine neue Routensuche auslösen kann. Bei nftables ist das eine Kette vom Typ route am Output-Hook; eine gewöhnliche Output-Filterkette setzt den Wert und lässt die Route unverändert.

Bei iptables lebt das Äquivalent in der mangle-OUTPUT-Anordnung, und dieselbe Anforderung gilt: die Routingentscheidung muss nach dem Setzen der Markierung erneut getroffen werden. Dann muss eine Policy-Regel die Markierung konsumieren und auf eine Tabelle mit einer brauchbaren Route zeigen. Ein conntrack-Mark zu setzen ist ein dritter, getrennter Vorgang; er speichert einen Wert am Flow und setzt diesen Wert nicht von sich aus auf das aktuelle Paket, damit das Routing ihn liest.

Prüfe Nachschlagen und Zähler gemeinsam

nft list ruleset
ip route get 198.51.100.25
ip route get 198.51.100.25 mark 0x1

Adresse und Markierung sind illustrativ, und die beiden Routenabfragen beantworten verschiedene Fragen. Die zweite fragt, was der Kernel täte, wenn ein Paket diese Markierung trüge; sie zeigt nicht, dass dein Regelset eine vergibt. Behandle sie als Hypothesentest, nicht als Beleg, dass die Richtlinie funktioniert.

Führe dann eine harmlose Anfrage aus und beobachte zwei Dinge gleichzeitig: den Zähler am gewählten Hook und den Ausgang, den das Paket tatsächlich genommen hat. Bewegt sich der Zähler und verlässt das Paket den Rechner woanders, sind Markierung oder Tabelle falsch. Bewegt sich keines von beiden, erreicht das Paket diesen Hook überhaupt nicht, und die nächste Frage ist der Namespace oder der Pfad.

Zum Schluss begrenze den Test auf das, was der Mechanismus ausdrücken kann. Eine Route für eine Adresse wird keine dauerhafte Richtlinie für einen Dienst, dessen Adressen rotieren. Entscheide zuerst den Paketumfang und prüfe dann, ob das Routing- und Markierungsdesign diesen Umfang nach einer erneuten Verbindung halten kann.

Ähnliche Artikel