Sichere Dein Apache mit mod_security
Version 1.0
Author: Falko Timme <ft [at] falkotimme [dot] com>
Diese Anleitung veranschaulicht, wie man mod_security installiert und konfiguriert. mod_security ist ein Apache Modul (für Apache 1 und 2), das Einbruchserkennung und ~prävention für Web Anwendungen bereitstellt. Web Anwendungen sollen von bekannten und unbekannten Attacken, wie zum Beispiel SQL Injection Attacks, Cross-Site Scripging, Path Traversal Attacks etc. geschützt werden.
Im ersten Kapitel werde ich zeigen, wie man mod_security auf Debian Sarge, Ubuntu 6.06 LTS (Dapper Drake) und auf Fedora Core 5 installiert. Das zweite Kapitel veranschaulicht dann wie man Apache für mod_security konfiguriert, was völlig unabhängig von der Distribution ist, die Du verwendest.
Ich möchte an dieser Stelle darauf hinweisen, dass dies nicht der einzige Weg ist, ein solches System einzurichten. Es gibt viele Möglichkeiten dieses Ziel zu erreichen – dies ist der Weg, den ich gewählt habe. Ich übernehme keine Garantie, dass dies auch bei Dir funktioniert!
1 Installation
1.1 Debian Sarge
mod_security ist in den Standard-Paketdatenbanken als Debian Paket verfügbar, daher ist die Installation sehr einfach:
apt-get install libapache2-mod-security
a2enmod mod-security
/etc/init.d/apache2 force-reload
1.2 Ubuntu 6.06 LTS (Dapper Drake)
Die Installation ist genau die gleiche wie auf Debian Sarge:
apt-get install libapache2-mod-security
a2enmod mod-security
/etc/init.d/apache2 force-reload
1.3 Fedora Core 5
Auf Fedora kannst Du mod_security wie folgt installieren und aktivieren:
yum install mod_security
/etc/init.d/httpd restart
Du müsstest nun die Datei /etc/httpd/conf.d/mod_security.conf finden, die bereits eine Basis- mod_security Konfiguration enthält:
vi /etc/httpd/conf.d/mod_security.conf
# Example configuration file for the mod_security Apache module
LoadModule security_module modules/mod_security.so
<IfModule mod_security.c>
# Turn the filtering engine On or Off
SecFilterEngine On
# The audit engine works independently and
# can be turned On of Off on the per-server or
# on the per-directory basis
SecAuditEngine RelevantOnly
# Make sure that URL encoding is valid
SecFilterCheckURLEncoding On
# Unicode encoding check
SecFilterCheckUnicodeEncoding On
# Only allow bytes from this range
SecFilterForceByteRange 1 255
# Cookie format checks.
SecFilterCheckCookieFormat On
# The name of the audit log file
SecAuditLog logs/audit_log
# Should mod_security inspect POST payloads
SecFilterScanPOST On
# Default action set
SecFilterDefaultAction "deny,log,status:406"
# Simple example filter
# SecFilter 111
# Prevent path traversal (..) attacks
# SecFilter "../"
# Weaker XSS protection but allows common HTML tags
# SecFilter "<( |n)*script"
# Prevent XSS atacks (HTML/Javascript injection)
# SecFilter "<(.|n)+>"
# Very crude filters to prevent SQL injection attacks
# SecFilter "delete[[:space:]]+from"
# SecFilter "insert[[:space:]]+into"
# SecFilter "select.+from"
# Require HTTP_USER_AGENT and HTTP_HOST headers
SecFilterSelective "HTTP_USER_AGENT|HTTP_HOST" "^$"
# Only accept request encodings we know how to handle
# we exclude GET requests from this because some (automated)
# clients supply "text/html" as Content-Type
SecFilterSelective REQUEST_METHOD "!^GET$" chain
SecFilterSelective HTTP_Content-Type "!(^$|^application/x-www-form-urlencoded$|^multipart/form-data)"
# Require Content-Length to be provided with
# every POST request
SecFilterSelective REQUEST_METHOD "^POST$" chain
SecFilterSelective HTTP_Content-Length "^$"
# Don't accept transfer encodings we know we don't handle
# (and you don't need it anyway)
SecFilterSelective HTTP_Transfer-Encoding "!^$"
# Some common application-related rules from
# http://modsecrules.monkeydev.org/rules.php?safety=safe
#Nuke Bookmarks XSS
SecFilterSelective THE_REQUEST "/modules.php?name=Bookmarks&file=(del_cat&catname|del_mark&markname|edit_cat&catname|edit_cat&catcomment|marks&catname|uploadbookmarks&category)=(<[[:space:]]*script|(http|https|ftp):/)"
#Nuke Bookmarks Marks.php SQL Injection Vulnerability
SecFilterSelective THE_REQUEST "modules.php?name=Bookmarks&file=marks&catname=.*&category=.*/**/(union|select|delete|insert)"
#PHPNuke general XSS attempt
#/modules.php?name=News&file=article&sid=1&optionbox=
SecFilterSelective THE_REQUEST "/modules.php?*name=<[[:space:]]*script"
# PHPNuke SQL injection attempt
SecFilterSelective THE_REQUEST "/modules.php?*name=Search*instory="
#phpnuke sql insertion
SecFilterSelective THE_REQUEST "/modules.php*name=Forums.*file=viewtopic*/forum=.*'/"
# WEB-PHP phpbb quick-reply.php arbitrary command attempt
SecFilterSelective THE_REQUEST "/quick-reply.php" chain
SecFilter "phpbb_root_path="
#Topic Calendar Mod for phpBB Cross-Site Scripting Attack
SecFilterSelective THE_REQUEST "/calendar_scheduler.php?start=(<[[:space:]]*script|(http|https|ftp):/)"
# phpMyAdmin: Safe
#phpMyAdmin Export.PHP File Disclosure Vulnerability
SecFilterSelective SCRIPT_FILENAME "export.php$" chain
SecFilterSelective ARG_what ".."
#phpMyAdmin path vln
SecFilterSelective REQUEST_URI "/css/phpmyadmin.css.php?GLOBALS[cfg][ThemePath]=/etc"
</IfModule>
|
Du kannst diese Konfiguration beibehalten. Um jedoch ein besseres Verständnis darüber zu erlangen, was mod_security tun kann, solltest Du den <IfModule mod_security.c>…</IfModule> Teil auskommentieren, Apache neu starten und Kapitel 2 folgen. Danach kannst Du Dein eigenes mod_security Ruleset erstellen, oder einfach wieder zu diesem wechseln.
2 Konfiguration
Beginnen wir nun mit einer Basis- mod_security Konfiguration, die es uns erlaubt, Regeln schnell einzufügen. Wir fügen alle mod_security Regeln in die globale Apache Konfiguration ein (es ist auch möglich die meisten Directiven in einem virtuellen Host Kontext zu verwenden, aber nicht alle).
Auf Debian und Ubuntu bearbeiten wir /etc/apache2/apache2.conf und fügen dies ans Ende:
Debian/Ubuntu:
vi /etc/apache2/apache2.conf
<IfModule mod_security.c>
# Turn the filtering engine On or Off
SecFilterEngine On
# Make sure that URL encoding is valid
SecFilterCheckURLEncoding On
# Unicode encoding check
SecFilterCheckUnicodeEncoding Off
# Only allow bytes from this range
SecFilterForceByteRange 0 255
# Only log suspicious requests
SecAuditEngine RelevantOnly
# The name of the audit log file
SecAuditLog /var/log/apache2/audit_log
# Debug level set to a minimum
SecFilterDebugLog /var/log/apache2/modsec_debug_log
SecFilterDebugLevel 0
# Should mod_security inspect POST payloads
SecFilterScanPOST On
# By default log and deny suspicious requests
# with HTTP status 500
SecFilterDefaultAction "deny,log,status:500"
</IfModule>
|
Auf Fedora fügen wir ungefähr das gleiche /etc/httpd/conf.d/mod_security.conf hinzu, ändern jedoch die Pfade zu den Log-Dateien, da Fedoras Apache /var/log/httpd als sein Log-Verzeichnis anstelle von /var/log/apache2: verwendet:
Fedora:
vi /etc/httpd/conf.d/mod_security.conf
<IfModule mod_security.c>
# Turn the filtering engine On or Off
SecFilterEngine On
# Make sure that URL encoding is valid
SecFilterCheckURLEncoding On
# Unicode encoding check
SecFilterCheckUnicodeEncoding Off
# Only allow bytes from this range
SecFilterForceByteRange 0 255
# Only log suspicious requests
SecAuditEngine RelevantOnly
# The name of the audit log file
SecAuditLog /var/log/httpd/audit_log
# Debug level set to a minimum
SecFilterDebugLog /var/log/httpd/modsec_debug_log
SecFilterDebugLevel 0
# Should mod_security inspect POST payloads
SecFilterScanPOST On
# By default log and deny suspicious requests
# with HTTP status 500
SecFilterDefaultAction "deny,log,status:500"
</IfModule>
|
Danach starten wir Apache neu:
Debian/Ubuntu:
/etc/init.d/apache2 restart
Fedora:
/etc/init.d/httpd restart
Die Direktiven sind ziemlich selbsterklärend.
- SecFilterEngine (On|Off): aktiviert/deaktiviert den Filtering Engine.
- SecFilterCheckURLEncoding (On|Off): Besondere Buchstaben müssen verschlüsselt werden bevor sie in die URL überführt werden können. Mit SecFilterCheckURLEncoding überprüfst Du, ob die Verschlüsselung gültig ist.
- SecFilterCheckUnicodeEncoding (On|Off): aktiviert/deaktiviert Überprüfung der Unicode Verschlüsselung. Das sollte ausgeschaltet sein, es sei denn, Du bist sicher, dass Deine Web Anwendungen und das Betriebssystem Unicode bearbeiten können.
- SecFilterForceByteRange: erzwingen, dass Anfragen nur aus Bytes einer bestimmten Byte Range bestehen. Das kann nützlich sein, um Stack Overflow Attacken zu verhindern. Die Standard-Range-Werte sind 0 und 255, d.h. alle Byte Werte sind erlaubt.
- SecAuditEngine (On|Off|RelevantOnly): aktiviert/deaktiviert mod_security Logging. RelevantOnly bedeutet: nur Log relevante Anfragen. Relevante Anfragen sind die Anfragen, die ein Filter Match verursachen.
- SecAuditLog: der Pfad zur mod_security Log-Datei.
- SecFilterDebugLog: der Pfad zum mod_securitys Debug-Log.
- SecFilterDebugLevel (0-9): kontrolliert, wie detailliert das Debug-Log ist. 0: nichts wird gelogged (für Produktionssysteme); 1: bedeutende Ereignisse; 2: Infor Messages; 3: detailliertere Info Messages; …
- SecFilterScanPOST (On|Off): mit mod_security kannst Du nicht nur GET Variablen scannen, sondern auch POST Variablen (von einem Formular auf einer Webseite, etc.). Dies ist standardmäßig deaktiviert, kann aber mit SecFilterScanPOST aktiviert werden.
- SecFilterDefaultAction: stellt die Standard-Aktion für ein Ereignis ein, das von unserem Filtering Ruleset gefiltert wird (was wir immer noch definieren müssen). Auf diese Direktiven folgen Aktionen, die unternommen werden müssen, z.B. „deny,log,status:500“ bedeutet: die Anfrage verweigern, sie auf den Audit-Log loggen und einen 500 (interner Server Error) Error an den Benutzer zurückgeben. Als nächstes werde ich die wichtigsten Aktionen erklären.
Aktionen
Dies sind die wichtigsten Aktionen, die mod_security auf ein Ereignis anwenden kann, dass von den Filtering Ruleset gecatched wird:
- pass: Erlaube Anfrage um auf einem Filter Match fortzufahren. Diese Aktion ist hilfreich, wenn Du ein Match loggen willst, aber andererseits nichts unternehmen möchtest.
- allow: Das ist eine stärkere Version des vorherigen Filters. Nachdem diese Aktion ausgeführt wird, werden Anfragen durchgelassen und keine anderen Filter werden ausprobiert.
- deny: Unterbreche Anfragenverarbeitung auf einem Filter Match. Sofern nicht auch die Status Aktion verwendet wird, wird ModSecurity sofort einen HTTP 500 Error Code zurückgeben.
- status: Verwende den bereitgestellten HTTP Status Code wenn die Anfrage verweigert wird.
- redirect: Leite den Benutzer zu der gegebenen URL auf dem Filter Match um.
- exec: Führe eine Binärdatei auf dem Filter Match aus. Der vollständige Pfad zur Binärdatei wird benötigt.
- log: Logge den Filter Match auf dem Apache Error Log.
- nolog: Logge nicht den Filter Match. Das wird außerdem das Audit Logging verhindern.
- chain: Rule Chaining ermöglicht es, mehrere Regeln zu verketten.
- auditlog: Logge die Transaktionsinformationen auf dem Audit Log.
- noauditlog: Logge keine Transaktionsinformationen auf dem Audit Log.