Own Your Stack · Teil 2
Die interne Zone, die öffentlich war

In Teil 1 habe ich sie angekündigt: die Geschichte vom Sicherheitsloch, das wir uns selbst gebaut haben. Hier ist sie — vollständig, inklusive des Teils, der wehtut.
Der Plan war gut
Die Architektur meines Setups trennt sauber zwischen öffentlich und privat: Ein paar Dienste müssen vom offenen Internet erreichbar sein (der Passwortmanager, das Login). Alles andere — Admin-Oberflächen, das Benutzerverzeichnis, das interne Dashboard — soll nur über das WireGuard-VPN erreichbar sein.
Dafür gab es eine «interne Zone»: Eine Wildcard-DNS-Adresse zeigt auf die private VPN-Adresse des Servers — von aussen eine Sackgasse. Und als doppelte Absicherung prüft der Reverse Proxy bei jeder Anfrage die Absender-IP: Was nicht aus dem VPN-Adressbereich kommt, wird abgewiesen.
Gürtel und Hosenträger. Was soll da schiefgehen?
Der Test, der alles kippte
Zu unserem Prozess gehört eine Regel, die sich an diesem Tag bezahlt gemacht hat: Jede Sperre wird von aussen gegen sich selbst getestet. Nicht «schauen, ob es von innen funktioniert», sondern aktiv versuchen, die eigene Mauer zu durchbrechen — von einem Rechner ausserhalb des VPN, gegen die öffentliche IP des Servers.
Das Ergebnis: Die interne Zone antwortete. Öffentlich. Jedem.
Die Ursache: Docker meint es gut
Der IP-Filter im Proxy war korrekt konfiguriert — und trotzdem wirkungslos. Der Grund ist ein Verhalten, das Docker offiziell dokumentiert, das man aber kennen muss: Läuft ein Container mit veröffentlichten Ports hinter Dockers Netzwerk-Bridge, ersetzt Docker die Absender-Adresse der Anfrage durch die interne Bridge-Adresse (Source NAT).
Der Proxy sah also nie die echte Absender-IP. Er sah bei jeder Anfrage — ob aus dem VPN oder aus dem offenen Internet — dieselbe interne Docker-Adresse. Und die stand auf der Erlaubt-Liste. Der Filter hat nicht versagt; er hat schlicht auf ein Signal geprüft, das es an dieser Stelle nicht mehr gab.
Der Fix
Zwei Änderungen, beide klein, beide grundsätzlich:
- Der Proxy läuft jetzt im Host-Netzwerk statt hinter der Bridge — er sieht wieder echte Absender-Adressen.
- Die Backends veröffentlichen ihre Ports nur noch lokal (auf die Loopback-Adresse gebunden) — sie sind gar nicht mehr direkt vom Netz erreichbar, sondern ausschliesslich über den Proxy.
Danach: derselbe Angriffstest von aussen, diesmal mit dem erwarteten Ergebnis — Verbindung abgewiesen. Erst jetzt wurde das Ganze im Entscheidungs-Log als erledigt markiert, mit einem Nachtrag, der die Lücke dokumentiert. Auch das gehört zu ehrlicher Infrastruktur: Der Fehler steht im selben Dokument wie die Entscheidung.
Die eigentliche Lehre
Die technische Lektion — «IP-Filter hinter Docker-NAT sind wertlos» — kann man googeln. Die Prozess-Lektion ist wertvoller:
Eine Sicherheitsmassnahme, die nie von aussen getestet wurde, ist keine Sicherheitsmassnahme. Sie ist eine Vermutung.
Ein KI-Agent baut so eine interne Zone in Minuten. Genau deshalb braucht es die Gegengewichte: dokumentierte Annahmen, und einen Test, der die Annahme angreift statt sie zu bestätigen. Tempo ist nur dann ein Vorteil, wenn die Prüfschleife mithält — das gilt für mein Heim-Setup genauso wie für jedes Unternehmen, das gerade «schnell mal mit KI» seine Infrastruktur umbaut.
Im nächsten Teil wird es grundsätzlicher: warum auf meinem Notebook Arch Linux läuft — und nicht macOS oder Windows.
Fragen, Einwände, eigene Kriegsgeschichten? Schreib mir — ich antworte selbst.