Nginx mit Modsecurity: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(16 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
 
= NGINX mit ModSecurity v3 und OWASP CRS als Reverse Proxy =
 
= NGINX mit ModSecurity v3 und OWASP CRS als Reverse Proxy =
 +
 +
Diese Konfiguration stellt einen TLS-gesicherten Reverse-Proxy mit aktiver ModSecurity-WAF und OWASP Core Rule Set (CRS) bereit. Ziel ist die Absicherung von Backend-Webdiensten, ergänzt durch Logging, Debug-Informationen und optionaler Anzeige des Audit-Logs im Browser.
  
 
== Voraussetzungen ==
 
== Voraussetzungen ==
 
* Ubuntu 22.04 oder Debian 12
 
* Ubuntu 22.04 oder Debian 12
* Zielsystem z. B. unter http://127.0.0.1:8080 erreichbar
+
* Backend-Dienst z. B. unter http://127.0.0.1:8080 erreichbar
 +
* TLS-Zertifikate (crt.pem, privkey.pem, ca.crt) aus interner CA
  
 
== Installation ==
 
== Installation ==
* NGINX und ModSecurity installieren
+
* Pakete installieren
 
  sudo apt update
 
  sudo apt update
  sudo apt install nginx libmodsecurity3 libnginx-mod-http-modsecurity git -y
+
  sudo apt install nginx libmodsecurity3 libnginx-mod-http-modsecurity git apache2-utils -y
  
 
== ModSecurity aktivieren ==
 
== ModSecurity aktivieren ==
* Konfigurationsverzeichnis erstellen
+
* Konfigurationsverzeichnis anlegen
 
  sudo mkdir -p /etc/nginx/modsec
 
  sudo mkdir -p /etc/nginx/modsec
  
* Standardkonfiguration erstellen
+
* Basis-Konfiguration erstellen
  sudo vi /etc/nginx/modsec/modsecurity.conf
+
  sudo nano /etc/nginx/modsec/modsecurity.conf
 
<pre>
 
<pre>
# Aktivieren des ModSecurity-Engines
 
 
SecRuleEngine On
 
SecRuleEngine On
 +
SecRequestBodyAccess On
 +
SecResponseBodyAccess Off
  
# Audit-Log-Modus (nur für Tests, später evtl. RelevantOnly)
 
 
SecAuditEngine RelevantOnly
 
SecAuditEngine RelevantOnly
 +
SecAuditLog /var/log/nginx/modsec_audit.log
 +
SecAuditLogParts ABIJDEFHZ
  
# Audit-Protokoll-Pfad
+
SecDebugLog /var/log/nginx/modsec_debug.log
SecAuditLog /var/log/nginx/modsec_audit.log
+
SecDebugLogLevel 3
  
# Speicherort für Zwischenregeln
 
 
SecTmpDir /tmp/
 
SecTmpDir /tmp/
 
SecDataDir /tmp/
 
SecDataDir /tmp/
  
# Basisregeln zulassen
+
# Beispiel-Testregel (optional)
SecRequestBodyAccess On
+
SecRule ARGS "@contains script" \
SecResponseBodyAccess Off
+
    "id:9999,phase:1,deny,log,status:403,msg:'Test rule triggered'"
  
# Logging
+
# OWASP Core Rule Set
SecDebugLog /var/log/nginx/modsec_debug.log
+
Include /etc/nginx/modsec/coreruleset/crs-setup.conf
SecDebugLogLevel 0
+
Include /etc/nginx/modsec/coreruleset/rules/*.conf
 
 
# Empfohlene Defaults
 
SecRule ARGS "@rx attack" "id:1234,deny,status:403,msg:'Attack detected'"
 
 
</pre>
 
</pre>
  
Zeile 53: Zeile 54:
  
 
== ModSecurity-Snippet erstellen ==
 
== ModSecurity-Snippet erstellen ==
* Konfigurationsdatei erstellen
+
* Konfigurationsdatei anlegen
 
  sudo nano /etc/nginx/modsec/main.conf
 
  sudo nano /etc/nginx/modsec/main.conf
 +
<pre>
 +
modsecurity on;
 +
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
 +
</pre>
  
* Inhalt:
+
== NGINX-Site konfigurieren ==
modsecurity on;
+
* Standard-VHost anpassen
  modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
+
  sudo nano /etc/nginx/sites-available/default
include /etc/nginx/modsec/coreruleset/crs-setup.conf;
+
<pre>
include /etc/nginx/modsec/coreruleset/rules/*.conf;
+
# HTTP → HTTPS Redirect
 +
server {
 +
    listen 80;
 +
    server_name localhost;
 +
    return 301 https://$host$request_uri;
 +
}
  
== Reverse Proxy konfigurieren ==
+
# HTTPS-Server mit TLS und ModSecurity
* Standard-VHost ersetzen
+
server {
sudo nano /etc/nginx/sites-available/default
+
    listen 443 ssl;
 +
    server_name localhost;
  
* Inhalt:
+
    ssl_certificate    /etc/nginx/fullchain.pem;
server {
+
    ssl_certificate_key /etc/nginx/privkey.pem;
    listen 80;
 
    server_name localhost;
 
 
   
 
   
    include /etc/nginx/modsec/main.conf;
 
 
    location / {
 
        proxy_pass http://127.0.0.1:8080;
 
        proxy_set_header Host $host;
 
        proxy_set_header X-Real-IP $remote_addr;
 
        proxy_set_header X-Forwarded-For
 
$proxy_add_x_forwarded_for;
 
    }
 
}
 
  
== NGINX prüfen und neu laden ==
+
    ssl_protocols TLSv1.2 TLSv1.3;
* Syntax testen
+
    ssl_prefer_server_ciphers on;
sudo nginx -t
+
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
 +
 
 +
    access_log /var/log/nginx/access.log waf_combined;
 +
    error_log  /var/log/nginx/error.log warn;
 +
 
 +
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
 +
    add_header Cache-Control "no-store, no-cache, must-revalidate";
 +
 
 +
    error_page 403 /403.html;
 +
    location = /403.html {
 +
        root /var/www/html;
 +
        internal;
 +
    }
 +
 
 +
    include /etc/nginx/modsec/main.conf;
 +
 
 +
    location / {
 +
        proxy_pass http://192.168.178.66;
 +
        proxy_set_header Host $host;
 +
        proxy_set_header X-Real-IP $remote_addr;
 +
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 +
    }
 +
 
 +
    # Optional: Audit-Log über Browser abrufbar
 +
    location /_waflog {
 +
        alias /var/log/nginx/modsec_audit.log;
 +
        types { }
 +
        default_type text/plain;
 +
 
 +
        auth_basic "ModSecurity Auditlog";
 +
        auth_basic_user_file /etc/nginx/.htpasswd;
 +
    }
 +
}
 +
</pre>
 +
 
 +
== Logging ==
 +
* Log-Format ergänzen (/etc/nginx/nginx.conf im http{}-Block)
 +
<pre>
 +
log_format waf_combined '$remote_addr - $remote_user [$time_local] '
 +
                        '"$request" $status $body_bytes_sent '
 +
                        '"$http_referer" "$http_user_agent" '
 +
                        'ModSecID=$request_id Host="$host" URI="$request_uri"';
 +
</pre>
 +
 
 +
* Log-Dateien anlegen
 +
<pre>
 +
touch /var/log/nginx/modsec_audit.log /var/log/nginx/modsec_debug.log
 +
chown www-data:www-data /var/log/nginx/modsec_*.log
 +
chmod 640 /var/log/nginx/modsec_*.log
 +
</pre>
  
* Dienst neu laden
+
== Fehlerseite anlegen ==
  sudo systemctl reload nginx
+
* Beispiel-Datei /var/www/html/403.html
 +
<pre>
 +
<html>
 +
  <head><title>403 Forbidden</title></head>
 +
<body>
 +
<h1>Oops! Zugriff verweigert</h1>
 +
<p>Deine Anfrage wurde von der Web Application Firewall blockiert.</p>
 +
</body>
 +
</html>
 +
</pre>
  
== Test ==
+
== Aktivierung ==
* Beispielziel: Python-Testserver
+
<pre>
python3 -m http.server 8080
+
ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
 +
nginx -t && systemctl reload nginx
 +
</pre>
  
* Angriff simulieren
+
== Hinweise ==
curl "http://localhost/?param=<script>alert(1)</script>"
+
* crs-setup.conf definiert Paranoia-Level, Variablen und Schwellenwerte.
 +
* Regeln liegen unter /etc/nginx/modsec/coreruleset/rules/.
 +
* Zugriff auf /_waflog erlaubt Audit-Log-Ansicht im Browser (mit Basic-Auth).
 +
* ModSecurity greift nur, wenn include /etc/nginx/modsec/main.conf gesetzt ist.
  
* Audit-Log (wenn aktiviert) prüfen:
+
[[KATEGORIE:WAF]]
/var/log/nginx/error.log
 

Aktuelle Version vom 23. August 2025, 17:28 Uhr

NGINX mit ModSecurity v3 und OWASP CRS als Reverse Proxy

Diese Konfiguration stellt einen TLS-gesicherten Reverse-Proxy mit aktiver ModSecurity-WAF und OWASP Core Rule Set (CRS) bereit. Ziel ist die Absicherung von Backend-Webdiensten, ergänzt durch Logging, Debug-Informationen und optionaler Anzeige des Audit-Logs im Browser.

Voraussetzungen

  • Ubuntu 22.04 oder Debian 12
  • Backend-Dienst z. B. unter http://127.0.0.1:8080 erreichbar
  • TLS-Zertifikate (crt.pem, privkey.pem, ca.crt) aus interner CA

Installation

  • Pakete installieren
sudo apt update
sudo apt install nginx libmodsecurity3 libnginx-mod-http-modsecurity git apache2-utils -y

ModSecurity aktivieren

  • Konfigurationsverzeichnis anlegen
sudo mkdir -p /etc/nginx/modsec
  • Basis-Konfiguration erstellen
sudo nano /etc/nginx/modsec/modsecurity.conf
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off

SecAuditEngine RelevantOnly
SecAuditLog /var/log/nginx/modsec_audit.log
SecAuditLogParts ABIJDEFHZ

SecDebugLog /var/log/nginx/modsec_debug.log
SecDebugLogLevel 3

SecTmpDir /tmp/
SecDataDir /tmp/

# Beispiel-Testregel (optional)
SecRule ARGS "@contains script" \
    "id:9999,phase:1,deny,log,status:403,msg:'Test rule triggered'"

# OWASP Core Rule Set
Include /etc/nginx/modsec/coreruleset/crs-setup.conf
Include /etc/nginx/modsec/coreruleset/rules/*.conf

OWASP Core Rule Set installieren

  • In das ModSecurity-Verzeichnis wechseln
cd /etc/nginx/modsec
  • CRS klonen
sudo git clone https://github.com/coreruleset/coreruleset.git
  • Setup-Datei aktivieren
sudo cp coreruleset/crs-setup.conf.example coreruleset/crs-setup.conf

ModSecurity-Snippet erstellen

  • Konfigurationsdatei anlegen
sudo nano /etc/nginx/modsec/main.conf
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;

NGINX-Site konfigurieren

  • Standard-VHost anpassen
sudo nano /etc/nginx/sites-available/default
# HTTP → HTTPS Redirect
server {
    listen 80;
    server_name localhost;
    return 301 https://$host$request_uri;
}

# HTTPS-Server mit TLS und ModSecurity
server {
    listen 443 ssl;
    server_name localhost;

    ssl_certificate     /etc/nginx/fullchain.pem;
    ssl_certificate_key /etc/nginx/privkey.pem;
 

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';

    access_log /var/log/nginx/access.log waf_combined;
    error_log  /var/log/nginx/error.log warn;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header Cache-Control "no-store, no-cache, must-revalidate";

    error_page 403 /403.html;
    location = /403.html {
        root /var/www/html;
        internal;
    }

    include /etc/nginx/modsec/main.conf;

    location / {
        proxy_pass http://192.168.178.66;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # Optional: Audit-Log über Browser abrufbar
    location /_waflog {
        alias /var/log/nginx/modsec_audit.log;
        types { }
        default_type text/plain;

        auth_basic "ModSecurity Auditlog";
        auth_basic_user_file /etc/nginx/.htpasswd;
    }
}

Logging

  • Log-Format ergänzen (/etc/nginx/nginx.conf im http{}-Block)
log_format waf_combined '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent" '
                        'ModSecID=$request_id Host="$host" URI="$request_uri"';
  • Log-Dateien anlegen
touch /var/log/nginx/modsec_audit.log /var/log/nginx/modsec_debug.log
chown www-data:www-data /var/log/nginx/modsec_*.log
chmod 640 /var/log/nginx/modsec_*.log

Fehlerseite anlegen

  • Beispiel-Datei /var/www/html/403.html
<html>
 <head><title>403 Forbidden</title></head>
 <body>
 <h1>Oops! Zugriff verweigert</h1>
 <p>Deine Anfrage wurde von der Web Application Firewall blockiert.</p>
 </body>
</html>

Aktivierung

ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
nginx -t && systemctl reload nginx

Hinweise

  • crs-setup.conf definiert Paranoia-Level, Variablen und Schwellenwerte.
  • Regeln liegen unter /etc/nginx/modsec/coreruleset/rules/.
  • Zugriff auf /_waflog erlaubt Audit-Log-Ansicht im Browser (mit Basic-Auth).
  • ModSecurity greift nur, wenn include /etc/nginx/modsec/main.conf gesetzt ist.