WAF-Schutz zu Nginx hinzufügen

Zwei getestete Ansätze, um Ihren Nginx-Webserver mit einer WAF zu schützen. Fügen Sie Coraza als Reverse Proxy vor Nginx hinzu oder ersetzen Sie Nginx vollständig durch Caddy+Coraza für eine Ein-Container-Lösung.

20-40 Minuten intermediate 8 steps
Zuletzt aktualisiert: Jun 6, 2026

"nginx waf" ist eine der häufigsten Suchanfragen im Bereich der Web-Application-Security, und die Antwort ist weniger offensichtlich, als sie sein sollte. Nginx verfügt über keine eingebaute WAF. Ihre Optionen sind, eine anzuflanschen (ModSecurity-Modul oder ein WAF-Reverse-Proxy vor Nginx) oder auf einen Webserver zu wechseln, der eine WAF eingebaut hat.

Diese Anleitung behandelt zwei Ansätze, beide getestet und verifiziert:

  • Option A: Nginx behalten, einen WAF-Proxy davor schalten, betreiben Sie Caddy mit dem Coraza-WAF-Plugin als Reverse Proxy. Ihre Nginx-Konfiguration bleibt unangetastet. Sie erhalten OWASP-CRS-v4-Schutz ohne Änderungen an Ihrer Anwendung.
  • Option B: Nginx durch Caddy+Coraza ersetzen, verwenden Sie Caddy sowohl als Webserver als auch als WAF. Ein Container, eine Konfigurationsdatei. Caddy übernimmt alles, was Nginx tut (statische Dateien, Reverse Proxy, TLS, Header, gzip), plus WAF-Schutz.

Beide Ansätze verwenden dieselbe WAF-Engine (Coraza) und denselben Regelsatz (OWASP CRS v4). Der Unterschied besteht darin, ob Sie Nginx im Spiel behalten oder Ihren Stack vereinfachen möchten.

Voraussetzungen

  • Docker auf Ihrem System installiert
  • Ein bestehendes Nginx-Setup, das Sie schützen möchten (oder folgen Sie den Beispielen)
  • Grundkenntnisse der Nginx-Konfiguration

Schritt-für-Schritt-Anleitung

1

Option A: WAF-Proxy vor Nginx schalten

Bei diesem Ansatz wird Caddy+Coraza vor Ihr bestehendes Nginx geschaltet. Die Architektur sieht so aus:

Client -> Caddy + Coraza WAF (:443) -> Nginx (:80) -> Your App

Ihre Nginx-Konfiguration bleibt genau so, wie sie ist. Sie fügen einen Caddy-Container hinzu, der den gesamten Datenverkehr prüft, bevor er saubere Anfragen an Nginx weiterleitet. Bösartige Anfragen werden blockiert, bevor sie Ihren Server erreichen.

Sehen Sie sich unsere eigene Schritt-für-Schritt-Anleitung an: Nginx mit Coraza WAF per Docker schützen. Diese Anleitung führt jede Datei, jeden Build-Schritt und jeden Test im Detail durch.

Wann Sie dies wählen sollten: Sie haben ein funktionierendes Nginx-Setup, möchten es nicht ändern und wollen einfach WAF-Schutz obendrauf hinzufügen.

2

Option B: Nginx durch Caddy+Coraza ersetzen

Anstatt zwei Container zu betreiben, können Sie Nginx vollständig ersetzen. Caddy übernimmt statische Dateien, Reverse Proxying, TLS, Header und Komprimierung, genau wie Nginx. Mit dem Coraza-Plugin bietet es zusätzlich WAF-Schutz.

Das Ergebnis: ein Container, eine Konfigurationsdatei, Webserver + WAF + automatisches HTTPS.

Wann Sie dies wählen sollten: Sie fangen neu an, möchten einen einfacheren Stack oder Ihre Nginx-Konfiguration ist unkompliziert genug, um sie nach Caddy zu übertragen.

3

Das Caddy+Coraza-Image bauen

Beide Optionen verwenden dasselbe Docker-Image. Erstellen Sie ein Dockerfile:

FROM caddy:2-builder AS builder

RUN xcaddy build \
    --with github.com/corazawaf/coraza-caddy/v2

FROM caddy:2

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

Bauen Sie es:

docker build -t caddy-coraza .
4

Ihre Nginx-Konfiguration in ein Caddyfile übertragen

So lassen sich gängige Nginx-Direktiven auf Caddy abbilden. Verwenden Sie diese Tabelle, um Ihre Konfiguration umzuwandeln:

Statische Dateien und Grundlagen

# Nginx                          -> Caddy
root /var/www/html;              -> root * /srv
index index.html;                -> (automatic with file_server)
try_files $uri $uri/ =404;       -> file_server
try_files $uri /index.html;      -> try_files {path} /index.html
gzip on;                         -> encode gzip
listen 443 ssl;                  -> (automatic with domain name)

Reverse Proxy

# Nginx                          -> Caddy
proxy_pass http://app:3000;      -> reverse_proxy app:3000
proxy_set_header Host $host;     -> (automatic)
proxy_set_header X-Real-IP ...;  -> (automatic)
proxy_read_timeout 60s;          -> reverse_proxy app:3000 { read_timeout 60s }
proxy_buffering off;             -> reverse_proxy app:3000 { flush_interval -1 }

Header und Sicherheit

# Nginx                          -> Caddy
add_header X-Frame-Options ...;  -> header X-Frame-Options DENY
add_header X-Content-Type ...;   -> header X-Content-Type-Options nosniff
server_tokens off;               -> (off by default in Caddy)

Weiterleitungen und Rewrites

# Nginx                          -> Caddy
return 301 https://$host$uri;    -> redir https://{host}{uri} permanent
rewrite ^/old(.*)$ /new$1;       -> rewrite /old* /new{path.1}
location /blog { ... }           -> handle /blog/* { ... }
location = /health { ... }       -> handle /health { ... }

TLS / HTTPS

# Nginx                          -> Caddy
ssl_certificate /path/cert.pem;  -> tls /path/cert.pem /path/key.pem
ssl_certificate_key /path/...;   -> (or just use a domain name for auto-HTTPS)
ssl_protocols TLSv1.2 TLSv1.3;  -> (TLS 1.2+ by default)
Tipp: Caddy verwaltet TLS-Zertifikate automatisch über Let's Encrypt, wenn Sie einen Domainnamen verwenden. Es sind keine Zertifikatspfade oder Erneuerungsskripte erforderlich.
5

Das Caddyfile mit WAF-Schutz schreiben

Hier ist ein vollständiges Caddyfile, das eine typische Nginx-Konfiguration für eine statische Website ersetzt, mit WAF-Schutz:

{
    order coraza_waf first
}

yourdomain.com {
    coraza_waf {
        load_owasp_crs
        directives `
        Include @coraza.conf-recommended
        Include @crs-setup.conf.example
        Include @owasp_crs/*.conf
        SecRuleEngine On
        `
    }

    root * /srv
    file_server
    encode gzip

    header {
        X-Content-Type-Options nosniff
        X-Frame-Options DENY
        Referrer-Policy strict-origin-when-cross-origin
    }
}

Für ein Reverse-Proxy-Setup (z. B. Proxy zu einer Node.js- oder Python-Anwendung):

{
    order coraza_waf first
}

yourdomain.com {
    coraza_waf {
        load_owasp_crs
        directives `
        Include @coraza.conf-recommended
        Include @crs-setup.conf.example
        Include @owasp_crs/*.conf
        SecRuleEngine On
        `
    }

    reverse_proxy app:3000
}
6

Ausführen und testen

Starten Sie den Container (Beispiel für statische Dateien):

docker run -d -p 80:80 -p 443:443 \
  -v ./Caddyfile:/etc/caddy/Caddyfile:ro \
  -v ./site:/srv:ro \
  -v caddy_data:/data \
  caddy-coraza

Testen Sie, dass normaler Datenverkehr funktioniert:

curl http://localhost/

Testen Sie, dass Angriffe blockiert werden:

# SQL-Injection - sollte 403 zurückgeben
curl -o /dev/null -w "%{http_code}\n" "http://localhost/?id=1%20OR%201=1"

# XSS - sollte 403 zurückgeben
curl -o /dev/null -w "%{http_code}\n" "http://localhost/?q=%3Cscript%3Ealert(1)%3C/script%3E"

# Scanner - sollte 403 zurückgeben
curl -o /dev/null -w "%{http_code}\n" -H "User-Agent: nikto" http://localhost/
7

Was sich nicht 1:1 abbilden lässt

Einige Nginx-Funktionen haben keine direkten Caddy-Entsprechungen. Darauf sollten Sie achten:

Funktioniert anders

  • upstream-Blöcke mit Gewichtungen/Health-Checks: Caddy erledigt dies inline in reverse_proxy mit anderer Syntax. Load-Balancing-Richtlinien (round_robin, least_conn, ip_hash) werden unterstützt, sind aber anders benannt.
  • map-Direktive: keine direkte Entsprechung. Verwenden Sie für einfache Fälle vars oder Caddys expression-Matcher.
  • limit_req_zone / Rate Limiting: verwenden Sie Caddys rate_limit-Direktive (als Plugin verfügbar).
  • Komplexe location-Regex: Caddy verwendet Path-Matcher und benannte Matcher anstelle von Regex-Locations. Die meisten Muster lassen sich sauber übertragen, aber tief verschachtelte Regex-Locations müssen überdacht werden.

In Caddy nicht verfügbar

  • proxy_cache: Caddy verfügt über kein eingebautes Antwort-Caching (es gibt ein cache-handler-Plugin, das aber weniger ausgereift ist als das von Nginx). Wenn Sie stark auf Nginx' Proxy-Cache angewiesen sind, behalten Sie Nginx als Backend.
  • Lua/njs-Scripting: keine Entsprechung. Wenn Sie Nginx-Lua-Skripte haben, müssen diese als Caddy-Plugins (Go) neu geschrieben oder in Ihre Anwendung verlagert werden.
  • HTTP/2 Push: in Browsern veraltet und in Caddy nicht unterstützt.
8

KI zur Umwandlung Ihrer Konfiguration nutzen

Wenn Ihre Nginx-Konfiguration lang oder komplex ist, können Sie einen KI-Assistenten bei der Umwandlung nutzen. Hier ist ein Prompt, den Sie in ChatGPT, Claude oder ein beliebiges LLM einfügen können:

Wandle die folgende Nginx-Konfiguration in eine Caddy-Konfiguration (Caddyfile) um.
Füge außerdem Coraza-WAF-Schutz mit dem coraza-caddy-Plugin und OWASP CRS hinzu.

Anforderungen:
- Verwende die coraza_waf-Direktive mit load_owasp_crs
- Binde @coraza.conf-recommended, @crs-setup.conf.example und @owasp_crs/*.conf ein
- Setze SecRuleEngine On
- Verwende "order coraza_waf first" im globalen Optionsblock
- Erhalte die gesamte bestehende Funktionalität (Weiterleitungen, Header, Proxy-Ziele)
- Füge Kommentare hinzu, die jeden Abschnitt erklären
- Kennzeichne alles, was keine direkte Caddy-Entsprechung hat

Hier ist meine Nginx-Konfiguration:

[Füge hier deine nginx.conf oder Site-Konfiguration ein]

Überprüfen Sie die Ausgabe sorgfältig. Prüfen Sie, ob alle Ihre Locations, Weiterleitungen und Proxy-Ziele erhalten bleiben. Testen Sie die umgewandelte Konfiguration in einer Staging-Umgebung, bevor Sie den Produktivverkehr umstellen.

Tipp: Testen Sie die umgewandelte Konfiguration auch mit KI-Unterstützung immer. Achten Sie besonders auf Weiterleitungen, Rewrites und alle benutzerdefinierten Header, von denen Ihre Anwendung abhängt.

Fazit & Nächste Schritte

Sie haben nun zwei bewährte Wege, um Ihrem Nginx-Setup WAF-Schutz hinzuzufügen:

  • Option A (Reverse Proxy): minimale Änderung, Caddy+Coraza vor Nginx schalten. Am besten, wenn Sie eine funktionierende Nginx-Konfiguration haben, die Sie nicht anfassen möchten.
  • Option B (vollständiger Ersatz): vereinfachen Sie Ihren Stack auf einen Container. Am besten für neue Deployments oder wenn Ihre Nginx-Konfiguration unkompliziert ist.

Beide Ansätze bieten Ihnen denselben OWASP-CRS-v4-Schutz gegen SQL-Injection, XSS, Command Injection, Scanner-Sondierungen und Hunderte weiterer Angriffsmuster.

Nächste Schritte:

  • Überwachen Sie die WAF-Logs in den ersten Tagen auf False Positives
  • Fügen Sie benutzerdefinierte SecRule-Direktiven für anwendungsspezifischen Schutz hinzu
  • Erwägen Sie die Integration von CrowdSec für IP-Reputations-Blockierung
  • Für detaillierte Docker-Setup-Anweisungen siehe die Coraza + Nginx Docker-Anleitung

Fehlerbehebung

Meine Anwendung funktioniert nach dem Hinzufügen der WAF nicht mehr

CRS-Regeln können False Positives bei legitimem Anwendungsdatenverkehr auslösen. Prüfen Sie die WAF-Logs, um herauszufinden, welche Regel auslöst, und fügen Sie dann eine Ausnahme hinzu: SecRuleRemoveById [rule_id] in Ihren Caddyfile-Direktiven.

Caddy-Konfigurationsfehler beim Start

Caddy validiert das Caddyfile beim Start. Häufige Probleme: fehlende schließende Klammern, falsche Einrückung oder die Verwendung von Nginx-Syntax. Führen Sie caddy validate --config Caddyfile --adapter caddyfile im Container aus, um konkrete Fehler zu sehen.

Meine Regex-Location-Blöcke funktionieren in Caddy nicht

Caddy verwendet Path-Matcher und benannte Matcher anstelle von Regex-basierten Location-Blöcken. Verwenden Sie für komplexe Muster benannte Matcher: @api path /api/* und dann handle @api { ... }.

Häufig gestellte Fragen

Kann Caddy Nginx vollständig ersetzen?

Für die meisten Anwendungsfälle ja. Caddy übernimmt das Ausliefern statischer Dateien, Reverse Proxying, TLS (automatisch über Let's Encrypt), Header, gzip-Komprimierung, Weiterleitungen und Load Balancing. Die wesentlichen Lücken sind proxy_cache (in Caddy weniger ausgereift), Lua/njs-Scripting (keine Entsprechung) und einige fortgeschrittene Load-Balancing-Funktionen. Wenn Ihre Nginx-Konfiguration eine standardmäßige statische Website oder ein Reverse Proxy ist, ist Caddy ein direkter Ersatz mit einfacherer Konfiguration.

Ist Caddy so schnell wie Nginx?

Für die meisten Workloads ja. Caddy und Nginx bewältigen beide hohe Nebenläufigkeit gut. Nginx hat bei extremer Skalierung (100k+ Anfragen/Sekunde) einen leichten Vorteil beim reinen Durchsatz statischer Dateien, aber der Unterschied ist für die überwiegende Mehrheit der Deployments vernachlässigbar. Der WAF-Overhead (1 bis 5 ms pro Anfrage durch die CRS-Verarbeitung) ist unabhängig vom verwendeten Webserver gleich.

Muss ich eine neue Konfigurationssprache lernen?

Ja, aber Caddys Konfigurationssprache (Caddyfile) ist einfacher als die von Nginx. Eine typische Nginx-Konfiguration entspricht in Caddy etwa einem Drittel der Zeilen. Die Zuordnungstabelle in dieser Anleitung deckt die gängigsten Direktiven ab. Verwenden Sie für komplexe Konfigurationen den KI-gestützten Umwandlungs-Prompt aus dieser Anleitung.

Kann ich Nginx und Caddy+Coraza während der Migration gleichzeitig betreiben?

Ja. Betreiben Sie Caddy+Coraza auf anderen Ports oder verwenden Sie einen Load Balancer, um den Datenverkehr schrittweise zu verlagern. Beginnen Sie damit, 10 % des Datenverkehrs durch Caddy zu leiten, überwachen Sie auf Probleme und erhöhen Sie dann. Dies ist der sicherste Weg, ohne Ausfallzeit zu migrieren.

Was ist mit Nginx-Plus-Funktionen?

Nginx Plus ergänzt kommerzielle Funktionen wie aktive Health-Checks, Session-Persistenz und ein Dashboard. Caddy bietet für die meisten davon Entsprechungen (aktive Health-Checks in reverse_proxy, Sticky Cookies für Session-Persistenz). Die wesentliche Nginx-Plus-Funktion ohne Caddy-Entsprechung ist das Live-Aktivitäts-Monitoring-Dashboard, obwohl Caddy Metriken über Prometheus bereitstellt.

Ähnliche Anleitungen