Nginx mit Modsecurity zusammen Whitelists: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
| Zeile 1: | Zeile 1: | ||
| − | = NGINX mit ModSecurity und Whitelist | + | = NGINX mit ModSecurity und Default-Deny-Whitelist = |
Diese Anleitung zeigt den Aufbau einer Web Application Firewall mit NGINX und ModSecurity v3. | Diese Anleitung zeigt den Aufbau einer Web Application Firewall mit NGINX und ModSecurity v3. | ||
| − | + | ModSecurity wird als Reverse Proxy aktiviert, das OWASP Core Rule Set (CRS) eingebunden und zusätzlich eine Whitelist-Policy eingerichtet. | |
| − | + | Dadurch gilt: **Alles ist standardmäßig verboten, nur definierte URIs (Whitelist) sind erlaubt.** | |
| − | Alles | ||
== Voraussetzungen == | == Voraussetzungen == | ||
| − | |||
* Ubuntu 22.04 oder Debian 12 | * Ubuntu 22.04 oder Debian 12 | ||
| − | * Backend | + | * Funktionierendes Backend (z. B. http://127.0.0.1:8080) |
* TLS-Zertifikate (crt.pem, privkey.pem, ca.crt) aus interner CA | * TLS-Zertifikate (crt.pem, privkey.pem, ca.crt) aus interner CA | ||
== Installation == | == Installation == | ||
| − | |||
* Pakete installieren | * Pakete installieren | ||
sudo apt update | sudo apt update | ||
sudo apt install nginx libmodsecurity3 libnginx-mod-http-modsecurity git apache2-utils -y | sudo apt install nginx libmodsecurity3 libnginx-mod-http-modsecurity git apache2-utils -y | ||
| − | * | + | * Verzeichnisstruktur anlegen |
| − | sudo mkdir -p /etc/nginx/ | + | sudo mkdir -p /etc/nginx/modsec/custom-rules |
== OWASP Core Rule Set installieren == | == OWASP Core Rule Set installieren == | ||
| − | |||
* In das ModSecurity-Verzeichnis wechseln | * In das ModSecurity-Verzeichnis wechseln | ||
| − | cd /etc/nginx/ | + | cd /etc/nginx/modsec |
* CRS klonen | * CRS klonen | ||
| Zeile 33: | Zeile 29: | ||
== ModSecurity konfigurieren == | == ModSecurity konfigurieren == | ||
| − | + | Datei: /etc/nginx/modsec/modsecurity.conf | |
| − | |||
<pre> | <pre> | ||
SecRuleEngine On | SecRuleEngine On | ||
| Zeile 43: | Zeile 38: | ||
SecAuditLog /var/log/nginx/modsec_audit.log | SecAuditLog /var/log/nginx/modsec_audit.log | ||
SecAuditLogParts ABIJDEFHZ | SecAuditLogParts ABIJDEFHZ | ||
| − | |||
| − | |||
| − | |||
SecTmpDir /tmp/ | SecTmpDir /tmp/ | ||
SecDataDir /tmp/ | SecDataDir /tmp/ | ||
| − | # | + | # Erst unsere Whitelist/Default-Deny laden |
| − | SecRule | + | Include /etc/nginx/modsec/custom-rules/default-deny.conf |
| − | "id: | + | |
| + | # Danach CRS – wirkt nur auf NICHT-Whitelist-URIs | ||
| + | Include /etc/nginx/modsec/coreruleset/crs-setup.conf | ||
| + | Include /etc/nginx/modsec/coreruleset/rules/*.conf | ||
| + | </pre> | ||
| + | |||
| + | == Whitelist-Policy == | ||
| + | * Datei mit erlaubten URIs /etc/nginx/modsec/allowed_uris.txt | ||
| + | <pre> | ||
| + | /upload | ||
| + | </pre> | ||
| + | |||
| + | * Regelwerk /etc/nginx/modsec/custom-rules/default-deny.conf | ||
| + | <pre> | ||
| + | # Whitelist: URIs aus Datei von Inspektion ausnehmen (inkl. CRS) | ||
| + | SecRule REQUEST_URI "@pmFromFile /etc/nginx/modsec/allowed_uris.txt" \ | ||
| + | "id:2000,phase:1,pass,log,ctl:ruleEngine=Off" | ||
| − | # | + | # Default-Deny: alles andere blockieren |
| − | + | SecRule REQUEST_URI ".*" \ | |
| − | + | "id:2999,phase:1,deny,status:403,log,msg:'Default deny policy'" | |
</pre> | </pre> | ||
== NGINX-Snippet == | == NGINX-Snippet == | ||
| − | + | Datei: /etc/nginx/modsec/main.conf | |
| − | Datei: /etc/nginx/ | ||
<pre> | <pre> | ||
modsecurity on; | modsecurity on; | ||
| − | modsecurity_rules_file /etc/nginx/ | + | modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf; |
</pre> | </pre> | ||
== NGINX-Site konfigurieren == | == NGINX-Site konfigurieren == | ||
| − | + | Datei: /etc/nginx/sites-available/default | |
| − | |||
<pre> | <pre> | ||
| − | |||
server { | server { | ||
listen 80; | listen 80; | ||
| Zeile 78: | Zeile 83: | ||
} | } | ||
| − | |||
server { | server { | ||
listen 443 ssl; | listen 443 ssl; | ||
| Zeile 89: | Zeile 93: | ||
error_log /var/log/nginx/error.log warn; | error_log /var/log/nginx/error.log warn; | ||
| − | + | include /etc/nginx/modsec/main.conf; | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | include /etc/nginx/ | ||
location / { | location / { | ||
| Zeile 120: | Zeile 115: | ||
== Logging == | == Logging == | ||
| − | |||
* 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 131: | Zeile 125: | ||
* Log-Dateien anlegen | * Log-Dateien anlegen | ||
<pre> | <pre> | ||
| − | sudo touch /var/log/nginx/modsec_audit | + | sudo touch /var/log/nginx/modsec_audit.log |
| − | sudo chown www-data:adm /var/log/nginx/ | + | sudo chown www-data:adm /var/log/nginx/modsec_audit.log |
| − | sudo chmod 640 /var/log/nginx/ | + | sudo chmod 640 /var/log/nginx/modsec_audit.log |
</pre> | </pre> | ||
| − | + | == Fehlerseite == | |
| + | /var/www/html/403.html | ||
<pre> | <pre> | ||
<html> | <html> | ||
<head><title>403 Forbidden</title></head> | <head><title>403 Forbidden</title></head> | ||
<body> | <body> | ||
| − | <h1> | + | <h1>Zugriff verweigert</h1> |
<p>Deine Anfrage wurde von der Web Application Firewall blockiert.</p> | <p>Deine Anfrage wurde von der Web Application Firewall blockiert.</p> | ||
</body> | </body> | ||
| Zeile 147: | Zeile 142: | ||
</pre> | </pre> | ||
| − | == | + | == Audit-Log im Browser == |
| − | |||
* Benutzerdatei anlegen | * Benutzerdatei anlegen | ||
| − | + | sudo htpasswd -c /etc/nginx/.htpasswd admin | |
| − | sudo htpasswd -c /etc/nginx/.htpasswd admin | ||
| − | |||
| − | * Aufruf | + | * Aufruf |
| − | https://<server>/_waflog | + | https://<server>/_waflog |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
== Aktivierung == | == Aktivierung == | ||
| − | + | * Syntax prüfen | |
| − | + | sudo nginx -t | |
| − | sudo nginx -t | + | * Reload |
| − | sudo systemctl reload nginx | + | sudo systemctl reload nginx |
| − | |||
== Testbeispiele == | == Testbeispiele == | ||
| − | |||
{| class="wikitable" | {| class="wikitable" | ||
! Methode !! URI !! Erwartung | ! Methode !! URI !! Erwartung | ||
|- | |- | ||
| − | | POST || | + | | POST || /upload || 200 OK |
|- | |- | ||
| − | | | + | | GET || /upload || 200 OK |
|- | |- | ||
| − | | GET || / | + | | GET || /admin || 403 Forbidden |
|- | |- | ||
| − | | | + | | POST || /bad || 403 Forbidden |
|} | |} | ||
| − | + | == Audit-Log verfolgen == | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | == Audit-Log | ||
| − | |||
<pre> | <pre> | ||
sudo tail -f /var/log/nginx/modsec_audit.log | sudo tail -f /var/log/nginx/modsec_audit.log | ||
| Zeile 238: | Zeile 174: | ||
== Ergebnis == | == Ergebnis == | ||
| − | * | + | * CRS schützt vor typischen Angriffen auf nicht-Whitelist-URIs |
| − | * | + | * Default-Deny blockt alles, was nicht explizit erlaubt ist |
| − | * | + | * Whitelist erlaubt gezielt z. B. `/upload` |
| − | * | + | * Audit-Log zeigt geblockte Requests |
| − | |||
| − | |||
| − | |||
| − | |||
Aktuelle Version vom 5. September 2025, 07:31 Uhr
NGINX mit ModSecurity und Default-Deny-Whitelist
Diese Anleitung zeigt den Aufbau einer Web Application Firewall mit NGINX und ModSecurity v3. ModSecurity wird als Reverse Proxy aktiviert, das OWASP Core Rule Set (CRS) eingebunden und zusätzlich eine Whitelist-Policy eingerichtet. Dadurch gilt: **Alles ist standardmäßig verboten, nur definierte URIs (Whitelist) sind erlaubt.**
Voraussetzungen
- Ubuntu 22.04 oder Debian 12
- Funktionierendes Backend (z. B. http://127.0.0.1:8080)
- 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
- Verzeichnisstruktur anlegen
sudo mkdir -p /etc/nginx/modsec/custom-rules
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 konfigurieren
Datei: /etc/nginx/modsec/modsecurity.conf
SecRuleEngine On SecRequestBodyAccess On SecResponseBodyAccess Off SecAuditEngine RelevantOnly SecAuditLog /var/log/nginx/modsec_audit.log SecAuditLogParts ABIJDEFHZ SecTmpDir /tmp/ SecDataDir /tmp/ # Erst unsere Whitelist/Default-Deny laden Include /etc/nginx/modsec/custom-rules/default-deny.conf # Danach CRS – wirkt nur auf NICHT-Whitelist-URIs Include /etc/nginx/modsec/coreruleset/crs-setup.conf Include /etc/nginx/modsec/coreruleset/rules/*.conf
Whitelist-Policy
- Datei mit erlaubten URIs /etc/nginx/modsec/allowed_uris.txt
/upload
- Regelwerk /etc/nginx/modsec/custom-rules/default-deny.conf
# Whitelist: URIs aus Datei von Inspektion ausnehmen (inkl. CRS)
SecRule REQUEST_URI "@pmFromFile /etc/nginx/modsec/allowed_uris.txt" \
"id:2000,phase:1,pass,log,ctl:ruleEngine=Off"
# Default-Deny: alles andere blockieren
SecRule REQUEST_URI ".*" \
"id:2999,phase:1,deny,status:403,log,msg:'Default deny policy'"
NGINX-Snippet
Datei: /etc/nginx/modsec/main.conf
modsecurity on; modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
NGINX-Site konfigurieren
Datei: /etc/nginx/sites-available/default
server {
listen 80;
server_name <server>;
return 301 https://$host$request_uri;
}
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;
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;
}
# 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
- 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 sudo chown www-data:adm /var/log/nginx/modsec_audit.log sudo chmod 640 /var/log/nginx/modsec_audit.log
Fehlerseite
/var/www/html/403.html
<html> <head><title>403 Forbidden</title></head> <body> <h1>Zugriff verweigert</h1> <p>Deine Anfrage wurde von der Web Application Firewall blockiert.</p> </body> </html>
Audit-Log im Browser
- Benutzerdatei anlegen
sudo htpasswd -c /etc/nginx/.htpasswd admin
- Aufruf
https://<server>/_waflog
Aktivierung
- Syntax prüfen
sudo nginx -t
- Reload
sudo systemctl reload nginx
Testbeispiele
| Methode | URI | Erwartung |
|---|---|---|
| POST | /upload | 200 OK |
| GET | /upload | 200 OK |
| GET | /admin | 403 Forbidden |
| POST | /bad | 403 Forbidden |
Audit-Log verfolgen
sudo tail -f /var/log/nginx/modsec_audit.log
Ergebnis
- CRS schützt vor typischen Angriffen auf nicht-Whitelist-URIs
- Default-Deny blockt alles, was nicht explizit erlaubt ist
- Whitelist erlaubt gezielt z. B. `/upload`
- Audit-Log zeigt geblockte Requests