
🌐 Auch auf: English · Français · Español
Ein Blog und zwei Nextcloud-Server für Vereine aus der Gegend: Auf keinem davon liegt etwas, das einen gezielten Angriff lohnt – und genau deshalb werden sie angegriffen. Nicht von jemandem, der meine Daten will, sondern von Scannern, die jede IP-Adresse im Internet durchprobieren, jede Stunde, immer mit denselben paar Tricks. Die meisten geben an der ersten verschlossenen Tür auf. Die Frage ist, was mit denen passiert, die es nicht tun.
Die Antwort hat einen Namen: Defense in Depth, also gestaffelte Verteidigung. Keine einzelne Maßnahme muss perfekt sein, weil hinter jeder Schicht noch eine weitere kommt. Dieser Beitrag sammelt alle Schichten, die meine Server inzwischen haben – und macht dann etwas leicht Unbequemes: Ich habe meinen KI-Co-Admin (Claude) gebeten, alles zu lesen, was ich über diesen Aufbau veröffentlicht habe, und wie ein Angreifer zu denken. Wo würde er anfangen?
🧅 Warum eine Mauer nicht reicht
Jede Sicherheitsmaßnahme kann versagen. Eine Firewall-Regel bekommt einen Tippfehler. Ein Dienst, der Angreifer sperren soll, bleibt still stehen – meiner tat das zwei Tage lang, und niemand hat es gemerkt. Ein Plugin bringt am Dienstag eine Lücke mit, und der Fix kommt am Donnerstag. Wenn so etwas das Einzige zwischen dem Internet und deinen Daten ist, bist du nur einen schlechten Tag von einem Einbruch entfernt.
Defense in Depth dreht das um: Geh davon aus, dass jede Schicht irgendwann versagen wird, und sorg dafür, dass die nächste trotzdem hält. Dazu kommt ein zweiter, weniger offensichtlicher Vorteil – ein Angreifer, der eine Schicht überwunden hat, muss Lärm machen, um durch die nächste zu kommen, und Lärm kann man erkennen.
🛡️ Die Schichten
1. Die Netzgrenze
Die Firewall (nftables) verwirft alles, was nicht ausdrücklich erlaubt ist: Webverkehr auf 80/443 und SSH auf einem Port abseits des Standards. Monitoring, Datenbanken und interne Ports antworten nur auf localhost oder innerhalb des Clusters. SSH nimmt neue Verbindungen außerdem nur aus IP-Bereichen meines eigenen Landes an – das hält niemanden auf, der es ernst meint (ein gemieteter Server im richtigen Land ist billig), aber es entfernt rund 98 % des Grundrauschens, sodass die übrigen Versuche tatsächlich auffallen.
2. SSH
Nur Schlüssel, keine Passwörter – festgeschrieben in einem Konfigurationsschnipsel, der vor allem einsortiert wird, was ein Cloud-Image mitbringt, nachdem ich ein Anbieter-Image erwischt hatte, das Passwort-Logins still wieder eingeschaltet hat. Obendrein läuft sshd in einer systemd-Sandbox, die jede Sitzung erbt: keine Kernel-Module nachladen, keine Kernel-Parameter ändern. Root kann das mit systemd-run trotzdem bewusst tun, es ist also eine Hürde und keine Mauer – aber die klassische Abfolge „einloggen, Rootkit-Modul laden“ scheitert, und das Laden von Modulen landet so oder so im Audit-Log.
3. Automatisches Sperren
fail2ban liest das SSH-Log und das Zugriffslog des Webservers und sperrt Adressen, die Passwörter raten, nach bekannten Dateien suchen oder auf die Login-Seiten einhämmern. Wiederholungstäter werden deutlich länger gesperrt. Die Sperren gehen direkt in die Firewall, und ein Wachhund startet fail2ban neu, falls es noch einmal ausfällt.
4. Der Webserver
Nur TLS, mit strengen Sicherheits-Headern. Die Login-URLs sind in der Rate begrenzt. Pfade, die Angreifer lieben – Konfigurationsdateien, .env, .git, WordPress‘ XML-RPC – werden blockiert, bevor sie überhaupt PHP erreichen, und WordPress verrät seine Benutzernamen nicht mehr über die REST-API.
5. Container
Die Anwendungen laufen in Kubernetes (K3s). NetworkPolicies legen fest, welcher Pod mit welchem sprechen darf – ein übernommenes WordPress kann sich nicht einfach mit allem verbinden, was es will. Eine Admission-Policy lässt nur Container-Images aus freigegebenen Registries zu, Service-Account-Tokens werden nicht eingebunden, wo sie niemand braucht, und SELinux erzwingt, dass ein Container nur in die Verzeichnisse schreibt, die ausdrücklich für ihn gekennzeichnet sind.
6. Die Anwendungen selbst
WordPress aktualisiert Core, Plugins, Themes und Übersetzungen jede Nacht – vorher mit einer Datenbanksicherung und danach mit einer Prüfung, ob die Seite noch antwortet. Ungenutzte Plugins und Themes werden gelöscht, nicht nur deaktiviert, denn deaktivierter Code ist immer noch erreichbar. Nextcloud erzwingt eine Passwortrichtlinie und bremst Brute-Force-Versuche aus; Admin-Konten nutzen Zwei-Faktor-Authentifizierung.
7. Erkennung
Vorbeugung versagt irgendwann; Erkennung ist, wie man es merkt. AIDE prüft jede Nacht, ob sich Systemdateien geändert haben, rkhunter sucht nach Rootkits, ClamAV scannt hochgeladene Dateien, auditd beobachtet Benutzerdateien, sudo und die Geheimnisse des Clusters, und ein Wachhund (Monit) schickt mir eine Mail, wenn ein Dienst, die Firewall, ein Zertifikat oder die Sicherung nicht im Sollzustand ist. Solange alles in Ordnung ist, schweigen sie alle – jede Mail bedeutet also etwas.
8. Wiederherstellung
Die letzte Schicht ist die, die man hoffentlich nie braucht. Sicherungen werden von einem Rechner bei mir zu Hause abgeholt, nicht von den Servern geschickt – ein übernommener Server hat keine Zugangsdaten, um an sie heranzukommen – und mit 30 Tagen Historie aufbewahrt, sodass sich selbst etwas, das eine Woche lang unbemerkt blieb, zurückdrehen lässt.
9. Der Prozess
Alles oben wird von Ansible aus einem Git-Repository eingerichtet – damit gehört das Repository selbst zur Angriffsfläche. Geheimnisse liegen nur in einem verschlüsselten Vault, der nie in Git landet. Jeder Commit läuft durch einen Linter und einen Secret-Scanner. Versionen sind festgeschrieben, Updates kommen als geprüfte Pull Requests, und jede Änderung läuft als Probelauf gegen die echten Server, bevor sie wirklich ausgeführt wird.
🕵️ Denken wie ein Angreifer
Jetzt der unbequeme Teil. Mein Ansible-Code ist öffentlich, und dasselbe gilt für mehrere Beiträge darüber, wie diese Server aufgebaut sind. Also habe ich Claude gefragt: Du kennst das alles – wo würdest du anfangen?
Die Antwort war nicht „die Firewall“ oder „SSH“. Sie war viel banaler:
- Die Anwendungen. Ein Plugin oder eine App mit einer frischen Lücke ist mit Abstand der wahrscheinlichste Weg hinein. Nächtliche Updates verkleinern dieses Zeitfenster; schließen können sie es nicht.
- Die Menschen. Einer der Nextcloud-Server hat über hundert Konten. Ein wiederverwendetes Passwort oder eine überzeugende Phishing-Mail schlägt jede technische Schicht oben – ganz ohne Exploit.
- Die Lieferkette. Wer mein Git-Konto oder meinen Admin-Rechner kontrolliert, muss die Server gar nicht angreifen: Ich würde seinen Code selbst ausrollen.
- Vergessene Dinge. Konten, die niemand mehr nutzt, geteilte Links ohne Ablaufdatum, alte Einstellungen, die noch unbemerkt in einer Datenbank schlummern.
Die Lehre: Sobald die technischen Grundlagen stehen, wandern die Schwachstellen dorthin, wo Menschen und Abläufe sind.
🔑 Öffentlicher Aufbau, geheime Schlüssel
Bleibt die naheliegende Frage: Ist es nicht leichtsinnig, das alles zu veröffentlichen? Kryptografen haben das 1883 beantwortet. Das Kerckhoffs-Prinzip besagt, dass ein System sicher bleiben muss, auch wenn alles darüber öffentlich ist – außer dem Schlüssel. So funktioniert jede Verschlüsselung, die du heute nutzt: Die Algorithmen sind veröffentlicht, untersucht und von Fachleuten auf der ganzen Welt angegriffen worden, und sie bleiben sicher, weil der Schlüssel geheim bleibt.
Meine Server folgen derselben Idee. Zu wissen, dass SSH nur Schlüssel annimmt, auf welchem Port, aus welchem Land, hinter welchen Firewall-Regeln, bringt ohne den privaten Schlüssel niemanden auch nur einen Schritt weiter. Zu wissen, dass die Konfiguration in einem Ansible-Vault liegt, hilft ohne das Vault-Passwort nicht. Zu wissen, dass Admins Zwei-Faktor-Authentifizierung nutzen, hilft ohne das Handy nicht. Der Aufbau ist öffentlich; die Schlüssel verlassen nie die Orte, an die sie gehören.
Das Gegenteil – Sicherheit, die nur funktioniert, solange niemand weiß, wie sie funktioniert – ist zerbrechlich: ein durchgesickertes Dokument, ein neugieriger Insider, und sie ist weg. Details zu verstecken kann einen Angreifer trotzdem Zeit kosten, aber nur als zusätzliche Schicht, nie als Fundament. Das Einzige, was nicht veröffentlicht werden darf, ist die Liste der Lücken, die noch nicht geschlossen sind.
Und noch etwas, für alle, die das hier mit falschen Absichten lesen: Nicht jede Schicht ist in diesem Beitrag beschrieben. Einige der Schutzmaßnahmen und Stolperdrähte auf diesen Servern sind bewusst weggelassen – du wirst sie erst kennenlernen, wenn du sie auslöst.
🔧 Was ich nach diesem Gespräch geändert habe
- Zwei-Faktor-Authentifizierung für jedes Admin-Konto auf beiden Nextcloud-Servern und auf dem Blog – mit ausgedruckten Backup-Codes und dem Wissen, dass ich es per SSH jederzeit wieder abschalten kann, falls ein Handy verloren geht.
- Eine Passwortrichtlinie auf beiden Nextcloud-Servern: mindestens 12 Zeichen, keine sehr verbreiteten Passwörter und keine Passwörter, die in bekannten Datenlecks auftauchen. Die letzte Prüfung nutzt k-Anonymität: Nur die ersten fünf Zeichen des Passwort-Hashes verlassen den Server.
- Inaktive Konten deaktiviert: alle, die sich über ein Jahr nicht angemeldet hatten, dazu Konten, die sich nie angemeldet haben – insgesamt dreißig, darunter ein ungenutzter zweiter Administrator. Ihre Daten bleiben erhalten; die Konten lassen sich in Sekunden wieder einschalten.
- Öffentliche Upload-Links laufen ab, statt für immer offen zu bleiben.
- Drei Stellen, an denen ein Passwort in einem Log hätte landen können – nur bei einem Diff oder einer Fehlermeldung, aber immerhin – sind jetzt ausgeblendet.
Und ein ehrlicher Fehler. Das Einschalten der Passwortrichtlinie auf der größeren Nextcloud hat eine Einstellung vom alten Server geweckt: Passwörter laufen nach 300 Tagen ab. Ein paar Minuten lang galt jedes ältere Passwort als abgelaufen – meins eingeschlossen. Die Einstellung ist jetzt ausdrücklich festgeschrieben, und ich habe gelernt, die vorhandene Konfiguration einer App zu lesen, bevor ich sie einschalte.
🤝 Die organisatorische Schicht
Nicht alles lässt sich mit einer Konfigurationsdatei lösen:
- Die Nutzer informieren. Ein kurzer Hinweis zu Passwort-Managern, Zwei-Faktor-Authentifizierung und Phishing („Nextcloud fragt nie per E-Mail nach deinem Passwort“) schützt mehr als jede Servereinstellung.
- Für den eigenen Ausfall planen. Wer kann einspringen, wenn ich nicht kann? Wo liegen die Wiederherstellungscodes und das Vault-Passwort – auf Papier, in einem verschlossenen Umschlag, nicht nur in meinem Kopf?
- Regelmäßig hinschauen. Eine kurze monatliche Prüfung: neue Admin-Konten, offene Freigabelinks, alles Auffällige in den Audit- und Sperr-Logs.
🎯 Fazit
Keine dieser Schichten ist für sich allein beeindruckend, und für jede gibt es einen Weg drumherum. Zusammen machen sie aus „ein Fehler, und es ist vorbei“ ein „mehrere Fehler, und jeder davon fällt auf“. Das ist die ganze Idee hinter Defense in Depth – und der Blick des Angreifers hat mir gezeigt, dass die nächsten Schichten keine weiteren Firewall-Regeln sind, sondern Konten, Gewohnheiten und die Rechner, von denen aus ich administriere.





