Nginx mit Modsecurity und Blocklost Policy
Zur Navigation springen
Zur Suche springen
NGINX mit ModSecurity und Blocklist-Policy
Diese Anleitung zeigt den Aufbau einer Web Application Firewall mit NGINX und ModSecurity v3 mit einer praxistauglichen Blocklist-Strategie.
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
sudo apt update
sudo apt install nginx libmodsecurity3 libnginx-mod-http-modsecurity git apache2-utils -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
Datei: /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
- sudo tee /etc/nginx/modsec/custom-rules/security-policy.conf > /dev/null <<EOF
# Security Policy: Blocklist + Default-Allow
# 1) 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}'"
# 2) ALLES ANDERE ERLAUBEN (wird von CRS geprüft)
SecRule REQUEST_URI ".*" \\
"id:2000,phase:1,pass,nolog"
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
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/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.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;
}
# 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;
}
}
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'\''"\$http_referer" "\$http_user_agent" '\''\\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
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
Audit-Log im Browser
# Benutzerdatei anlegen
sudo htpasswd -c /etc/nginx/.htpasswd admin
Aktivierung
# Syntax prüfen
sudo nginx -t
# Nginx neu laden
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