Verhindern, dass VPN-Clients sich im Tunnel gegenseitig erreichen
Einen Dienst zu erreichen ist eine Route, einen anderen Client zu erreichen ist Richtlinie. Finden Sie den Weiterleitungspunkt, der den Peer-Verkehr entscheidet, und weisen Sie die Sperre von einem Client aus nach.
Zwei Clients können beide den Jump-Host öffnen und trotzdem nichts damit zu tun haben, einander zu öffnen. Einen Dienst zu erreichen ist eine Weiterleitungsentscheidung, während einen Peer zu erreichen eine Richtlinienentscheidung ist, und die meisten VPN-Stacks halten beides in getrennten Objekten. Nichts, was Sie für das erste konfigurieren, setzt das zweite durch. Die Aufgabe besteht daher nicht darin, eine Regel hinzuzufügen, sondern das Objekt zu finden, das auf diesem Server den Peer-Verkehr entscheidet, die Sperre dort zu schreiben und sie von einem Client aus nachzuweisen.
Eine Route zum gemeinsamen Dienst ist keine Erlaubnis zwischen Peers
Das Ankündigen des Client-Subnetzes sagt einem Peer, wie er ein Paket auf die Leitung in Richtung der Adresse eines anderen Clients legt. Ob dieses Paket zugestellt wird, entscheidet sich danach, durch das, was es weiterleitet. Auf einem Linux-Gateway ist das die FORWARD-Kette; in einem Daemon im Userspace ist es die eigene Sitzungstabelle des Tunnels. Eine Route beantwortet die Erreichbarkeit und lässt die Erlaubnis unberührt.
Deshalb beweist eine Isolationsprüfung, die nur Routen liest, nichts. Ein /24 kann an jeden Client verteilt werden, während jedes Peer-zu-Peer-Paket am Weiterleitungshaken verworfen wird. Gefährlich ist der umgekehrte Fall: keine ausdrückliche Regel, eine freizügige Voreinstellung und eine Isolation, die nur existiert, weil sie niemand getestet hat.
Schreiben Sie die Anforderung in einer Zeile auf, bevor Sie ein Terminal öffnen. Erreichen Sie den Dienstblock und den Jump-Host, erreichen Sie nichts anderes innerhalb des Client-Blocks.
Finden Sie heraus, wer das Peer-Paket tatsächlich weiterleitet
Zwei Serververhalten sehen von der Client-Seite gleich aus und verlangen unterschiedliche Regeln. Entweder leitet der Kernel das Paket erneut aus der Tunnel-Schnittstelle heraus, oder der Daemon kopiert es zwischen Sitzungen, und der Kernel sieht es nie.
WireGuard gehört zur ersten Gruppe: Es hat keinen Peer-zu-Peer-Schalter, also kommt ein Paket von 10.8.0.4 nach 10.8.0.5 auf wg0 an, trifft den Weiterleitungshaken und wird wieder aus wg0 geroutet, wenn AllowedIPs beide Adressen abdeckt. OpenVPN ist die zweite Gruppe, sobald client-to-client in der Serverkonfiguration gesetzt ist, weil diese Direktive das Paket im Userspace zwischen Sitzungen übergibt. Prüfen Sie die geladene Konfiguration auf diese Direktive, bevor Sie etwas schreiben. Eine Kernelregel, die nie Verkehr sieht, ist von einer Regel, die funktioniert, nicht zu unterscheiden, und so endet ein Rollout ganz ohne Isolation.
Lesen Sie die effektive Konfiguration statt der Datei, von der Sie annehmen, dass sie geladen ist, denn Distributionspakete bringen ihre eigenen Includes mit. Wenn der Daemon weiterleitet, gehört die Sperre in seine eigenen Steuerungen pro Client, und eine Host-Firewall filtert nur Verkehr, der an den Host adressiert ist. Wenn der Kernel weiterleitet, ist der Weiterleitungshaken der einzige Ort, der zählt.
Geroutete und übersetzte Bereitstellungen brauchen eine weitere Prüfung: die Quelle, die ein entfernter Client sieht, ist möglicherweise nicht die erwartete. Dann trifft eine Regel, die auf das Client-Subnetz passt, auf nichts zu. Notieren Sie die Adresse, die die Übersetzung übersteht, bevor Sie den Treffer schreiben, und ziehen Sie es vor, das Schnittstellenpaar zu treffen, statt NAT-Adressen zu raten.
Geben Sie jeder Adresse eine Identität, die sich einzeln widerrufen lässt
Die Isolation bricht zusammen, sobald zwei Geräte eine Anmeldeinformation teilen. Eine an diese Identität gebundene Regel kann sie nicht trennen, und der Widerruf eines verlorenen Laptops widerruft die ganze Gruppe. Zertifikate pro Gerät oder Schlüssel pro Peer halten den Widerruf lokal und die Richtlinie lesbar, weil jede Adresse genau einer Person oder Maschine entspricht. Wo das Design das nicht kann, sagen Sie es im Runbook, statt die Regel als feinkörnig zu beschreiben.
Die Adressvergabe muss zur Richtlinie passen. Reservieren Sie einen Block für Dienste, einen Block für Clients, und vergeben Sie Client-Adressen aus einem Pool, den Sie kontrollieren, statt aus einem Wer-zuerst-kommt-Bereich. Wenn der Server übersetzt oder überbrückt, halten Sie die Zuordnungstabelle neben der Konfiguration, denn genau die braucht der nächste Leser, um die Regel neu abzuleiten.
Setzen Sie die Sperre dorthin, wo das Paket den Tunnel überquert
Auf einem Gateway, das WireGuard-Verkehr weiterleitet, decken zwei Regeln den Fall ab: den Dienstblock erlauben, dann den Rest des Client-Blocks verwerfen. Das Schnittstellenpaar zählt so viel wie die Adressen, denn ein Treffer nur auf das Ziel fängt auch Verkehr aus dem LAN ab. Laden Sie sie in dieser Reihenfolge, damit die Erlaubnis zuerst ausgewertet wird.
Mit nftables geht das Paar in eine vorhandene inet-filter-Tabelle, Erlaubnis zuerst und Verwerfen danach. Beide Treffer binden das Schnittstellenpaar sowie die Adressen.
nft add rule inet filter forward iifname "wg0" oifname "wg0" ip saddr 10.8.0.0/24 ip daddr 10.8.2.0/24 accept
nft add rule inet filter forward iifname "wg0" oifname "wg0" ip saddr 10.8.0.0/24 ip daddr 10.8.0.0/24 drop
Lesen Sie die Kette nach dem Laden zurück, statt dem Exit-Status zu vertrauen, und bestätigen Sie, dass beide Regeln in der beabsichtigten Reihenfolge stehen. Fügen Sie passende ip6-Regeln für den IPv6-Pool hinzu, sonst ist das v4-Paar auf einem Dual-Stack-Tunnel nur Dekoration. Wenn der Server bereits eine freizügige Weiterleitungsrichtlinie hat, fügen Sie das Verwerfen hinzu, statt die Kette ganz zu ersetzen.
Wenn client-to-client auf OpenVPN aktiviert ist, treffen diese Weiterleitungsregeln nie Peer-Verkehr, und die Sperre muss in den eigenen Steuerungen des Daemons liegen. Behalten Sie die Kernelregeln für Verkehr an den Host, aber zählen Sie sie nicht als Isolationssteuerung.
Weisen Sie die Sperre von einem Client nach, nicht vom Server
Tests vom Gateway aus beweisen nichts, weil lokal erzeugter Verkehr den Ausgabepfad nimmt und den Weiterleitungshaken nie überquert. Verwenden Sie zwei echte Clients: einen, der den Dienst erreichen soll, einen, der abgelehnt werden soll. Führen Sie zuerst den Erlaubnisfall aus, damit ein defekter Tunnel nicht für eine funktionierende Richtlinie gehalten wird.
Bestätigen Sie vom erlaubten Client aus, dass der Dienst auf seinem Port antwortet. Versuchen Sie vom selben Client aus die Peer-Adresse und erwarten Sie ein stilles Verwerfen statt einer Ablehnung:
ping -c 3 -W 2 10.8.0.5
nc -z -w 2 10.8.0.5 22
nft list chain inet filter forward
iptables -vnL FORWARD
ping -6 -c 3 -W 2 fd00:8::5
Ein verworfenes Paket und ein Offline-Peer sehen beide wie eine Zeitüberschreitung aus, prüfen Sie also die Zähler, bevor Sie etwas schließen. Bestätigen Sie, dass der Zähler der Verwerfungsregel steigt, während der Peer nachweislich erreichbar ist. Wiederholen Sie das über IPv6, wo eine fehlende ip6-Regel die v4-Sperre wirksam aussehen lässt. Halten Sie die akzeptierten und abgelehnten Ergebnisse mit Datum im Runbook fest, weil die nächste Migration die Regel neu ableiten wird.