Nginx mit Modsecurity und Blocklost Policy: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
Weiterleitung: Tippfehler im Titel, konsolidiert
Markierung: Neue Weiterleitung
 
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

Aktuelle Version vom 31. Oktober 2026, 15:15 Uhr