Das offene Mesh zumachen: VPN-ACLs auf Least-Privilege härten
Das offene Mesh zumachen: VPN-ACLs auf Least-Privilege härten
Inhaltsverzeichnis
Ausgangslage: jeder darf zu jedem
Ein privates VPN-Mesh startet fast immer mit einer freizügigen Regel: jeder Knoten darf jeden anderen erreichen, auf jedem Port. Für die Erstinbetriebnahme ist das praktisch — man will schließlich, dass die Dinge erstmal funktionieren. Aber diese Voreinstellung verschiebt eine Grenze, die man leicht übersieht: Das Mesh authentifiziert nur, wer dabei ist, nicht, worauf jeder zugreifen darf.
Die Verschlüsselung schützt gegen außen. Innen ist es ein flaches, offenes Netz. Und das ist genau der Moment, in dem ein einzelner kompromittierter Knoten teuer wird: ein Container-Ausbruch, ein verwundbarer Dienst, eine gestohlene Sitzung — und der Angreifer steht plötzlich neben dem Mailserver, dem Virtualisierungs-Host, der Datenbank. Alles gegenseitig erreichbar. Die Mitgliedschaft im Mesh ist der einzige Zaun; ist man drin, gibt es keinen mehr.
Erst zählen, dann zumachen
Die größte Versuchung ist, die Regeln aus dem Kopf zu schreiben: „Der Cluster redet vermutlich mit dem Monitoring, der Automatisierungs-Host mit den Nodes …". Genau so bricht man Dinge — leise. Ein vergessener Flow (ein nächtlicher Backup-Zug, ein Metrik-Scrape, ein selten genutzter Verwaltungspfad) scheitert klanglos, und man merkt es Tage später.
Deshalb die goldene Regel: erst alle Ist-Flows enumerieren, dann Regeln schreiben. Jeden Knoten und seine Rolle auflisten — und dann beobachten, was tatsächlich mit was spricht, statt es anzunehmen. Die lehrreiche Überraschung bei mir: Der zentrale Metrik-Sammler zog seine Daten ausschließlich von lokalen Zielen. Eine ganze Klasse vermuteter netzübergreifender Verbindungen existierte schlicht nicht. Man kann nicht zumachen, was man nicht gemessen hat.
Das Modell: Menschen breit, Maschinen schmal
Der Denkrahmen, der den Explosionsradius klein hält, ohne jeden einzelnen Port zu mikromanagen: Knoten nach Rolle gruppieren — und die beiden Gruppen bewusst ungleich behandeln.
Operator-Geräte (die Laptops und Telefone der Menschen, die das System betreiben) sind vertrauenswürdige Clients. Sie bekommen breiten Zugriff auf die Infrastruktur. Sie einzuschränken bringt wenig Sicherheit — sie sind ohnehin die Betreiber — und riskiert vor allem, den eigenen Zugang zu zerschießen.
Server- und Infrastruktur-Knoten sind die andere Seite. Hier sitzt das Risiko: Sie führen Workloads aus, sind internet-nah, sind das, was kompromittiert wird. Also bekommen sie nur die Flows, die sie wirklich brauchen. Der einzige ausgehende Bedarf eines Cluster-Nodes ist vielleicht der Monitoring-Endpunkt. Sonst nichts.
Die Regeln: von „alles" zu „nur diese Zeilen"
Sobald man die Allow-all-Regel entfernt, gilt implizit Default-Deny: Was nicht ausdrücklich erlaubt ist, wird verworfen. Die Policy wird damit zu einer kurzen, lesbaren Liste bekannter Flows. Schematisch (die konkreten Namen und Ports sind hier nur Platzhalter):
{
"groups": { "group:admins": ["operator@"] },
"acls": [
// Operator-Geräte: voller Zugriff auf die Infrastruktur
{ "action": "accept",
"src": ["operator@"],
"dst": ["tag:server:*", "tag:cluster:*"] },
// Cluster-Knoten: NUR der Monitoring-Endpunkt am Server
{ "action": "accept",
"src": ["tag:cluster"],
"dst": ["tag:server:<monitoring-port>"] },
// Automatisierungs-Host: NUR die Verwaltungs-Ports der Knoten
{ "action": "accept",
"src": ["tag:automation"],
"dst": ["tag:cluster:22,<api-port>"] }
]
}
Alles, was nicht in diesen Zeilen steht, ist gesperrt. Diese Umkehr — von „alles erlaubt" zu „nur diese wenigen Zeilen" — ist die Härtung. Und weil die Liste kurz und benannt ist, kann man sie lesen wie eine Landkarte der Absichten.
Zwei Fallen, die man erst im Feuer merkt
1. Strenge Policy-Syntax kann den ganzen Dienst kippen. Der Koordinations-Server liest die Policy beim Start ein. Eine einzige falsch formatierte Identität — ein fehlendes Zeichen, ein Tippfehler im Referenzformat — und die Policy lädt nicht mehr. Der Dienst kommt nicht sauber hoch. Im schlimmsten Fall steht die gesamte VPN-Steuerung. Aus einer „kleinen Regeländerung" wird ein Ausfall.
2. Der Health-Status täuscht. Nach einem Neustart springt die Gesundheitsanzeige eines Dienstes oft erst nach seinem Prüf-Intervall auf „gesund" — etwa nach 30 Sekunden. Wartet das Skript nur 20 Sekunden und sieht „nicht gesund", zieht es den Fehlschluss „kaputt" und macht eine völlig valide Policy wieder rückgängig. Genau das ist mir passiert: ein Fehlalarm-Revert. Die Lehre: nicht auf den periodischen Health-Status des Orchestrators warten, sondern das eigene Bereitschafts-Kommando des Dienstes fragen — das antwortet sofort.
Der eigentliche Test ist der negative
Die meisten testen, dass die erlaubten Flows noch funktionieren. Die entscheidende, oft übersprungene Hälfte: prüfen, dass die gesperrten Flows wirklich gesperrt sind. Eine ACL, die nichts verbietet, ist Dekoration.
Das Schöne: Man braucht dafür kein Werkzeug. Ein kurzer TCP-Klopftest genügt, direkt in der Shell:
probe(){ timeout 4 bash -c "echo > /dev/tcp/$1/$2" 2>/dev/null \
&& echo OFFEN || echo BLOCKIERT; }
probe <server> <monitoring-port> # erwartet: OFFEN
probe <server> <mail-port> # erwartet: BLOCKIERT
probe <hypervisor> <admin-port> # erwartet: BLOCKIERT
Man fährt die positive Menge (muss offen sein) und die negative Menge (muss blockiert sein) — und zwar vom jeweiligen Quell-Knoten aus, denn genau dessen Perspektive setzt die ACL durch. Erst wenn ein Cluster-Knoten den Monitoring-Endpunkt erreicht und den Mail-Port nicht erreicht, weiß man beides: die Funktion ist erhalten, und die seitliche Bewegung ist eingedämmt.
Sich nicht selbst aussperren
Der Albtraum bei Netz-ACLs ist, sich genau von dem Ding auszusperren, das man zum Reparieren braucht. Zwei Vorkehrungen machen die Änderung ungefährlich.
Ein Zugang außerhalb des VPN. Die Policy-Datei muss über einen Weg editierbar bleiben, der nicht vom VPN selbst abhängt — etwa der normale, direkte Administrationszugang der Maschine. Dann ist keine Regel je tödlich: Man kommt immer an die Datei und kann zurückrollen.
Ein Backup und ein skriptierter Rückweg. Die vorherige Policy als datierte Sicherung behalten und den Revert automatisieren. „Anwenden, verifizieren, bei Fehler zurückrollen" verwandelt eine angsteinflößende Änderung in eine wiederholbare Routine.
Was man mitnimmt
- Mitgliedschaft ≠ Erlaubnis. Ein VPN ohne ACLs ist ein flaches Netz mit Verschlüsselung außen rum.
- Erst messen, dann härten. Geratene Flows brechen leise — enumeriere, statt zu vermuten.
- Menschen breit, Maschinen schmal. Der Gewinn liegt darin, Server-zu-Server-Sprünge zu verhindern.
- Negativ testen. Eine Regel, die nichts verbietet, ist Deko. Prüfe, dass Gesperrtes wirklich sperrt.
- Immer ein Rückweg. Zugang außerhalb des VPN plus Auto-Revert nimmt der Änderung den Schrecken.
Ein offenes Mesh fühlt sich sicher an, weil es verschlüsselt ist — und ist doch nur so stark wie sein schwächster Knoten. Es zuzumachen war keine große Geste, sondern eine kurze Liste bewusster Zeilen: zähle, was wirklich fließt, erlaube genau das, beweise das Gegenteil durch das, was jetzt scheitert — und lass dir einen Weg zurück offen.