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.

Das könnte dich auch interessieren …