Skip to content

Apache2 mit OWASP mod_security2

Installation

mod_security ist direkt in den Paketquellen von Debian/Ubuntu enthalten. Benötigt wird folgendes Paket.

sudo apt-get install libapache2-mod-security2

Anschließend muss das Modul security2 und headers noch aktiviert werden.

sudo a2enmod security2
sudo a2enmod headers

Konfiguration

mod_security Konfigurieren wir in der Datei /etc/modsecurity/modsecurity.conf. Diese Datei müssen wir erst durch kopieren einer Example Datei (-recommended) erstellen.

sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf

Öffnet man nun die Datei /etc/modsecurity/modsecurity.conf mit einem beliebigen Texteditor, befindet sich das Modul im Erkennungsmodus (Detectionmode). In unserem Fall belassen wir das so, wir aktivieren mod_security per VirtualHost.

Im Detectionmode werden keine corerules geladen und es wird daher kein Client aktiv blockiert.

Folgende Einstellungen habe ich gesetzt/geändert.

sudo vi /etc/modsecurity/modsecurity.conf
# -- Rule engine initialization ----------------------------------------------

# Enable ModSecurity, attaching it to every transaction. Use detection
# only to start with, because that minimises the chances of post-installation
# disruption.
#
SecRuleEngine DetectionOnly

SecRequestBodyLimit 26214400
....
SecRequestBodyNoFilesLimit 256000
....
SecRequestBodyInMemoryLimit 262144
....
SecRequestBodyLimitAction ProcessPartial
....
SecPcreMatchLimit 300000
....
SecPcreMatchLimitRecursion 300000
....

Wo die Rules sich befinden und die Reihenfolge beim Laden, definiert man in der Datei /etc/apache2/mods-available/security2.conf. :warning: Die Reihenfolge beim Laden ist sehr wichtig!

sudo cat <<CONFIG >/etc/apache2/mods-available/security2.conf
<IfModule security2_module>
        # Default Debian dir for modsecurity's persistent data
        SecDataDir /var/cache/modsecurity

        # Include all the *.conf files in /etc/modsecurity.
        # Keeping your local configuration in that directory
        # will allow for an easy upgrade of THIS file and
        # make your life easier
        IncludeOptional /etc/modsecurity/modsecurity.conf
        IncludeOptional /etc/modsecurity/crs-setup.conf

        # Include OWASP ModSecurity CRS rules if installed
        IncludeOptional custom.d/modsecurity.d/rules-custom/*-BEFORE-CRS.conf
        IncludeOptional custom.d/modsecurity.d/rules-custom/*_modsec.conf
        IncludeOptional custom.d/modsecurity.d/rules-enabled/*.conf
        IncludeOptional custom.d/modsecurity.d/rules-custom/*-AFTER-CRS.conf

</IfModule>
CONFIG

OWASP ModSecurity Rules herunterladen und installieren

Die OWASP Rules laden wir von https://github.com/coreruleset/ herunter und speichern diese in /etc/modsecurity.

cd /etc/modsecurity/
sudo wget https://github.com/coreruleset/coreruleset/archive/refs/tags/v3.3.5.tar.gz -O coreruleset-3.3.5.tar.gz

Nun entpacken wir das Coreruleset und setzen einen Symlink auf die aktuelle Version. Dies mach später ein Update auf eine neue Version leichter.

sudo tar xzvf coreruleset-3.3.5.tar.gz && sudo rm coreruleset-3.3.5.tar.gz
sudo ln -s coreruleset-3.3.5 coreruleset

Dann kopieren wir uns noch die crs-setup.conf.example Datei nach crs-setup.conf.

sudo cp coreruleset/crs-setup.conf.example coreruleset/crs-setup.conf
sudo ln -s coreruleset/crs-setup.conf

Apache Konfiguration

Ich speichere meine Custom Konfiguration des Apache Webservers in dem Verzeichnis /etc/apache2/custom.d, welches wir und erstmal anlegen.

cd /etc/apache2/ && sudo mkdir -p custom.d/modsecurity.d/rules-{custom,enabled}
cd custom.d/modsecurity.d/
sudo ln -s /etc/modsecurity/coreruleset/rules rules-available

Nun haben wir folgende Verzeichnisstruktur in unserem mod_security Konfigurationsverzeichnis. rules-available ist dabei ein Symlink auf /etc/modsecurity/coreruleset/rules.

ls -1 /etc/apache2/custom.d/modsecurity.d/
rules-available
rules-custom
rules-enabled

Jetzt werden wir unser OWASP Coreruleset im Verzeichnis rules-enabled aktivieren, indem wir dort Symlinks auf den Rules setzen. Dies machen wir am schnellsten wie folgt.

cd rules-enabled/
for link in $(ls -1 ../rules-available/*{data,conf}); do sudo ln -s $link ; done

Beim aktivieren der Rules, haben wir zwei .example Rules ausgelassen. Diese beiden Rules kopieren wir in das Verzeichnis rules-custom.

cd /etc/apache2/custom.d/modsecurity.d/
sudo cp rules-available/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example rules-custom/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
sudo cp rules-available/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example rules-custom/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf

Wenn wir uns nochmal die Datei /etc/apache2/mods-available/security2.conf ansehen, sieht man, das eine bestimmte Reihenfolge beim Laden der Rules wichtig ist.

1. rules-custom/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf

Request Ruleset, hier kommen eigentlich die Customrules rein, ich nutze aber pro VirtualHost extra Dateien

2. rules-custom/*_modsec.conf

VirtualHost Ruleset, den Namen wähle ist wie der Servername, z.B. www.example.com_modsec.conf

3. rules-enabled/*.conf

Main Ruleset für alle aktiven VirtualHost

4. rules-custom/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf

Responce Ruleset

Jetzt können wir unsere VirtualHost Datei öffnen und mod_security für diesen VirtualHost aktivieren.

vi /etc/apache2/sites-available/www.example.com.conf
<VirtualHost *:443>
....
    # ModSecurity configuration for www.example.com
    <IfModule mod_security2.c>
        SecRuleEngine On
        SecAuditLog ${APACHE_LOG_DIR}/www.example.com_modsec.log
        SecWebAppId "www.example.com"
    </IfModule>
....
</VirtualHost>

Als letztes prüfen wir nochmal die Konfiguration des Apache Webservers und laden die gemachten Einstellungen.

apache2ctl configtest && apache2ctl graceful

Werden Rules angewendet und ein Request geblockt, findet man im Logfile unter /var/log/apache2/www.example.com_modsec.log weitere Dateils, warum ein Request geblockt wurde. Mit dem Skript modseclogs lassen sich die Logfiles bequem und farbig anzeigen. Im Artikel ModSecurity Logs einfacher auslesen wird das Skript im detail erklärt.

Dokumentation