Zurück zum Blog

Three-Layer Brute-Force Protection System

Three-Layer Brute-Force Protection System für matzka.cloud

Three-Layer Brute-Force Protection System für matzka.cloud

Datum 8. Januar 2026
Kategorie Sicherheit, Infrastruktur
Lesezeit 12 Minuten

Einführung

Sicherheit ist ein kritischer Aspekt jeder modernen Cloud-Infrastruktur. Bei matzka.cloud betreiben wir elf verschiedene Dienste mit Authentifizierungsendpunkten, die potentiell anfällig für Brute-Force-Angriffe sind.

Dienste mit Authentifizierung: Authentik SSO, Nextcloud, Directus CMS, n8n, Mailcow, Grafana, Wazuh, Umami Analytics und Portal

Die Anforderung war klar: Ein umfassendes Schutzsystem implementieren, das Angreifer erkennt und blockiert, ohne legitime Benutzer zu behindern.

Die Herausforderung

Ausgangslage

Vor dieser Implementierung hatten wir:

  • ✅ Fail2ban für SSH-Schutz
  • ✅ Wazuh SIEM für Sicherheitsüberwachung
  • ✅ Traefik als Reverse Proxy
  • ❌ Keine Web-Service Brute-Force Protection
  • ❌ Keine Koordination zwischen Systemen
  • ❌ Keine automatische IP-Blockierung für Web-Services

Anforderungen

  1. Multi-Layer Defence: Angreifer auf mehreren Ebenen blockieren
  2. Automatisierung: Keine manuellen Eingriffe nötig
  3. Transparenz: Email-Benachrichtigungen für alle Blöcke
  4. Keine False Positives: Legitime Benutzer nicht behindern
  5. SSO-Kompatibilität: OAuth/OIDC-Flows müssen funktionieren

Architektur: Drei Schichten

Das System arbeitet auf drei verschiedenen Ebenen:

┌─────────────────────────────────────────┐ │ Internet (Angreifer) │ └─────────────┬───────────────────────────┘ │ ┌───────▼────────┐ │ Layer 3: │ Traefik Rate Limiting │ HTTP Level │ (5-30 req/min) └───────┬────────┘ │ ┌───────▼────────┐ │ Layer 2: │ Wazuh IPS │ Host Firewall │ (Firewall-Drop) └───────┬────────┘ │ ┌───────▼────────┐ │ Layer 1: │ Fail2ban │ iptables Ban │ (iptables-multiport) └───────┬────────┘ │ ┌───────▼────────────────┐ │ Authentifizierte │ │ Web-Services │ └────────────────────────┘

Wie es funktioniert

  1. Request kommt an → Traefik Rate Limiter überprüft
  2. Rate Limit überschritten? → HTTP 429 (zu viele Anfragen)
  3. Failed Login Attempt → Traefik loggt in access.log (JSON)
  4. Fail2ban liest Log → Erkennt fehlgeschlagene Logins
  5. 5 Versuche in 10 Min? → IP wird blockiert (iptables)
  6. Wazuh erkennt Muster → Zusätzliches firewall-drop Command
  7. IP-Blockade → 1-2 Stunden (je nach Service)
  8. Email-Alert → Admin wird benachrichtigt

Schicht 1: Fail2ban

JSON-basierte Log-Analyse

Traefik gibt Logs im JSON-Format aus. Dies erforderte eine spezielle Regex:

# Filter: /etc/fail2ban/filter.d/matzka-bruteforce.conf
[Definition]
failregex = "ClientAddr":"(<HOST>[^"]+)".+?"DownstreamStatus":(401|403)
ignoreregex = "/api/live|/ping|/metrics|/health"

10 Aktive Jails

Jail Service Max Retries Ban Time
authentik-login Authentik SSO 5 in 10min 1h
nextcloud-login Nextcloud 5 in 10min 1h
directus-login Directus CMS 5 in 10min 1h
n8n-login n8n Automation 5 in 10min 1h
grafana-login Grafana 3 in 10min 2h
wazuh-login Wazuh SIEM 3 in 10min 2h

Schicht 2: Wazuh IPS

Automatische Firewall-Blockierung

<!-- In /var/ossec/etc/ossec.conf -->
<command>
  <name>firewall-drop</name>
  <executable>firewall-drop</executable>
  <timeout_allowed>yes</timeout_allowed>
</command>

<active-response>
  <disabled>no</disabled>
  <command>firewall-drop</command>
  <location>local</location>
  <rules_id>80702,5503,5504,5505</rules_id>
  <timeout>3600</timeout>
</active-response>
Sicherheit: Wazuh läuft in separatem Docker-Network, was Email-Konfiguration komplex macht. Lösung: Alertmanager als zentrale Email-Komponente für alle Warnungen.

Schicht 3: Traefik Rate Limiting

Rate-Limiting Policies

ratelimit-sso:           30 req/min  # OAuth/OIDC Flows
ratelimit-login:         5 req/min   # Standard Login
ratelimit-admin:         3 req/min   # Admin Interfaces
ratelimit-api:          20 req/min   # API Endpoints

Kritisches Learning: SSO-Kompatibilität

OAuth/OIDC-Flows benötigen deutlich mehr Requests als normales "POST login":

  • Initial auth request
  • Redirect zu Authentik
  • Token request
  • Token validation
  • Cookie/Session management
Warnung: 5 req/min ist zu restriktiv für SSO. Erhöht auf 30 req/min für `auth-login` Policy, um OIDC/OAuth Flows zu ermöglichen.

Probleme & Lösungen

Problem 1: SSO funktioniert nicht mehr

Error:
Route /auth/login/authentik doesn't exist
HTTP/2 404 Not Found

Diagnose

  • Directus hat keine Authentik-Umgebungsvariablen
  • .env file war unvollständig
  • AUTH_AUTHENTIK_DRIVER= war leer

Lösung

  1. Alle AUTH_AUTHENTIK_* Variablen zur .env hinzufügen
  2. Echte CLIENT_SECRET aus Authentik-DB abrufen:
    docker exec postgres-authentik psql -U authentik -d authentik -c \
    "SELECT client_secret FROM authentik_providers_oauth2_oauth2provider \
    WHERE name ILIKE '%directus%';"
  3. Directus neu starten mit korrekten Credentials
Lesson Learned: OAuth2 Secrets dürfen nicht geraten werden. Authentik-DB ist "Source of Truth" für OAuth-Credentials.

Problem 2: Rate-Limiting zu restriktiv für SSO

Ursache

5 req/min für `auth-login` ist zu restriktiv. OIDC Authorization Flow mit PKCE benötigt 8-12 Anfragen in schneller Folge.

Lösung

# Neue Policy für SSO
ratelimit-sso:
  rateLimit:
    average: 30 req/min
    burst: 60

# Verwendung in auth-login Chain
auth-login:
  chain:
    middlewares:
      - ratelimit-sso  # 30 req/min statt 5

Problem 3: Traefik Middleware YAML Syntax

Fehler

middleware "mailcow-headers,auth-login@file" does not exist

Ursache

# ❌ Falsch: Comma-separated String
middlewares: mailcow-headers,auth-login@file

# ✅ Richtig: YAML Liste
middlewares:
  - mailcow-headers
  - auth-login@file
Wichtig: Traefik Docker Labels sind Strings, müssen aber als YAML-Listen interpretiert werden.

Finale Konfiguration

Alle 11 geschützten Services

# Service Fail2ban Rate Limit Wazuh IPS
1 Authentik (auth.matzka.cloud) 30 req/min
2 Nextcloud (next.matzka.cloud) 5 req/min
3 Directus (cms.matzka.cloud) 5 req/min
4 n8n (n8n.matzka.cloud) 5 req/min
5 Mailcow (mail.matzka.cloud) 5 req/min
6 Grafana (monitor.matzka.cloud) 3 req/min
7 Wazuh (siem.matzka.cloud) 3 req/min
8 Umami (analytics.matzka.cloud) 5 req/min
9 Portal (portal.matzka.cloud) - 5 req/min
10 WebApp (matzka.cloud) - 10 req/min
11 n8n Webhook (/webhook/chat) 25 req/min
Resultat: Alle 11 Services sind geschützt, SSO funktioniert, Brute-Force-Angreifer werden blockiert.

Lessons Learned

Technische Erkenntnisse

1. Layered Security funktioniert

  • Eine Schicht allein reicht nicht
  • Mehrere Schichten erschweren Angriffe exponentiell
  • Redundanz ist wichtig: Bei Fehler in einer Schicht funktionieren andere noch

2. Network Isolation ist Double-Edged

  • ✅ Gut für Sicherheit (Services können sich nicht beeinflussen)
  • ❌ Schlecht für Konfiguration (komplexe DNS/Network-Setup)
  • 💡 Zentrale Koordination (Prometheus) ist besser als dezentral

3. Log Format ist kritisch

  • JSON-Logs sind strukturiert, aber komplexer zum Parsen
  • Alte regex-based Tools brauchen Anpassungen
  • Investition in JSON-aware Tools lohnt sich

4. OAuth/OIDC ist komplex

  • Viel mehr Requests als normales "POST login"
  • PKCE, State, Nonce, Token Refresh
  • Rate Limits müssen "großzügig" für SSO sein

Prozess Erkenntnisse

  1. Monitoring first, dann sperren: Zuerst Fail2ban mit Email, ohne zu blockieren
  2. Dokumentation während Implementierung: Was funktioniert nicht? Warum? Wie gelöst?
  3. Schritt für Schritt: Nicht alles auf einmal ändern. Eine Schicht nach der anderen.
  4. Testing ist essential: Jede Konfigurationsänderung mit echten Clients testen

Empfehlungen für zukünftige Projekte

Best Practices:
  • Layered Defense von Anfang an planen
  • Logs strukturiert (JSON) speichern
  • Zentrale Alerting-Komponente (Prometheus + Alertmanager) nutzen
  • Rate Limits nicht zu restriktiv für SSO/OAuth
  • Monitoring ohne Blocking starten, dann progressiv verschärfen

Fazit

Das Three-Layer Brute-Force Protection System für matzka.cloud ist nun produktiv im Betrieb:

Deployments-Status:
✅ 10 Fail2ban Jails überwachen alle Login-Endpunkte
✅ Wazuh IPS blockiert verdächtige IPs auf Firewall-Ebene
✅ Traefik Rate Limiting drosselt schnelle Anfragen
✅ Alertmanager benachrichtigt Admin über Vorfälle
✅ Alle 11 Web-Services sind geschützt
✅ SSO/OAuth Flows funktionieren korrekt
✅ Keine False Positives für legitime Benutzer

Das System wurde unter realen Bedingungen getestet und alle identifizierten Probleme wurden gelöst. Die Infrastruktur ist nun deutlich resistenter gegen Brute-Force-Angriffe, während gleichzeitig Benutzerfreundlichkeit und SSO-Funktionalität erhalten bleiben.