Waf - Nginx mit Modsecurity und Blocklist
Version vom 30. April 2026, 12:53 Uhr von Thomas.will (Diskussion | Beiträge) (→ModSecurity konfigurieren)
Was machen wir
Diese Anleitung zeigt den Aufbau einer Web Application Firewall mit NGINX und ModSecurity v3 mit einer praxistauglichen Blocklist-Strategie.
Voraussetzungen
- Ubuntu 24.04 oder Debian 13
- Funktionierendes Backend (z. B. http://127.0.0.1:8080)
- TLS-Zertifikate (
/etc/ssl/own.crt,/etc/ssl/own.key)
Installation
sudo apt update
sudo apt install nginx libmodsecurity3 libnginx-mod-http-modsecurity git -y
sudo mkdir -p /etc/nginx/modsec/custom-rules
OWASP Core Rule Set installieren
cd /etc/nginx/modsec
sudo git clone https://github.com/coreruleset/coreruleset.git
sudo cp coreruleset/crs-setup.conf.example coreruleset/crs-setup.conf
Blocklist erstellen
sudo tee /etc/nginx/modsec/blocked_uris.txt > /dev/null <<EOF
/admin
/wp-admin
/administrator
/backup
/config
/database
/phpmyadmin
/mysql
/server-status
/.env
/.git
/wp-login.php
/login-bypass
EOF
ModSecurity konfigurieren
- vi
/etc/nginx/modsec/modsecurity.conf
sudo tee /etc/nginx/modsec/modsecurity.conf > /dev/null <<EOF
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off
SecAuditEngine RelevantOnly
SecAuditLog /var/log/nginx/modsec_audit.log
SecAuditLogParts ABIJDEFHZ
SecTmpDir /tmp/
SecDataDir /tmp/
# Zuerst CRS – wirkt auf ALLE Requests
Include /etc/nginx/modsec/coreruleset/crs-setup.conf
Include /etc/nginx/modsec/coreruleset/rules/*.conf
# Danach unsere Security Policy (Blocklist)
Include /etc/nginx/modsec/custom-rules/security-policy.conf
EOF
Security Policy (Blocklist)
Datei: /etc/nginx/modsec/custom-rules/security-policy.conf
Was nicht durch die Blocklist oder den CRS geblockt wird, passiert durch – ein explizites Erlauben ist nicht notwendig.
sudo tee /etc/nginx/modsec/custom-rules/security-policy.conf > /dev/null <<EOF
# Security Policy: Blocklist + Default-Allow
# Kritische Pfade explizit blockieren (Phase 1)
SecRule REQUEST_URI "@pmFromFile /etc/nginx/modsec/blocked_uris.txt" \
"id:1999,phase:1,deny,status:403,log,msg:'Blocked path detected: %{MATCHED_VAR}'"
EOF
NGINX-Snippet
Datei: /etc/nginx/modsec/main.conf
sudo tee /etc/nginx/modsec/main.conf > /dev/null <<EOF
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
EOF
Logging
# Log-Format ergänzen (/etc/nginx/nginx.conf im http{}-Block)
sudo sed -i '/http {/a\\tlog_format waf_combined '\''$remote_addr - $remote_user [$time_local] '\''\n\t\t\t\t\t'\''"$request" $status $body_bytes_sent '\''\n\t\t\t\t\t'\''ModSecID=$request_id Host="$host" URI="$request_uri"'\'';' /etc/nginx/nginx.conf
# 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
NGINX-Site konfigurieren
Datei: /etc/nginx/sites-available/default
sudo tee /etc/nginx/sites-available/default > /dev/null <<EOF
server {
listen 80;
server_name _;
return 301 https://\$host\$request_uri;
}
server {
listen 443 ssl;
server_name _;
ssl_certificate /etc/ssl/own.crt;
ssl_certificate_key /etc/ssl/own.key;
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;
}
}
EOF
Fehlerseite
sudo tee /var/www/html/403.html > /dev/null <<EOF
<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>
EOF
Aktivierung
sudo nginx -t
sudo systemctl reload nginx
Testbeispiele
| Methode | URI | Erwartung |
|---|---|---|
| GET | / | 200 OK |
| GET | /admin | 403 Forbidden |
| GET | /wp-admin | 403 Forbidden |
| POST | /upload | 200 OK (wenn erlaubt) |
Audit-Log verfolgen
sudo tail -f /var/log/nginx/modsec_audit.log
Ergebnis
- CRS schützt vor typischen Angriffen auf alle Requests
- Blocklist blockiert explizit kritische Pfade
- Default-Allow ermöglicht normale Seiten-Nutzung
- Minimaler Wartungsaufwand durch Blocklist-Ansatz