Nginx mit Modsecurity zusammen Whitelists: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
Zeile 1: Zeile 1:
 
= NGINX mit ModSecurity und Whitelist-Policy =
 
= NGINX mit ModSecurity und Whitelist-Policy =
  
Diese Anleitung zeigt den Aufbau einer Web Application Firewall mit NGINX und ModSecurity v3. Zuerst wird ModSecurity mit OWASP Core Rule Set (CRS) als Reverse Proxy aktiviert, anschließend wird eine Whitelist-Policy ergänzt, die nur definierte Methoden und Pfade zulässt. Alles andere wird standardmäßig blockiert.
+
Diese Anleitung zeigt den Aufbau einer Web Application Firewall mit NGINX und ModSecurity v3.
 +
Im ersten Schritt wird ModSecurity mit OWASP Core Rule Set (CRS) als Reverse Proxy aktiviert
 +
Im zweiten Schritt folgt die Whitelist-Policy, bei der nur definierte Methoden und Pfade erlaubt sind.
 +
Alles andere wird standardmäßig blockiert.
  
 
== Voraussetzungen ==
 
== Voraussetzungen ==
 +
Bevor es losgeht, muss das System vorbereitet sein. Wir arbeiten hier mit Ubuntu 22.04 oder Debian 12, einem funktionierenden Backend (z. B. Web-App auf Port 8080) und internen TLS-Zertifikaten.
 
* Ubuntu 22.04 oder Debian 12
 
* Ubuntu 22.04 oder Debian 12
 
* Backend-Dienst z. B. unter http://127.0.0.1:8080 erreichbar
 
* Backend-Dienst z. B. unter http://127.0.0.1:8080 erreichbar
Zeile 9: Zeile 13:
  
 
== Installation ==
 
== Installation ==
 +
Zunächst werden die benötigten Pakete installiert und ein Konfigurationsverzeichnis angelegt.
 
* Pakete installieren
 
* Pakete installieren
 
  sudo apt update
 
  sudo apt update
Zeile 17: Zeile 22:
  
 
== OWASP Core Rule Set installieren ==
 
== OWASP Core Rule Set installieren ==
 +
Das OWASP CRS (Core Rule Set) enthält die eigentlichen Standard-Regeln gegen typische Webangriffe. Es wird von GitHub geholt und aktiviert.
 
* In das ModSecurity-Verzeichnis wechseln
 
* In das ModSecurity-Verzeichnis wechseln
 
  cd /etc/nginx/modsecurity
 
  cd /etc/nginx/modsecurity
Zeile 27: Zeile 33:
  
 
== ModSecurity konfigurieren ==
 
== ModSecurity konfigurieren ==
 +
Die Hauptkonfiguration legt fest, dass ModSecurity Anfragen inspiziert und Logs schreibt. Außerdem wird das CRS eingebunden.
 
* Basis-Konfiguration /etc/nginx/modsecurity/modsecurity.conf
 
* Basis-Konfiguration /etc/nginx/modsecurity/modsecurity.conf
 
<pre>
 
<pre>
Zeile 53: Zeile 60:
  
 
== NGINX-Snippet ==
 
== NGINX-Snippet ==
 +
Damit ModSecurity aktiviert wird, bindet NGINX ein Snippet ein. Das erleichtert die Konfiguration in den VHosts.
 
Datei: /etc/nginx/modsecurity/main.conf
 
Datei: /etc/nginx/modsecurity/main.conf
 
<pre>
 
<pre>
Zeile 60: Zeile 68:
  
 
== NGINX-Site konfigurieren ==
 
== NGINX-Site konfigurieren ==
 +
Die Site-Definition sorgt dafür, dass HTTP auf HTTPS umgeleitet wird und alle Anfragen durch ModSecurity laufen. Zusätzlich wird ein Zugriff auf das Auditlog im Browser angeboten.
 
* Standard-VHost anpassen /etc/nginx/sites-available/default
 
* Standard-VHost anpassen /etc/nginx/sites-available/default
 
<pre>
 
<pre>
Zeile 65: Zeile 74:
 
server {
 
server {
 
     listen 80;
 
     listen 80;
     server_name localhost;
+
     server_name <server>;
 
     return 301 https://$host$request_uri;
 
     return 301 https://$host$request_uri;
 
}
 
}
Zeile 72: Zeile 81:
 
server {
 
server {
 
     listen 443 ssl;
 
     listen 443 ssl;
     server_name localhost;
+
     server_name <server>;
  
 
     ssl_certificate    /etc/nginx/fullchain.pem;
 
     ssl_certificate    /etc/nginx/fullchain.pem;
Zeile 111: Zeile 120:
  
 
== Logging ==
 
== Logging ==
 +
Logs sind wichtig, um Angriffe und Blockierungen nachzuvollziehen. Dazu werden Logformate und Rechte angepasst.
 
* Log-Format ergänzen (/etc/nginx/nginx.conf im http{}-Block)
 
* Log-Format ergänzen (/etc/nginx/nginx.conf im http{}-Block)
 
<pre>
 
<pre>
Zeile 137: Zeile 147:
 
</pre>
 
</pre>
  
== Zugriffsschutz für /_waflog ==
+
== Zugriff auf Audit-Log per Browser ==
* htpasswd installieren und User anlegen
+
Damit Teilnehmer ohne Shell-Zugriff das Log sehen können, wird es über eine URL abrufbar gemacht – geschützt durch Passwort.
 +
* Benutzerdatei anlegen
 
<pre>
 
<pre>
sudo apt install apache2-utils -y
 
 
sudo htpasswd -c /etc/nginx/.htpasswd admin
 
sudo htpasswd -c /etc/nginx/.htpasswd admin
 
</pre>
 
</pre>
 +
 +
* Aufruf im Browser
 +
https://<server>/_waflog 
 +
Benutzer: admin, Passwort wie vergeben
 +
 +
* Nutzen
 +
* Anzeige, welche Requests geblockt wurden (Regel-ID, URI, Methode)
 +
* Für Schulungen sofort sichtbar, warum eine Anfrage blockiert wurde
 +
* Auch ohne SSH-Zugang direkt im Browser nutzbar
  
 
== Whitelist-Policy ==
 
== Whitelist-Policy ==
 +
Standardmäßig prüfen die CRS-Regeln sehr viele Muster. Mit einer Whitelist-Policy wird das Verhalten verschärft: nur definierte Methoden und Pfade dürfen durch, alles andere wird geblockt.
 
* Datei mit erlaubten POST-URIs /etc/nginx/modsecurity/allowed_post_uris.txt
 
* Datei mit erlaubten POST-URIs /etc/nginx/modsecurity/allowed_post_uris.txt
 
<pre>
 
<pre>
Zeile 175: Zeile 195:
  
 
== Aktivierung ==
 
== Aktivierung ==
 +
Zum Schluss Konfiguration testen und NGINX neu laden.
 
<pre>
 
<pre>
 
sudo nginx -t
 
sudo nginx -t
Zeile 181: Zeile 202:
  
 
== Testbeispiele ==
 
== Testbeispiele ==
 +
Mit diesen Beispielen lässt sich prüfen, ob die Whitelist-Policy greift.
 
{| class="wikitable"
 
{| class="wikitable"
 
! Methode !! URI !! Erwartung
 
! Methode !! URI !! Erwartung
Zeile 194: Zeile 216:
  
 
== curl-Tests ==
 
== curl-Tests ==
 +
Die folgenden Befehle simulieren die Requests aus der Tabelle. <server> muss durch die IP oder den Hostnamen des Systems ersetzt werden.
 
<pre>
 
<pre>
 
# Erwartet 200 (erlaubter POST)
 
# Erwartet 200 (erlaubter POST)
curl -k -i -X POST https://localhost/safe/upload
+
curl -k -i -X POST https://<server>/safe/upload
  
 
# Erwartet 403 (POST nicht erlaubt)
 
# Erwartet 403 (POST nicht erlaubt)
curl -k -i -X POST https://localhost/badpath
+
curl -k -i -X POST https://<server>/badpath
  
 
# Erwartet 200 (erlaubtes GET)
 
# Erwartet 200 (erlaubtes GET)
curl -k -i https://localhost/safe/form
+
curl -k -i https://<server>/safe/form
  
 
# Erwartet 403 (GET nicht erlaubt)
 
# Erwartet 403 (GET nicht erlaubt)
curl -k -i https://localhost/admin
+
curl -k -i https://<server>/admin
 
</pre>
 
</pre>
  
 
== Audit-Log überwachen ==
 
== Audit-Log überwachen ==
 +
Um live zu sehen, welche Requests geblockt werden, kann das Audit-Log verfolgt werden.
 
<pre>
 
<pre>
 
sudo tail -f /var/log/nginx/modsec_audit.log
 
sudo tail -f /var/log/nginx/modsec_audit.log
Zeile 218: Zeile 242:
 
* Nur definierte Methoden und Pfade sind erlaubt, alle anderen Anfragen werden blockiert.
 
* Nur definierte Methoden und Pfade sind erlaubt, alle anderen Anfragen werden blockiert.
 
* Das Audit-Log unter /var/log/nginx/modsec_audit.log dokumentiert alle geblockten Requests.
 
* Das Audit-Log unter /var/log/nginx/modsec_audit.log dokumentiert alle geblockten Requests.
* Zugriff auf Audit-Log über Browser möglich: https://localhost/_waflog (mit Basic-Auth).
+
* Zugriff auf Audit-Log über Browser möglich: https://<server>/_waflog (mit Basic-Auth).
 
* Optional Debug-Log: /var/log/nginx/modsec_debug.log.
 
* Optional Debug-Log: /var/log/nginx/modsec_debug.log.
  
 
[[KATEGORIE:WAF]]
 
[[KATEGORIE:WAF]]

Version vom 28. August 2025, 19:14 Uhr

NGINX mit ModSecurity und Whitelist-Policy

Diese Anleitung zeigt den Aufbau einer Web Application Firewall mit NGINX und ModSecurity v3. Im ersten Schritt wird ModSecurity mit OWASP Core Rule Set (CRS) als Reverse Proxy aktiviert. Im zweiten Schritt folgt die Whitelist-Policy, bei der nur definierte Methoden und Pfade erlaubt sind. Alles andere wird standardmäßig blockiert.

Voraussetzungen

Bevor es losgeht, muss das System vorbereitet sein. Wir arbeiten hier mit Ubuntu 22.04 oder Debian 12, einem funktionierenden Backend (z. B. Web-App auf Port 8080) und internen TLS-Zertifikaten.

  • 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

Zunächst werden die benötigten Pakete installiert und ein Konfigurationsverzeichnis angelegt.

  • Pakete installieren
sudo apt update
sudo apt install nginx libmodsecurity3 libnginx-mod-http-modsecurity git apache2-utils -y
  • Verzeichnis für Konfiguration anlegen
sudo mkdir -p /etc/nginx/modsecurity

OWASP Core Rule Set installieren

Das OWASP CRS (Core Rule Set) enthält die eigentlichen Standard-Regeln gegen typische Webangriffe. Es wird von GitHub geholt und aktiviert.

  • In das ModSecurity-Verzeichnis wechseln
cd /etc/nginx/modsecurity
  • 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 konfigurieren

Die Hauptkonfiguration legt fest, dass ModSecurity Anfragen inspiziert und Logs schreibt. Außerdem wird das CRS eingebunden.

  • Basis-Konfiguration /etc/nginx/modsecurity/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 CRS laden
Include /etc/nginx/modsecurity/coreruleset/crs-setup.conf
Include /etc/nginx/modsecurity/coreruleset/rules/*.conf

NGINX-Snippet

Damit ModSecurity aktiviert wird, bindet NGINX ein Snippet ein. Das erleichtert die Konfiguration in den VHosts. Datei: /etc/nginx/modsecurity/main.conf

modsecurity on;
modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf;

NGINX-Site konfigurieren

Die Site-Definition sorgt dafür, dass HTTP auf HTTPS umgeleitet wird und alle Anfragen durch ModSecurity laufen. Zusätzlich wird ein Zugriff auf das Auditlog im Browser angeboten.

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

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

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

    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/modsecurity/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;
    }

    # Audit-Log im Browser abrufbar (Basic-Auth)
    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

Logs sind wichtig, um Angriffe und Blockierungen nachzuvollziehen. Dazu werden Logformate und Rechte angepasst.

  • 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
sudo touch /var/log/nginx/modsec_audit.log /var/log/nginx/modsec_debug.log
sudo chown www-data:adm /var/log/nginx/modsec_*.log
sudo chmod 640 /var/log/nginx/modsec_*.log
  • Fehlerseite anlegen /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>

Zugriff auf Audit-Log per Browser

Damit Teilnehmer ohne Shell-Zugriff das Log sehen können, wird es über eine URL abrufbar gemacht – geschützt durch Passwort.

  • Benutzerdatei anlegen
sudo htpasswd -c /etc/nginx/.htpasswd admin
  • Aufruf im Browser
https://<server>/_waflog  
Benutzer: admin, Passwort wie vergeben
  • Nutzen
  • Anzeige, welche Requests geblockt wurden (Regel-ID, URI, Methode)
  • Für Schulungen sofort sichtbar, warum eine Anfrage blockiert wurde
  • Auch ohne SSH-Zugang direkt im Browser nutzbar

Whitelist-Policy

Standardmäßig prüfen die CRS-Regeln sehr viele Muster. Mit einer Whitelist-Policy wird das Verhalten verschärft: nur definierte Methoden und Pfade dürfen durch, alles andere wird geblockt.

  • Datei mit erlaubten POST-URIs /etc/nginx/modsecurity/allowed_post_uris.txt
/safe/upload
/safe/form
/safe/login
  • Regelwerk /etc/nginx/modsecurity/custom-rules/default-deny.conf
# Erlaube POST nur für explizit freigegebene URIs
SecRule REQUEST_METHOD "@streq POST" "chain,id:2000,phase:1,deny,status:403,msg:'POST not allowed on this URI'"
    SecRule REQUEST_URI "!@pmFromFile /etc/nginx/modsecurity/allowed_post_uris.txt"

# Erlaube GET nur unterhalb von /safe/
SecRule REQUEST_METHOD "@streq GET" "chain,id:2001,phase:1,allow,log,skipAfter:ALLOWLIST_DONE"
    SecRule REQUEST_URI "@beginsWith /safe/"

# Marker
SecMarker ALLOWLIST_DONE

# Catch-All: alles andere blockieren
SecRule REQUEST_URI ".*" "id:2999,phase:1,deny,status:403,msg:'Blocked by default policy',skipAfter:ALLOWLIST_DONE"
  • Einbindung in /etc/nginx/modsecurity/modsecurity.conf
Include /etc/nginx/modsecurity/custom-rules/default-deny.conf

Aktivierung

Zum Schluss Konfiguration testen und NGINX neu laden.

sudo nginx -t
sudo systemctl reload nginx

Testbeispiele

Mit diesen Beispielen lässt sich prüfen, ob die Whitelist-Policy greift.

Methode URI Erwartung
POST /safe/upload 200 OK
POST /badpath 403 Forbidden
GET /safe/form 200 OK
GET /admin 403 Forbidden

curl-Tests

Die folgenden Befehle simulieren die Requests aus der Tabelle. <server> muss durch die IP oder den Hostnamen des Systems ersetzt werden.

# Erwartet 200 (erlaubter POST)
curl -k -i -X POST https://<server>/safe/upload

# Erwartet 403 (POST nicht erlaubt)
curl -k -i -X POST https://<server>/badpath

# Erwartet 200 (erlaubtes GET)
curl -k -i https://<server>/safe/form

# Erwartet 403 (GET nicht erlaubt)
curl -k -i https://<server>/admin

Audit-Log überwachen

Um live zu sehen, welche Requests geblockt werden, kann das Audit-Log verfolgt werden.

sudo tail -f /var/log/nginx/modsec_audit.log

Ergebnis

  • ModSecurity + CRS schützt vor typischen Angriffen.
  • Die Whitelist-Policy setzt zusätzlich eine Default-Deny-Strategie um.
  • Nur definierte Methoden und Pfade sind erlaubt, alle anderen Anfragen werden blockiert.
  • Das Audit-Log unter /var/log/nginx/modsec_audit.log dokumentiert alle geblockten Requests.
  • Zugriff auf Audit-Log über Browser möglich: https://<server>/_waflog (mit Basic-Auth).
  • Optional Debug-Log: /var/log/nginx/modsec_debug.log.