Nginx mit Modsecurity Whitelists: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „ == Voraussetzungen == * Webserver mit ModSecurity (z. B. NGINX + ModSecurity v3) * OWASP CRS kann verwendet werden, aber nicht erforderlich * Pfad zur Haupt…“)
 
 
Zeile 1: Zeile 1:
 +
= ModSecurity Default-Deny-Policy =
  
 
== Voraussetzungen ==
 
== Voraussetzungen ==
* Webserver mit ModSecurity (z. B. NGINX + ModSecurity v3)
+
* NGINX mit ModSecurity v3
* OWASP CRS kann verwendet werden, aber nicht erforderlich
+
* Hauptkonfigurationsdatei: /etc/nginx/modsec/modsecurity.conf
* Pfad zur Hauptregeldatei z. B.: /etc/modsecurity/main.conf
+
* Eigene Regeln liegen in: /etc/nginx/modsec/custom-rules/
  
 
== Ziel ==
 
== Ziel ==
* Nur definierte Methoden und Pfade zulassen
+
* Default-Deny: Alles ist verboten
* Alles andere standardmäßig ablehnen
+
* Nur explizit definierte URIs für bestimmte Methoden sind erlaubt
* Pfad-Whitelist aus externer Datei laden
+
* Whitelist aus externen Dateien geladen
  
== Datei mit erlaubten URIs ==
+
== Allowlist-Dateien ==
Pfad: /etc/modsecurity/allowed_post_uris.txt
 
  
Inhalt:
+
/etc/nginx/modsec/allowed_post_uris.txt
/safe/upload
+
---------------------------------------
/safe/form
+
/safe/upload
/safe/login
+
/safe/form
 +
/safe/login
  
== Regelwerk (Whitelist-Ansatz) ==
+
/etc/nginx/modsec/allowed_get_prefixes.txt
Datei: /etc/modsecurity/custom-rules/default-deny.conf
+
------------------------------------------
 +
/safe/
 +
/assets/
 +
/static/
 +
 
 +
== Eigene Regeln ==
 +
Datei: /etc/nginx/modsec/custom-rules/default-deny.conf
  
 
<pre>
 
<pre>
# Erlaube POST nur für explizit freigegebene URIs
+
# POST nur auf URIs aus Datei erlauben
SecRule REQUEST_METHOD "@streq POST" "chain,id:2000,phase:1,deny,status:403,msg:'POST not allowed on this URI'"
+
SecRule REQUEST_METHOD "@streq POST" \
     SecRule REQUEST_URI "!@pmFromFile /etc/modsecurity/allowed_post_uris.txt"
+
    "id:2000,phase:1,allow,log,skipAfter:ALLOWLIST_DONE,chain"
 +
     SecRule REQUEST_URI "@pmFromFile /etc/nginx/modsec/allowed_post_uris.txt"
  
# Erlaube GET auf bestimmte Pfade
+
# GET nur auf Präfixe aus Datei erlauben
SecRule REQUEST_METHOD "@streq GET" "chain,id:2001,phase:1,pass,nolog,ctl:ruleEngine=Off"
+
SecRule REQUEST_METHOD "@streq GET" \
     SecRule REQUEST_URI "@beginsWith /safe/"
+
    "id:2001,phase:1,allow,log,skipAfter:ALLOWLIST_DONE,chain"
 +
     SecRule REQUEST_URI "@pmFromFile /etc/nginx/modsec/allowed_get_prefixes.txt" "chain,capture"
 +
    SecRule REQUEST_URI "@beginsWith %{MATCHED_VAR}"
  
# Optional: weitere erlaubte Methoden einfügen
+
# Alles andere blockieren (Default-Deny)
# z. B. HEAD, OPTIONS, PUT usw. je nach Bedarf
+
SecRule REQUEST_URI ".*" \
 +
    "id:2999,phase:1,deny,status:403,log,msg:'Default deny policy'"
  
# Marker zur Trennung von Erlaubnis und Default-Ablehnung
+
# Marker für SkipAfter
 
SecMarker ALLOWLIST_DONE
 
SecMarker ALLOWLIST_DONE
 
# Alles andere wird abgelehnt
 
SecRule REQUEST_URI ".*" "id:2999,phase:1,deny,status:403,msg:'Blocked by default policy',skipAfter:ALLOWLIST_DONE"
 
 
</pre>
 
</pre>
  
== Einbindung in Hauptregeldatei ==
+
== Hauptkonfiguration ==
Pfad: /etc/modsecurity/main.conf
+
Datei: /etc/nginx/modsec/modsecurity.conf
  
 
<pre>
 
<pre>
# Optional: OWASP CRS laden
+
SecRuleEngine On
Include /usr/share/modsecurity-crs/crs-setup.conf
+
SecRequestBodyAccess On
Include /usr/share/modsecurity-crs/rules/*.conf
+
SecResponseBodyAccess Off
 +
 
 +
# Optionale CRS-Regeln (nur wenn gewünscht)
 +
#Include /usr/share/modsecurity-crs/crs-setup.conf
 +
#Include /usr/share/modsecurity-crs/rules/*.conf
  
# Eigene Regeln einbinden
+
# Eigene Default-Deny-Policy laden
Include /etc/modsecurity/custom-rules/default-deny.conf
+
Include /etc/nginx/modsec/custom-rules/default-deny.conf
 
</pre>
 
</pre>
  
== NGINX-Integration ==
+
== NGINX-Einbindung ==
In der vHost-Konfiguration oder nginx.conf:
+
In der vHost- oder http/server/location-Konfiguration:
  
 
<pre>
 
<pre>
 
modsecurity on;
 
modsecurity on;
modsecurity_rules_file /etc/modsecurity/main.conf;
+
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
 
</pre>
 
</pre>
  
 
== Neustart / Reload ==
 
== Neustart / Reload ==
* systemctl reload nginx
+
* Syntaxprüfung: nginx -t
* Fehlerprüfung mit: nginx -t
+
* Reload: systemctl reload nginx
  
== Testbeispiele ==
+
== Testfälle ==
 
{| class="wikitable"
 
{| class="wikitable"
 
! Methode !! URI !! Erwartung
 
! Methode !! URI !! Erwartung
Zeile 72: Zeile 84:
 
| POST || /badpath || 403 Forbidden
 
| POST || /badpath || 403 Forbidden
 
|-
 
|-
| GET || /safe/form || 200 OK
+
| GET || /safe/test || 200 OK
 
|-
 
|-
 
| GET || /admin || 403 Forbidden
 
| GET || /admin || 403 Forbidden
 
|}
 
|}
 
== Hinweise ==
 
* @pmFromFile lädt zeilenweise rohe Pfadstrings ohne Regex.
 
* Jede Methode (POST, GET, PUT, ...) benötigt eigene Allow-Regel.
 
* Die Catch-All-Regel am Ende macht daraus eine echte Default-Deny-Policy.
 
* Die Regel-ID 2999 muss höher sein als alle anderen.
 
 
== Erweiterung ==
 
* Cookie-Integritätsschutz: REQUEST_COOKIES validieren
 
* CSRF-Token-Validierung über eigene Variablen
 
* Separate Whitelist-Dateien für verschiedene Methoden
 
 
== Fazit ==
 
Diese Konfiguration erreicht eine vergleichbare Zugriffskontrolle wie die Sophos XG Webserver Protection – vollständig transparent, erweiterbar und ohne GUI-Zwang.
 

Aktuelle Version vom 5. September 2025, 07:13 Uhr

ModSecurity Default-Deny-Policy

Voraussetzungen

  • NGINX mit ModSecurity v3
  • Hauptkonfigurationsdatei: /etc/nginx/modsec/modsecurity.conf
  • Eigene Regeln liegen in: /etc/nginx/modsec/custom-rules/

Ziel

  • Default-Deny: Alles ist verboten
  • Nur explizit definierte URIs für bestimmte Methoden sind erlaubt
  • Whitelist aus externen Dateien geladen

Allowlist-Dateien

/etc/nginx/modsec/allowed_post_uris.txt


/safe/upload /safe/form /safe/login

/etc/nginx/modsec/allowed_get_prefixes.txt


/safe/ /assets/ /static/

Eigene Regeln

Datei: /etc/nginx/modsec/custom-rules/default-deny.conf

# POST nur auf URIs aus Datei erlauben
SecRule REQUEST_METHOD "@streq POST" \
    "id:2000,phase:1,allow,log,skipAfter:ALLOWLIST_DONE,chain"
    SecRule REQUEST_URI "@pmFromFile /etc/nginx/modsec/allowed_post_uris.txt"

# GET nur auf Präfixe aus Datei erlauben
SecRule REQUEST_METHOD "@streq GET" \
    "id:2001,phase:1,allow,log,skipAfter:ALLOWLIST_DONE,chain"
    SecRule REQUEST_URI "@pmFromFile /etc/nginx/modsec/allowed_get_prefixes.txt" "chain,capture"
    SecRule REQUEST_URI "@beginsWith %{MATCHED_VAR}"

# Alles andere blockieren (Default-Deny)
SecRule REQUEST_URI ".*" \
    "id:2999,phase:1,deny,status:403,log,msg:'Default deny policy'"

# Marker für SkipAfter
SecMarker ALLOWLIST_DONE

Hauptkonfiguration

Datei: /etc/nginx/modsec/modsecurity.conf

SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off

# Optionale CRS-Regeln (nur wenn gewünscht)
#Include /usr/share/modsecurity-crs/crs-setup.conf
#Include /usr/share/modsecurity-crs/rules/*.conf

# Eigene Default-Deny-Policy laden
Include /etc/nginx/modsec/custom-rules/default-deny.conf

NGINX-Einbindung

In der vHost- oder http/server/location-Konfiguration:

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

Neustart / Reload

  • Syntaxprüfung: nginx -t
  • Reload: systemctl reload nginx

Testfälle

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