DarkWolfCave
linux

Traefik absichern: WAF, Rate-Limiting und TLS-Setup

Cyber-Wolf schützt Web-Dienste mit Traefik Security-Layer und WAF-Schild
DarkWolf Maskottchen KI-Bild Generiert mit Gemini

Traefik absichern: WAF, Rate-Limiting und TLS

Traefik kann mehr als nur Routing. In diesem Artikel zeige ich dir, wie du deinen Reverse Proxy als Sicherheitsschicht konfigurierst — mit TLS, Rate-Limiting, IP-Filterung, Security Headers und einer Web Application Firewall. Alles mit Docker Compose und konkreten Konfigurationsbeispielen.

DarkWolfCave.de

ℹ️ Hinweis: Dieser Artikel setzt voraus, dass du Traefik bereits grundlegend eingerichtet hast. Falls nicht, findest du die Basis-Installation in meinem Traefik-Einrichtungsartikel. Die hier gezeigten Konfigurationen sind für Traefik v3 — bei v2 weichen einzelne Middleware-Namen ab (z.B. ipWhiteList statt ipAllowList).

Warum dein Reverse Proxy mehr als nur Routing kann

Du hast Traefik als Reverse Proxy eingerichtet und leitest Anfragen an deine Docker-Container weiter. Grafana, Portainer, Home Assistant — alles läuft hinter Traefik. Aber nutzt du Traefik auch als Sicherheitsschicht?

Ein Reverse Proxy sitzt an einer strategisch wichtigen Stelle: zwischen dem Internet und deinen Diensten. Jede Anfrage muss durch ihn hindurch. Das macht ihn zum idealen Punkt für Sicherheitsmaßnahmen — TLS-Terminierung, Rate-Limiting, IP-Filterung und sogar eine Web Application Firewall.

Die Maßnahmen in diesem Artikel setzen genau hier an. Sie ergänzen die Netzwerk-Sicherheit und Firewall auf Applikationsebene und arbeiten zusammen mit der Server-Härtung auf Betriebssystemebene.

VIP Support
Wolf Support Avatar

Du wirst hier einen groben Überblick finden.
Allerdings biete ich dir auch noch etwas mehr Support an:

  • Du benötigst persönlichen Support
  • Du möchtest von Beginn an Unterstützung bei deinem Projekt
  • Du möchtest ein hier vorgestelltes Plugin durch mich installieren und einrichten lassen
  • Du würdest gerne ein von mir erstelltes Script etwas mehr an deine Bedürfnisse anpassen

Für diese Punkte und noch einiges mehr habe ich einen limitierten VIP-Tarif eingerichtet.

Falls der Tarif gerade nicht verfügbar ist, kontaktiere mich auf Discord!

TLS-Terminierung mit Let’s Encrypt

Unverschlüsselter HTTP-Traffic ist ein offenes Buch. Jeder im Netzwerkpfad — vom lokalen Netzwerk bis zum ISP — kann mitlesen. TLS löst das Problem, und Traefik macht die Einrichtung mit Let’s Encrypt automatisch.

Certificate Resolver konfigurieren

In deiner traefik.yml (statische Konfiguration) definierst du einen Certificate Resolver:

# traefik.yml
entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@deine-domain.de
      storage: /letsencrypt/acme.json
      httpChallenge:
        entryPoint: web

Die redirections-Konfiguration leitet alle HTTP-Anfragen automatisch auf HTTPS um. Kein Client erreicht deine Dienste unverschlüsselt.

Docker Compose für TLS

# docker-compose.yml
services:
  traefik:
    image: traefik:v3.3
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yml:/traefik.yml:ro
      - ./letsencrypt:/letsencrypt
    networks:
      - proxy

  mein-dienst:
    image: mein-dienst:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.mein-dienst.rule=Host(`dienst.deine-domain.de`)"
      - "traefik.http.routers.mein-dienst.entrypoints=websecure"
      - "traefik.http.routers.mein-dienst.tls.certresolver=letsencrypt"
    networks:
      - proxy

networks:
  proxy:
    name: proxy

💡 Tipp: Setze tls.certresolver=letsencrypt auf jeden Router. Traefik holt und erneuert die Zertifikate vollautomatisch — du musst dich nie wieder um Zertifikate kümmern.

TLS-Optionen verschärfen

Für zusätzliche Sicherheit kannst du die TLS-Version und Cipher-Suites einschränken:

# traefik.yml — TLS-Optionen
tls:
  options:
    default:
      minVersion: VersionTLS12
      cipherSuites:
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
        - TLS_AES_256_GCM_SHA384
        - TLS_CHACHA20_POLY1305_SHA256
EinstellungEmpfehlungBegründung
Min. TLS-Version1.2TLS 1.0/1.1 gelten als unsicher
Cipher-SuitesNur AEADGCM und ChaCha20 sind aktueller Standard
HTTP → HTTPS RedirectAktivierenKein unverschlüsselter Traffic

Rate-Limiting gegen Brute-Force

Rate-Limiting begrenzt die Anzahl der Anfragen pro Zeitraum. Das bremst Brute-Force-Angriffe auf Login-Seiten, API-Missbrauch und einfache DDoS-Versuche.

Middleware definieren

In Traefik definierst du Rate-Limiting als Middleware — per Docker-Label oder in einer dynamischen Konfigurationsdatei:

# Per Docker-Label
labels:
  - "traefik.http.middlewares.rate-limit.ratelimit.average=20"
  - "traefik.http.middlewares.rate-limit.ratelimit.burst=50"
  - "traefik.http.middlewares.rate-limit.ratelimit.period=1s"

Das bedeutet: Maximal 20 Anfragen pro Sekunde im Durchschnitt, mit einem Burst von bis zu 50 Anfragen. Anfragen darüber hinaus erhalten HTTP 429 (Too Many Requests).

Unterschiedliche Limits pro Dienst

Nicht jeder Dienst braucht die gleichen Limits. Ein Login-Formular sollte strenger limitiert sein als eine öffentliche Webseite:

# Strenges Limit für Login-Seiten
labels:
  - "traefik.http.middlewares.auth-limit.ratelimit.average=5"
  - "traefik.http.middlewares.auth-limit.ratelimit.burst=10"
  - "traefik.http.middlewares.auth-limit.ratelimit.period=1s"

# Moderates Limit für APIs
labels:
  - "traefik.http.middlewares.api-limit.ratelimit.average=50"
  - "traefik.http.middlewares.api-limit.ratelimit.burst=100"
  - "traefik.http.middlewares.api-limit.ratelimit.period=1s"

Middleware auf Router anwenden

labels:
  - "traefik.http.routers.mein-dienst.middlewares=rate-limit@docker"

Mehrere Middlewares kombinierst du kommagetrennt:

labels:
  - "traefik.http.routers.mein-dienst.middlewares=rate-limit@docker,security-headers@docker"

Funktionstest

# 100 Anfragen schnell hintereinander senden
for i in $(seq 1 100); do
  curl -s -o /dev/null -w "%{http_code}\n" https://dienst.deine-domain.de/
done

Ab einer bestimmten Anzahl sollten 429-Codes auftauchen — dann greift dein Rate-Limit.

IP-Whitelisting für sensible Dienste

Manche Dienste sollten nur von bestimmten IP-Adressen erreichbar sein — Admin-Panels, Datenbank-Frontends oder Monitoring-Dashboards. Traefik bietet dafür die ipAllowList-Middleware.

Konfiguration per Docker-Label

# Nur lokales Netzwerk und VPN erlauben
labels:
  - "traefik.http.middlewares.local-only.ipallowlist.sourcerange=192.168.1.0/24,10.0.0.0/8"

Alle Anfragen von anderen IPs erhalten HTTP 403 (Forbidden).

Beispiel: Admin-Panel absichern

services:
  portainer:
    image: portainer/portainer-ce
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.portainer.rule=Host(`portainer.deine-domain.de`)"
      - "traefik.http.routers.portainer.entrypoints=websecure"
      - "traefik.http.routers.portainer.tls.certresolver=letsencrypt"
      - "traefik.http.routers.portainer.middlewares=local-only@docker,rate-limit@docker"
      - "traefik.http.middlewares.local-only.ipallowlist.sourcerange=192.168.1.0/24"
    networks:
      - proxy

⚠️ Wichtig: Wenn Traefik hinter einem Load Balancer oder Cloudflare steht, siehst du nicht die echte Client-IP, sondern die des Proxys. Konfiguriere in dem Fall forwardedHeaders oder proxyProtocol in deinen Entrypoints, damit Traefik die echte IP aus dem X-Forwarded-For-Header liest.

EinsatzIP-RangeBeschreibung
Lokales Netzwerk192.168.1.0/24Nur LAN-Zugriff
VPN-Clients10.8.0.0/24Nur über VPN
Einzelne IP203.0.113.5/32Eine spezifische IP
Kombiniert192.168.1.0/24,10.8.0.0/24LAN + VPN

Security Headers setzen

HTTP Security Headers weisen den Browser an, bestimmte Sicherheitsrichtlinien durchzusetzen. Traefik kann diese Headers automatisch zu jeder Antwort hinzufügen.

Headers-Middleware konfigurieren

Per Docker-Labels:

labels:
  - "traefik.http.middlewares.sec-headers.headers.browserxssfilter=true"
  - "traefik.http.middlewares.sec-headers.headers.contenttypenosniff=true"
  - "traefik.http.middlewares.sec-headers.headers.framedeny=true"
  - "traefik.http.middlewares.sec-headers.headers.stsincludesubdomains=true"
  - "traefik.http.middlewares.sec-headers.headers.stspreload=true"
  - "traefik.http.middlewares.sec-headers.headers.stsseconds=31536000"
  - "traefik.http.middlewares.sec-headers.headers.referrerpolicy=strict-origin-when-cross-origin"
  - "traefik.http.middlewares.sec-headers.headers.permissionspolicy=camera=(), microphone=(), geolocation=()"

Oder als dynamische Konfigurationsdatei:

# dynamic/security-headers.yml
http:
  middlewares:
    sec-headers:
      headers:
        browserXssFilter: true
        contentTypeNosniff: true
        frameDeny: true
        stsIncludeSubdomains: true
        stsPreload: true
        stsSeconds: 31536000
        customFrameOptionsValue: "SAMEORIGIN"
        referrerPolicy: "strict-origin-when-cross-origin"
        permissionsPolicy: "camera=(), microphone=(), geolocation=()"

Was bewirken die einzelnen Headers?

HeaderEinstellungWirkung
X-XSS-ProtectionbrowserXssFilter: trueBrowser blockiert erkannte XSS-Angriffe
X-Content-Type-OptionscontentTypeNosniff: trueVerhindert MIME-Type-Sniffing
X-Frame-OptionsframeDeny: trueVerhindert Einbettung in iframes (Clickjacking)
Strict-Transport-SecuritystsSeconds: 31536000Browser erzwingt HTTPS für 1 Jahr
Referrer-Policystrict-origin-when-cross-originBegrenzt Referrer-Informationen
Permissions-Policycamera=(), microphone=()Deaktiviert nicht benötigte Browser-APIs

Headers prüfen

# Response-Headers anzeigen
curl -I https://dienst.deine-domain.de/

In der Ausgabe sollten alle konfigurierten Security Headers auftauchen. Tools wie securityheaders.com bewerten deine Konfiguration von A+ bis F.

Coraza WAF — Web Application Firewall

Eine Web Application Firewall analysiert HTTP-Anfragen auf bekannte Angriffsmuster — SQL-Injection, Cross-Site-Scripting, Path Traversal und mehr. Coraza ist eine moderne WAF-Engine in Go und der Nachfolger von ModSecurity.

Coraza als Traefik-Plugin

Traefik unterstützt Coraza als WASM-Plugin. Das Plugin prüft jede eingehende Anfrage gegen konfigurierbare Regeln — inklusive dem OWASP Core Rule Set (CRS), einer Sammlung von über 200 Regeln gegen die häufigsten Webangriffe.

Zuerst registrierst du das Plugin in der statischen Konfiguration:

# traefik.yml
experimental:
  plugins:
    coraza:
      moduleName: github.com/jcchavezs/coraza-http-wasm-traefik
      version: v0.3.0

Middleware konfigurieren

# dynamic/waf.yml
http:
  middlewares:
    waf:
      plugin:
        coraza:
          directives:
            - "SecRuleEngine On"
            - "SecRequestBodyAccess On"
            - "SecResponseBodyAccess Off"
            - "SecRule REQUEST_URI \"@streq /admin\" \"id:101,phase:1,t:lowercase,log,deny,status:403\""
            - "SecRule ARGS \"@detectSQLi\" \"id:102,phase:2,deny,status:403,msg:'SQL Injection blocked'\""
            - "SecRule ARGS \"@detectXSS\" \"id:103,phase:2,deny,status:403,msg:'XSS blocked'\""

Per Docker-Label:

labels:
  - "traefik.http.middlewares.waf.plugin.coraza.directives[0]=SecRuleEngine On"
  - "traefik.http.middlewares.waf.plugin.coraza.directives[1]=SecRequestBodyAccess On"
  - "traefik.http.middlewares.waf.plugin.coraza.directives[2]=SecRule ARGS \"@detectSQLi\" \"id:102,phase:2,deny,status:403\""
  - "traefik.http.routers.mein-dienst.middlewares=waf@docker,sec-headers@docker,rate-limit@docker"

OWASP Core Rule Set — Was wird geprüft?

Das Core Rule Set deckt die gängigsten Angriffsvektoren ab:

KategorieBeispielCRS-Regeln
SQL-Injection' OR 1=1 --942xxx
Cross-Site-Scripting (XSS)<script>alert(1)</script>941xxx
Path Traversal../../etc/passwd930xxx
Remote Code Execution; cat /etc/passwd932xxx
Scanner-ErkennungNikto, SQLMap User-Agents913xxx

Funktionstest

# Normaler Request — sollte 200 zurückgeben
curl -I https://dienst.deine-domain.de/

# SQL-Injection-Versuch — sollte 403 zurückgeben
curl -I "https://dienst.deine-domain.de/?id=1' OR 1=1 --"

# XSS-Versuch — sollte 403 zurückgeben
curl -I "https://dienst.deine-domain.de/?q=<script>alert(1)</script>"

⚠️ Wichtig: Teste neue WAF-Regeln zuerst im Detection-Only-Modus (SecRuleEngine DetectionOnly). Im Normalbetrieb kann das CRS False Positives verursachen — besonders bei Anwendungen die HTML in Formularen verarbeiten. Beobachte die Logs und passe die Regeln an, bevor du auf On umstellst.

Alternative: ModSecurity als Sidecar

Wenn du ModSecurity statt Coraza bevorzugst, kannst du es als separaten Container betreiben:

services:
  modsecurity:
    image: owasp/modsecurity-crs:nginx
    environment:
      - MODSEC_RULE_ENGINE=On
      - PARANOIA=1
    networks:
      - internal

Traefik leitet an den ModSecurity-Container weiter, der die Anfragen filtert und an den eigentlichen Dienst weitergibt. Der Nachteil: eine zusätzliche Netzwerk-Hop pro Anfrage und mehr Konfigurationsaufwand.

Docker-Netzwerk-Isolation

Die beste Middleware hilft nichts, wenn deine Dienste direkt aus dem Internet erreichbar sind — am Proxy vorbei. Docker-Netzwerk-Isolation stellt sicher, dass alle Anfragen durch Traefik laufen müssen.

Interne Netzwerke verwenden

services:
  traefik:
    image: traefik:v3.3
    ports:
      - "80:80"
      - "443:443"
    networks:
      - proxy

  mein-dienst:
    # KEINE ports: Sektion!
    networks:
      - proxy
      - internal

  datenbank:
    # KEINE ports: Sektion!
    networks:
      - internal

networks:
  proxy:
    name: proxy
  internal:
    name: internal
    internal: true  # Kein Internetzugang

Der Punkt: Nur Traefik hat ports konfiguriert. Deine Dienste haben keine eigenen Port-Mappings und sind nur über das Docker-Netzwerk erreichbar. Die Datenbank sitzt in einem separaten internal-Netzwerk ohne Internetzugang.

NetzwerkInternetzugangContainer
proxyJa (über Traefik)Traefik + alle Web-Dienste
internalNeinDatenbanken, Redis, interne Services

Docker-Socket absichern

Traefik braucht Zugriff auf den Docker-Socket um Container zu erkennen. Das ist ein Sicherheitsrisiko — wer den Socket kontrolliert, kontrolliert den Host. Zwei Maßnahmen helfen:

1. Read-Only-Zugriff:

volumes:
  - /var/run/docker.sock:/var/run/docker.sock:ro

2. Docker Socket Proxy dazwischenschalten:

services:
  docker-socket-proxy:
    image: tecnativa/docker-socket-proxy
    environment:
      - CONTAINERS=1
      - NETWORKS=1
      - SERVICES=1
      - TASKS=0
      - POST=0
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - proxy

  traefik:
    environment:
      - DOCKER_HOST=tcp://docker-socket-proxy:2375
    # Kein docker.sock Volume mehr nötig
    networks:
      - proxy

Der Socket Proxy gibt Traefik nur Lesezugriff auf die Container-API — ohne die Möglichkeit Container zu starten, stoppen oder zu löschen.

Access-Logs und Monitoring

Sicherheitsmaßnahmen sind nur so gut wie deine Fähigkeit, Angriffe zu erkennen. Traefik-Access-Logs liefern die Daten dafür.

Access-Logs aktivieren

# traefik.yml
accessLog:
  filePath: /var/log/traefik/access.log
  format: json
  filters:
    statusCodes:
      - "400-499"
      - "500-599"
    retryAttempts: true

Das JSON-Format ist einfacher zu parsen als das Common Log Format und enthält mehr Informationen — Client-IP, Anfrage-Dauer, Middleware-Entscheidungen und Status-Codes.

Integration mit Fail2Ban

Fail2Ban kann die Traefik-Logs überwachen und IPs nach wiederholten Fehlversuchen sperren:

# /etc/fail2ban/filter.d/traefik-auth.conf
[Definition]
failregex = ^.*"ClientHost":"<HOST>".*"OriginStatus":40[13].*$
# /etc/fail2ban/jail.d/traefik.conf
[traefik-auth]
enabled = true
filter = traefik-auth
logpath = /var/log/traefik/access.log
maxretry = 5
bantime = 3600
findtime = 300

Das sperrt IPs für eine Stunde nach 5 fehlgeschlagenen Authentifizierungsversuchen innerhalb von 5 Minuten.

💡 Tipp: Wenn du bereits Monitoring mit auditd und AIDE betreibst, füge die Traefik-Logs zu deiner Überwachung hinzu. Ungewöhnliche Muster — z.B. massenhafte 403er von einer IP — sind oft der erste Hinweis auf einen Angriff.

Alle Maßnahmen zusammen

Hier die acht Maßnahmen im Überblick — von einfach bis fortgeschritten:

MaßnahmeAufwandWirkungPriorität
HTTP → HTTPS Redirect2 MinutenKein unverschlüsselter TrafficKritisch
TLS mit Let’s Encrypt10 MinutenAutomatische ZertifikatsverwaltungKritisch
Rate-Limiting5 MinutenBremst Brute-Force und DDoSHoch
Security Headers5 MinutenBrowser-seitige SchutzmaßnahmenHoch
Docker-Netzwerk-Isolation10 MinutenKein Bypass am Proxy vorbeiHoch
IP-Whitelisting5 MinutenZugriffskontrolle für sensible DiensteMittel
Access-Logs + Fail2Ban15 MinutenAngriffserkennung und automatische SperrungMittel
WAF (Coraza)30 MinutenSchutz vor OWASP Top 10Fortgeschritten

Traefik ist mehr als ein Reverse Proxy — mit den richtigen Middlewares wird er zur Sicherheitsschicht vor deinen Diensten. Fang mit TLS und Rate-Limiting an, füge Security Headers hinzu und arbeite dich dann zu Docker-Netzwerk-Isolation und WAF vor.

Und wenn du die Grundlagen noch brauchst: Die Traefik-Einrichtung erklärt die Basis-Installation, in meiner SSH-Komplettanleitung geht es um die Absicherung des Serverzugangs, und mit Netzwerk-Sicherheit und Firewall schließt du die Lücken auf Netzwerkebene. Zusammen bilden diese Artikel eine Security-Strategie für jeden Linux-Server.

Hardware-Keys für 2FA und deutschsprachige Security-Bücher

Werbung

Security Tools & Literatur

Bild Produkt Preis
Produktdaten werden geladen...
Letzte Aktualisierung: - | Infos zu Affiliate Links | Bilder von der Amazon Product Advertising API

Die komplette Artikelserie

Diese Artikel bilden zusammen einen Leitfaden für Linux-Server-Sicherheit:

  1. SSH-Server absichern — Die Eingangstür härten
  2. Netzwerk-Sicherheit & Firewall — Den Perimeter schützen
  3. Linux-Server härten — Die Angriffsfläche minimieren
  4. Monitoring & Intrusion Detection — Angriffe erkennen
  5. Endlessh SSH Tarpit — Bots aufhalten und beobachten
  6. Backup & Defense-in-Depth — Das Sicherheitsnetz und die Gesamtstrategie
  7. Traefik als Security-Layer (dieser Artikel) — WAF, Rate-Limiting und TLS
FAQ - Frequently Asked Questions DarkWolfCave
DarkWolf hilft bei FAQs

Häufig gestellte Fragen

Brauche ich TLS auch im Heimnetzwerk?
Für rein lokale Dienste ohne Internetzugang ist TLS optional. Sobald ein Dienst über das Internet erreichbar ist — auch über einen Tunnel oder VPN — ist TLS Pflicht. Selbst im lokalen Netzwerk schützt TLS vor Man-in-the-Middle-Angriffen, falls ein Gerät kompromittiert ist.
Welche Rate-Limits sind für einen normalen Webserver sinnvoll?
Für APIs und Login-Seiten empfehle ich 10-20 Anfragen pro Sekunde als Einstieg. Für statische Webseiten kannst du höher gehen (50-100/s). Beobachte deine normalen Zugriffsmuster und setze das Limit so, dass legitime Nutzer nicht betroffen sind, aber automatisierte Angriffe gebremst werden.
Was ist der Unterschied zwischen ipWhiteList und ipAllowList?
Ab Traefik v3 wurde ipWhiteList in ipAllowList umbenannt. Die Funktionalität ist identisch — nur der Name hat sich geändert. Wenn du Traefik v2 nutzt, verwende weiterhin ipWhiteList. Bei v3 funktioniert der alte Name nicht mehr.
Verlangsamt eine WAF meinen Server?
Minimal. Coraza prüft jede Anfrage gegen die Regeln, was typischerweise 1-5 Millisekunden pro Request kostet. Bei den meisten Anwendungen ist das nicht spürbar. Für hochfrequente APIs kannst du die Regeln gezielt reduzieren oder bestimmte Pfade von der Prüfung ausschließen.
Kann ich Rate-Limiting und IP-Whitelisting gleichzeitig nutzen?
Ja, Traefik-Middlewares lassen sich in einer Kette kombinieren. Du definierst die Reihenfolge über das Label traefik.http.routers.name.middlewares. Sinnvoll ist: zuerst IP-Allowlist prüfen, dann Rate-Limit anwenden. So werden erlaubte IPs nicht unnötig limitiert.
Was ist Coraza und wie unterscheidet es sich von ModSecurity?
Coraza ist eine in Go geschriebene WAF-Engine, die als moderner Nachfolger von ModSecurity gilt. Sie ist kompatibel mit dem OWASP Core Rule Set (CRS) und bietet bessere Performance sowie native Integration als Traefik-Plugin. ModSecurity ist das Original in C, aber die Entwicklung der v3 stagniert.
Wie teste ich ob meine Security-Middlewares funktionieren?
Nutze curl mit verschiedenen Parametern: curl -I für Header-Prüfung, eine Schleife für Rate-Limit-Tests, und Anfragen von nicht-erlaubten IPs für Allowlist-Tests. Für WAF-Tests sendest du typische SQL-Injection oder XSS-Strings und prüfst ob sie blockiert werden.

Kommentare

URLs werden automatisch verlinkt
Kommentare werden geladen...