Ein zweiter OpenVPN Server gibt Ihnen einen zweiten Ort, an dem sich Clients verbinden können, und mehr nicht. Er bringt diese Clients nicht in das Netz des ersten Servers, und die Option client-to-client ändert nur die Weiterleitung innerhalb eines einzelnen Serverprozesses. Die zwei Pools werden zu einem Netz, wenn Sie bewusst zwischen ihnen routen, mit einem Verantwortlichen für jede Richtung. Alles Folgende setzt den TUN-Modus im Userspace mit abgeschalteter interner Weiterleitung voraus, sodass der Kernel die Entscheidung trifft.

Der Mythos: eine Kontenliste, ein Netz

Authentifizierung und Erreichbarkeit werden verwechselt, weil beides in der Serverkonfiguration lebt. Ein Benutzer, der sich an beiden Gateways anmelden kann, wirkt von außen wie ein Benutzer auf einem System mit zwei Türen. Innen verteilt jeder Server Adressen aus seinem eigenen Pool und installiert Routen nur für die Clients, die er terminiert. Ein Client an Gateway A, der ein Paket an einen Client an Gateway B schickt, fragt also nach einem Ziel, von dem sein eigener Server nie gehört hat. Das Paket geht an die Standardroute von A, verlässt den Tunnel und kommt bei einer Firewall an, die nie gebeten wurde, es zuzulassen.

Einen zweiten Server hinzuzufügen bringt daher keine Redundanz, keine Erkennung und keine gemeinsame Broadcast-Domäne. Es fügt ein geroutetes Netz hinzu, das einen Plan braucht, und der Plan beginnt bei der Adressierung.

Geben Sie jedem Gateway einen eigenen Pool und eine Transitadresse

Zwei Bereiche, die sich mit nichts anderem überschneiden dürfen, plus eine kleine Transitverbindung zwischen den Hosts – das ist der ganze Adressplan. Halten Sie den Transit in einem privaten Segment, das Sie kontrollieren, und schreiben Sie die Zahlen auf, bevor irgendein Server eine Lease vergibt.

GatewayClient poolTransit address
gateway-a10.64.10.0/24172.28.44.1/30
gateway-b10.64.20.0/24172.28.44.2/30

Widerstehen Sie der Versuchung, beiden Servern denselben Pool zu geben, damit die Profile gleich bleiben. Eine Kernelroute kann nicht sagen, welcher von zwei Hosts derzeit eine beliebige Adresse innerhalb eines gemeinsamen Bereichs besitzt, also würde die Routingtabelle auf ein Gateway zeigen, während der Client am anderen hängt. Schnittstellennamen sind lokale Konventionen, kein gemeinsamer Zustand. Beide Hosts hier nennen das Tunnelgerät tun0 und die Transitverbindung transit0, was in Ordnung ist, weil kein Paket diese Namen trägt.

Installieren Sie die Route auf beiden Seiten

Jedes Gateway braucht eine Route für den Pool des anderen über die Transitadresse, und die Weiterleitung muss aktiv sein, damit eines als Hop dienen kann. Bestätigen Sie zuerst die aktuelle Tabelle, fügen Sie dann den Eintrag hinzu und machen Sie ihn über den Netzwerkmanager des Hosts dauerhaft statt über einen Reconnect-Hook.

sysctl net.ipv4.ip_forward
ip route add 10.64.20.0/24 via 172.28.44.2 dev transit0
ip route get 10.64.20.37

Spiegeln Sie das auf dem anderen Host mit getauschten Pools. Wiederholtes Anhängen derselben Route aus einem fremden Skript ist der Weg, auf dem ein Host mehrere Kopien und beim nächsten Blick in die Tabelle eine rätselhafte Änderung bekommt. Ist die Transitverbindung selbst ein Tunnel, zeigt die Route auf dessen Topologie, und der Hop muss dessen Reconnect überleben. Eine Transitadresse, die dreißig Sekunden verschwindet, nimmt den Weg zwischen den Pools mit, was eine Designeigenschaft ist, die man besser benennt, als sie zu entdecken.

Schieben Sie die Client-Route, ohne Eigentum vorzutäuschen

Clients brauchen eine Route für den entfernten Pool, sonst schickt ihr eigenes Betriebssystem das Paket an sein Standard-Gateway, und der Tunnel sieht es nie. Die Serverkonfiguration ist der natürliche Ort, das auszuliefern.

push "route 10.64.20.0 255.255.255.0"

Setzen Sie die Spiegelzeile in die Konfiguration des anderen Servers, verbinden Sie dann einen Testclient neu und lesen Sie dessen Tabelle. Ein Client, der geschobene Routen ignoriert, braucht seine eigene freigegebene Konfiguration, und eine Route, die nie ankommt, ist keine Zugangskontrolle. Geben Sie einem Client kein iroute für den gesamten Pool des anderen Gateways. Diese Direktive existiert für ein Subnetz hinter einem verbundenen Client, und sie zu benutzen, um eine fehlende Route zwischen den Gateways zu überdecken, erzeugt einen Server, der glaubt, Adressen zu besitzen, die er nicht erreichen kann.

Beweisen Sie eine Anfrage und lehnen Sie eine andere ab

Wählen Sie eine echte Operation, zum Beispiel HTTPS von einem Client auf 10.64.10.21 zu einem Dienst auf 10.64.20.37, und erlauben Sie genau das auf beiden Hosts. Jede Firewall nimmt die Anfrage auf ihrer eingehenden Seite und die verfolgte Antwort auf der Rückseite an; die eigene Dienstrichtlinie des Ziels muss sie weiterhin akzeptieren.

iptables -A FORWARD -i tun0 -o transit0 -s 10.64.10.21 -d 10.64.20.37 -p tcp --dport 443 -j ACCEPT
iptables -A FORWARD -i transit0 -o tun0 -d 10.64.10.21 -s 10.64.20.37 -p tcp --sport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Mit gegenseitigen Routen ist Source-NAT unnötig und hier aktiv schädlich: das Übersetzen der Quelle verbirgt, welcher Client die Anfrage gestellt hat, und untergräbt quellbasierte Richtlinien auf der Zielseite. Prüfen Sie, ob eine bestehende Masquerade-Regel für den Internetausgang auch diesen Pfad erfasst. Testen Sie dann die Ablehnung. Ein Dienst, der lokal in Pool B bleiben soll, muss aus Pool A unerreichbar bleiben, und auch Client-Paare am selben Gateway müssen getestet werden, da die gerade geänderte Weiterleitungsrichtlinie auch für sie gilt.

Noch eine Korrektur des mentalen Modells: die Transitverbindung trägt entschlüsselte innere Pakete, ist also eine Vertrauensgrenze und keine private Garantie. Wenn sie ein Netz durchquert, das Sie nicht kontrollieren, schützen Sie diesen Hop mit einem genehmigten verschlüsselten Tunnel und routen Sie über dessen reale Topologie. End-to-End-TLS authentifiziert die Anwendung weiterhin selbst, weshalb der innere Dienst es weiter nutzen sollte.

Ähnliche Artikel