|
|
| Zeile 1: |
Zeile 1: |
| = NGINX mit ModSecurity und Default-Deny-Whitelist =
| | #WEITERLEITUNG [[Nginx mit Modsecurity Whitelists]] |
| | |
| 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
| |
| <pre>
| |
| 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
| |
| </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>
| |
| | |
| == NGINX-Snippet ==
| |
| Datei: /etc/nginx/modsec/main.conf
| |
| <pre>
| |
| modsecurity on;
| |
| modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
| |
| </pre>
| |
| | |
| == NGINX-Site konfigurieren ==
| |
| Datei: /etc/nginx/sites-available/default
| |
| <pre>
| |
| 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;
| |
| }
| |
| }
| |
| </pre>
| |
| | |
| == Logging ==
| |
| * Log-Format ergänzen (/etc/nginx/nginx.conf im http{}-Block)
| |
| <pre>
| |
| 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"';
| |
| </pre>
| |
| | |
| * Log-Dateien anlegen
| |
| <pre>
| |
| 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
| |
| </pre>
| |
| | |
| == Fehlerseite ==
| |
| /var/www/html/403.html
| |
| <pre>
| |
| <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>
| |
| </pre>
| |
| | |
| == 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 ==
| |
| {| class="wikitable"
| |
| ! Methode !! URI !! Erwartung
| |
| |-
| |
| | POST || /upload || 200 OK
| |
| |-
| |
| | GET || /upload || 200 OK
| |
| |-
| |
| | GET || /admin || 403 Forbidden
| |
| |-
| |
| | POST || /bad || 403 Forbidden
| |
| |}
| |
| | |
| == Audit-Log verfolgen ==
| |
| <pre>
| |
| sudo tail -f /var/log/nginx/modsec_audit.log
| |
| </pre>
| |
| | |
| == 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
| |