|
|
| Zeile 1: |
Zeile 1: |
| = NGINX mit ModSecurity und Blocklist-Policy =
| | #WEITERLEITUNG [[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 ==
| |
| <syntaxhighlight lang="bash">
| |
| sudo apt update
| |
| sudo apt install nginx libmodsecurity3 libnginx-mod-http-modsecurity git apache2-utils -y
| |
| | |
| sudo mkdir -p /etc/nginx/modsec/custom-rules
| |
| </syntaxhighlight>
| |
| | |
| == OWASP Core Rule Set installieren ==
| |
| <syntaxhighlight lang="bash">
| |
| cd /etc/nginx/modsec
| |
| sudo git clone https://github.com/coreruleset/coreruleset.git
| |
| sudo cp coreruleset/crs-setup.conf.example coreruleset/crs-setup.conf
| |
| </syntaxhighlight>
| |
| | |
| == Blocklist erstellen ==
| |
| <syntaxhighlight lang="bash">
| |
| 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
| |
| </syntaxhighlight>
| |
| | |
| == ModSecurity konfigurieren ==
| |
| Datei: <code>/etc/nginx/modsec/modsecurity.conf</code>
| |
| *sudo tee /etc/nginx/modsec/modsecurity.conf > /dev/null <<EOF
| |
| <syntaxhighlight lang="bash">
| |
| 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
| |
| </syntaxhighlight>
| |
| | |
| == Security Policy (Blocklist) ==
| |
| Datei: <code>/etc/nginx/modsec/custom-rules/security-policy.conf</code>
| |
| *sudo tee /etc/nginx/modsec/custom-rules/security-policy.conf > /dev/null <<EOF
| |
| <syntaxhighlight lang="bash">
| |
| # 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
| |
| </syntaxhighlight>
| |
| | |
| == NGINX-Snippet ==
| |
| Datei: <code>/etc/nginx/modsec/main.conf</code>
| |
| *sudo tee /etc/nginx/modsec/main.conf > /dev/null <<EOF
| |
| <syntaxhighlight lang="bash">
| |
| modsecurity on;
| |
| modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
| |
| EOF
| |
| </syntaxhighlight>
| |
| | |
| == NGINX-Site konfigurieren ==
| |
| Datei: <code>/etc/nginx/sites-available/default</code>
| |
| *sudo tee /etc/nginx/sites-available/default > /dev/null <<EOF
| |
| <syntaxhighlight lang="bash">
| |
| | |
| 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
| |
| </syntaxhighlight>
| |
| | |
| == Logging ==
| |
| <syntaxhighlight lang="bash">
| |
| # 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
| |
| </syntaxhighlight>
| |
| | |
| == Fehlerseite ==
| |
| <syntaxhighlight lang="bash">
| |
| 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
| |
| </syntaxhighlight>
| |
| | |
| == Audit-Log im Browser ==
| |
| <syntaxhighlight lang="bash">
| |
| # Benutzerdatei anlegen
| |
| sudo htpasswd -c /etc/nginx/.htpasswd admin
| |
| </syntaxhighlight>
| |
| | |
| == Aktivierung ==
| |
| <syntaxhighlight lang="bash">
| |
| # Syntax prüfen
| |
| sudo nginx -t
| |
| | |
| # Nginx neu laden
| |
| sudo systemctl reload nginx
| |
| </syntaxhighlight>
| |
| | |
| == Testbeispiele ==
| |
| {| class="wikitable"
| |
| ! Methode !! URI !! Erwartung
| |
| |-
| |
| | GET || / || 200 OK
| |
| |-
| |
| | GET || /admin || 403 Forbidden
| |
| |-
| |
| | GET || /wp-admin || 403 Forbidden
| |
| |-
| |
| | POST || /upload || 200 OK (wenn erlaubt)
| |
| |}
| |
| | |
| == Audit-Log verfolgen ==
| |
| <syntaxhighlight lang="bash">
| |
| sudo tail -f /var/log/nginx/modsec_audit.log
| |
| </syntaxhighlight>
| |
| | |
| == 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
| |