· DevOps · 8 Min. Lesezeit
Admin-Oberflächen schützen mit CrowdSec und einer dynamischen IP-Freigabe
CrowdSec liest die Traefik-Logs und sperrt auffällige Adressen, eine IP-Freigabe nimmt Admin-Bereiche ganz aus der Schusslinie. Der Aufbau Schritt für Schritt, mit fünf Stolpersteinen, darunter der wichtigste: eine Engine, die läuft, meldet und dabei nichts liest.

Jede öffentlich erreichbare IP wird permanent gescannt, nach Login-Seiten, bekannten Pfaden, offenen Türen. Das trifft den kleinen Server genauso wie den großen.
Dagegen helfen zwei Bausteine, die unterschiedlich ansetzen. CrowdSec fängt das Grundrauschen ab, indem es Muster im Zugriffs-Log erkennt und Adressen sperrt. Eine IP-Freigabe nimmt die Admin-Flächen ganz aus der Schusslinie, indem sie nur die eigene Herkunft durchlässt.
Wichtig ist das Verständnis der Aufgabenteilung, denn daran scheitern die meisten Aufbauten. CrowdSec entscheidet nur. Durchgesetzt wird die Entscheidung von einer separaten Komponente, dem Bouncer. Die CrowdSec-Doku nennt diese Komponenten inzwischen Remediation Components und beschreibt, dass sie sich die aktiven Entscheidungen von der Local API abholen und dafür einen eigenen API-Token brauchen. Wer nur die Engine aufsetzt, hat ein Erkennungssystem ohne Wirkung.
Voraussetzungen prüfen
Der Reverse Proxy schreibt ein Zugriffs-Log. Ohne Log gibt es nichts zu lernen. Bei Traefik ist das Access-Log nicht in jeder Konfiguration aktiv.
Die Engine kommt an dieses Log heran. Läuft CrowdSec im Container, muss das Verzeichnis hineingereicht werden, sinnvollerweise nur lesend:
services:
crowdsec:
volumes:
- ../traefik/logs:/var/log/traefik:roSchritt 1: Die Acquisition einrichten
Die Datei acquis.yaml legt fest, was gelesen wird. Die Doku zur dateibasierten Acquisition beschreibt die Schlüssel: filenames nimmt eine Liste von Pfaden und beherrscht Globbing, source steht auf file, und unter labels legt type fest, mit welchem Parser gearbeitet wird.
filenames:
- /var/log/traefik/access.log
labels:
type: traefikSchritt 2: Prüfen, dass tatsächlich gelesen wird
Das ist der wichtigste Prüfschritt des ganzen Aufbaus, und er wird fast immer übersprungen.
cscli metricsSie suchen die Acquisition-Zeile für Ihre Quelle. Steht dort dauerhaft nichts oder null, liest die Engine nichts, ganz gleich wie gesund der Container aussieht. Warum das so leicht passiert, steht unter Stolperstein 1.
Schritt 3: Die Collections auf die Wirklichkeit bringen
Collections bestimmen, wonach gesucht wird. Voreingestellt ist oft mehr, als Sie betreiben.
cscli collections listWas Sie nicht betreiben, fliegt raus. Eine Collection für eine Anwendung, die es auf dem Server gar nicht gibt, erzeugt nur Rauschen und verschleiert die Sicht auf das, was zählt. Bei einem reinen Reverse-Proxy-Aufbau bleiben die Traefik-Collection und generische Web-Angriffsmuster.
Schritt 4: Den Bouncer anmelden
Der Bouncer braucht einen eigenen Schlüssel, den die Engine ausstellt:
cscli bouncers add traefik-bouncerDer ausgegebene Schlüssel wandert in die Bouncer-Konfiguration. Notieren Sie ihn beim Anlegen, ein zweites Mal wird er nicht angezeigt.
Schritt 5: Die Middleware unabhängig vom Container definieren
Hier entscheidet sich, ob der Aufbau stabil ist. Definieren Sie die Bouncer-Middleware im Datei-Provider, nicht als Label an einem Container:
http:
middlewares:
crowdsec-bouncer:
plugin:
bouncer:
enabled: true
crowdsecLapiHost: crowdsec:8080
crowdsecLapiScheme: http
crowdsecLapiKey: "<schluessel aus schritt 4>"Die Router referenzieren sie dann mit dem Provider-Suffix:
labels:
- "traefik.http.routers.meine-site.middlewares=crowdsec-bouncer@file"Warum das keine Geschmacksfrage ist, steht unter Stolperstein 2.
Schritt 6: Die Durchsetzung end-to-end testen
Ein Bouncer, dessen Wirkung nie geprüft wurde, ist eine Annahme. Der Test dauert eine Minute. Sperren Sie eine Adresse, von der aus Sie testen können, laut Doku zu cscli decisions add:
cscli decisions add --ip 203.0.113.10 --duration 5m --type banDann von dieser Adresse aus abfragen:
curl -s -o /dev/null -w '%{http_code}\n' https://lab.rz.jabi-it.de/Erwartet wird 403. Danach zurücknehmen:
cscli decisions delete --ip 203.0.113.10Und erneut prüfen, jetzt wird 200 erwartet. Erst wenn beide Richtungen stimmen, wirkt die Kette.
Die fünf Stolpersteine
1. Die Engine läuft, meldet sich gesund und liest nichts
Symptom: CrowdSec läuft seit Wochen ohne Fehler im Log. Es gibt aber nie eine Entscheidung, nie eine Sperre, nie einen Alarm. Der Server wird trotzdem nachweislich gescannt.
Ursache: Der Pfad in der Acquisition zeigt ins Leere. Ein Tippfehler, ein umbenanntes Verzeichnis, ein Mount, der nicht mehr existiert. Die Engine startet trotzdem und beschwert sich nicht laut. Die Doku beschreibt zudem, dass ein Glob, der in einem vorhandenen Verzeichnis keine Datei trifft, dieses Verzeichnis standardmäßig gar nicht erst überwacht, was sich nur mit force_inotify: true ändern lässt.
Prüfung: Zuerst, ob die Datei aus Sicht des Containers überhaupt existiert:
docker compose exec crowdsec ls -l /var/log/traefik/access.logDann, ob sie gelesen wird:
cscli metricsLösung: Pfad korrigieren und danach erneut messen. Wiederholen Sie diese Messung nach jeder Änderung an Mounts oder Verzeichnisnamen, nicht nur bei der Einrichtung. Der Ausfall ist von außen nicht sichtbar: Die Oberfläche zeigt eine laufende Engine, die Alarmliste bleibt leer, und beides sieht aus wie ein ruhiger Betrieb.
2. Die Middleware verschwindet mit einem fremden Container
Symptom: Ein völlig unbeteiligter Dienst wird abgeschaltet, und danach antworten mehrere andere Seiten mit 404. Diese Seiten haben mit dem abgeschalteten Dienst nichts zu tun.
Ursache: Die Bouncer-Middleware war per Docker-Label an genau diesem Container definiert. Traefik kennt Middlewares nur, solange ihr Provider sie liefert. Verschwindet der Container, verschwindet die Middleware. Jeder Router, der sie referenziert, ist damit unvollständig und fällt aus.
Prüfung: Nachsehen, woher die Middleware kommt und ob sie noch existiert:
curl -s http://localhost:8080/api/http/middlewares | jq -r '.[].name'Lösung: Gemeinsam genutzte Middlewares gehören in den Datei-Provider, wie in Schritt 5 gezeigt, und werden mit @file referenziert. Eine Middleware, die mehrere Router brauchen, darf nicht am Lebenszyklus eines einzelnen Containers hängen.
3. Die Collections passen nicht zum Server
Symptom: Viele Treffer, wenig Aussagekraft. Oder umgekehrt: Angriffe auf die tatsächlich betriebene Software werden nicht erkannt.
Ursache: Die installierten Collections spiegeln einen früheren Stand. Nach dem Abschalten einer Anwendung bleibt ihre Collection zurück, nach dem Hinzufügen einer neuen fehlt die passende.
Prüfung:
cscli collections listLösung: Die Liste gegen die tatsächlich betriebenen Dienste halten und angleichen. Das gehört auf dieselbe Liste wie das Abschalten des Dienstes selbst, sonst wird es vergessen.
4. Die IP-Freigabe sieht die falsche Adresse
Symptom: Die IP-Freigabe sperrt Sie selbst aus, oder sie lässt jeden durch, obwohl der Bereich eingegrenzt ist.
Ursache: Steht noch ein Proxy oder CDN davor, ist die Adresse, die der Proxy sieht, nicht die des Besuchers. Die Traefik-Doku zur IPAllowList beschreibt zudem eine Reihenfolge, die leicht übersehen wird: Die Freigabe greift, bevor tatsächlich weitergeleitet wird, während der vorherige Hop erst in den späten Phasen des Weiterleitens an X-Forwarded-For angehängt wird. Wer sich auf diesen Header verlässt, muss wissen, was zum Prüfzeitpunkt darin steht.
Prüfung: Sich die Adresse zeigen lassen, die tatsächlich ankommt, indem Sie das Access-Log während eines eigenen Zugriffs beobachten.
Lösung: Für Aufbauten hinter einem weiteren Proxy die ipStrategy bewusst setzen, entweder über depth mit der Anzahl vertrauenswürdiger Hops oder über excludedIPs. Beides raten hilft nicht, es muss zur tatsächlichen Kette passen.
5. Das Missverständnis mit der Quell-IP unter rootless Docker
Symptom: Die Sorge, dass unter rootless Docker alle Zugriffe mit einer internen Adresse im Log landen und IP-basierte Abwehr deshalb wirkungslos sei.
Ursache: Ein halb richtiges Wissen. Es stimmt, dass beim rootless-Betrieb Adressen umgeschrieben werden können. Betroffen ist davon aber der Zugriff über den Host-Loopback, der als interne Adresse erscheint. Echte externe Besucher behalten ihre öffentliche Adresse im Access-Log.
Prüfung: Statt zu vermuten, nachsehen. Rufen Sie die Seite einmal von außen auf, etwa über das Mobilfunknetz, und suchen Sie den Eintrag:
tail -n 50 ./traefik/logs/access.log | awk '{print $1}' | sort | uniq -cLösung: Keine, es funktioniert. Die Konsequenz ist trotzdem wichtig: Ein Test vom Server selbst aus taugt nicht zur Beurteilung, weil genau dieser Weg die umgeschriebene Adresse zeigt. Testen Sie IP-basierte Regeln immer von außen.
Die dynamische IP-Freigabe
Der wirksamste Schutz für ein Login ist, es gar nicht erst für alle erreichbar zu machen. Admin-Oberflächen und Analyse-Dashboards gebe ich nur von der eigenen Herkunft frei.
Das Hindernis ist der wechselnde Anschluss zu Hause. Die Lösung ist ein dynamischer DNS-Name und ein kleiner Dienst, der regelmäßig prüft, ob sich die Adresse geändert hat, und die Freigaben nachzieht. Sinnvoll ist, dabei alle Stellen gemeinsam zu aktualisieren, an denen die Adresse hinterlegt ist, also die Middleware im Proxy, die Firewall und die Ausnahmeliste der Sperr-Engine. Werden diese Stellen getrennt gepflegt, driften sie auseinander, und Sie sperren sich irgendwann selbst aus.
Grenzen
CrowdSec erkennt Muster im Nachhinein. Es sieht einen Angriff, wenn er sich im Log abzeichnet, nicht vorher. Gegen einen einzelnen, gezielten Zugriff mit gültigen Zugangsdaten hilft es nicht.
Die IP-Freigabe wiederum ist stark, aber spröde. Sie schließt Sie selbst aus, sobald Sie von unterwegs arbeiten, und sie hilft nicht bei Diensten, die von vielen Orten erreichbar sein müssen.
Beide zusammen ersetzen keine ordentliche Authentifizierung. Sie senken das Rauschen und verkleinern die Fläche. Der eigentliche Gewinn liegt eine Ebene davor, nämlich in der Frage, was überhaupt öffentlich erreichbar sein muss.
Sie betreiben Dienste im Netz und wollen die Angriffsfläche klein halten? Ich sichere Admin-Zugänge und öffentliche Dienste in mehreren Schichten ab, angefangen bei der Frage, was überhaupt erreichbar sein muss. Mehr unter IT-Sicherheit & ISMS, das Erstgespräch ist unverbindlich.

Alex Jabi
Ich betreue IT, Informationssicherheit und Datenschutz für KMU und Praxen an der Bergstraße und im Odenwald, persönlich, dokumentiert und ohne Cloud-Zwang.
Mehr über mich



