Eine Dienstadresse auf jedem OpenVPN-Knoten: was sie nicht leistet
Reserviere eine private /32 auf jedem Knoten, damit ein Client den Server erreicht, den er gewählt hat. Die Adresse macht kein Failover, verschiebt keine Sitzungen und wählt keinen gesunden Knoten.
Ein Client verbindet sich mit einem von mehreren OpenVPN-Servern und braucht dann einen kleinen Dienst, der auf genau diesem Knoten läuft: eine Statusseite, einen Metrik-Endpunkt, einen Backup-Agenten. Wenn jeder Knoten dieselbe private Dienstadresse erhält, ist die Konfiguration des Clients identisch, egal auf welchem Server er gelandet ist. Dieser Komfort ist real, und er lässt sich auch leicht überinterpretieren: Die gemeinsame Adresse sagt dir, welchen Knoten du erreicht hast, nicht dass irgendetwas redundant ist.
Warum dieselbe Adresse auf jedem Knoten funktioniert
Jeder Knoten besitzt die Adresse lokal und antwortet für sie, sodass ein Client, der sie über seinen aktuellen Tunnel erreicht, den Dienst am anderen Ende genau dieses Tunnels bekommt. Zwischen den Knoten wird nichts koordiniert, und kein Verkehr läuft von einem Knoten zum anderen.
Die Adresse ist ein lokales Etikett, wiederholt statt repliziert. Jeder Knoten antwortet nur für sich selbst, und keiner von ihnen leitet Verkehr für die Adresse im Namen eines anderen Knotens weiter. Das hält eine Client-Konfiguration gültig, während die Server unabhängig bleiben. Es ist auch der Grund, warum das Design keine Koordination zwischen den Knoten braucht.
Deshalb funktioniert dieselbe Konfiguration auf jedem Server ohne ein Routing-Protokoll zwischen ihnen. Es ist auch der Grund, warum das Design nichts über Gesundheit aussagt: Die Adresse existiert auf einem ungesunden Knoten genauso wie auf einem gesunden, weil sie an den Host gebunden ist und nicht daran, dass der Dienst nützlich ist.
Weise sie dem Loopback zu, nicht dem Tunnel
Die Adresse auf eine Loopback-Schnittstelle zu legen entkoppelt sie von der Lebensdauer jedes Tunnel-Geräts, sodass ein Wiederverbinden oder ein Neuladen der Konfiguration sie nicht entfernt. Die Adresse existiert, solange der Host existiert.
Eine Adresse auf lo ist kein Filter. Der Dienst muss weiterhin darauf lauschen, und die Host-Firewall wertet weiterhin den realen eingehenden Pfad aus, der auf der Tunnel-Schnittstelle ankommt. Wer annimmt, Loopback bedeute nur lokal, blockiert am Ende entweder legitime Clients oder legt etwas offen, das er nicht beabsichtigt hatte.
Mach die Zuweisung über die Netzwerkkonfiguration des Hosts dauerhaft, statt sie aus einem Hook heraus erneut hinzuzufügen. Ein Setup-Hook feuert auf einem Knoten nicht, auf dem kein Tunnel hochkam, und die Dienstadresse sollte nicht von Tunnel-Aktivität abhängen. Lege die Adresse in die Schnittstellenkonfiguration, die deine Distribution verwaltet, starte dann einmal neu und prüfe sie. Ein Neustart ist der einzige Test, der eine spätere Konfigurationsänderung übersteht.
ip address show dev lo | grep 10.250.0.1
ip address add 10.250.0.1/32 dev loSchiebe eine Route und meine ein Ziel
Der Client braucht eine Host-Route für die Adresse, angeboten von dem Server, mit dem er sich verbindet. Weil jeder Server dasselbe Ziel anbietet, ändert sich das Profil nicht, wenn der Client wechselt.
Prüfe, was der Client installiert hat, bevor du dem Dienst die Schuld gibst.
ip route get 10.250.0.1Gib der Adresse für einen HTTP-Dienst einen Namen und ein Zertifikat für diesen Namen. Die gemeinsame IP ist keine Identität, und sie ersetzt nicht die TLS-Prüfung, noch rechtfertigt sie es, einen privaten Schlüssel auf jeden Knoten zu kopieren. Ein Name, der auf die gemeinsame Adresse auflöst, hält die Zertifikatsgeschichte gewöhnlich und lässt dir eine Identität pro Knoten, wenn du eine brauchst.
Was die gemeinsame Adresse nicht kann
Sie bietet kein Failover. Stirbt der gewählte Knoten, stirbt die Adresse mit ihm, und der Client muss sich woanders neu verbinden.
Sie migriert keine laufende TCP-Sitzung, weil eine neue Verbindung auf einem anderen Host endet, der den alten nicht kennt.
Sie wählt keinen gesunden Knoten, verteilt keine Last und synchronisiert keine Daten zwischen Knoten. Jedes davon ist ein eigener Mechanismus mit eigenen Fehlermodi, und so zu tun, als decke der Adressierungstrick sie ab, ist der Weg, auf dem ein einfaches Design einen unverdienten Ruf für Ausfallsicherheit erwirbt. Wenn zwei Tunnel gleichzeitig aktiv sind, wird die Bedeutung des Ziels mehrdeutig, also halte die Annahme eines einzigen aktiven Tunnels ausdrücklich fest.
Halte die Dienstidentität beim Namen
Schreib auf, was die Adresse bedeutet: Sie erreicht den Dienst auf dem Knoten, mit dem der Client gerade verbunden ist. Dieser eine Satz verhindert den größten Teil des Missverständnisses, das dieses Muster anzieht.
Dokumentiere dann die Teile zusammen: die Adresse, die Schnittstelle, auf der sie lebt, die Route, die der Server schiebt, und den Namen und das Zertifikat, die der Dienst vorzeigt. Vier kleine Fakten, die ein künftiger Leser prüfen kann, in der Reihenfolge, in der er sie prüfen wird.
Ist die Anforderung ein stabiles Ziel für einen knotenlokalen Dienst, passt das Muster und kostet fast nichts.
Ist die Anforderung Verfügbarkeit, geh eine Ebene höher: ein Load Balancer, ein Dienstname mit Health Checks oder ein Orchestrierungssystem, das bereits weiß, wie man einen Knoten ersetzt.
Das früh zu entscheiden hält die gemeinsame Adresse zu dem, was sie ist, einem bequemen Etikett, statt einer Komponente, von der still erwartet wird, dass sie Arbeit erledigt, für die sie nie entworfen wurde.