Installer et configurer ModSecurity

07 Jun 2011 ,

ModSecurity est un module open source apache faisant office de firewall web. Il analyse et protège les sites internet contre les attaques diverses comme l'injection de script par exemple. Sa force réside dans le fait qu'il agit au niveau du protocole HTTP et qu'il peut donc protéger des sites internet qui possèdent des failles de sécurité. Il est donc un complément aujourd'hui indispensable à iptables et surtout à tous les cms actuels dont la sécurité est relativement douteuse.

Ce document est une version light de la documentation officielle que vous pouvez trouver sur le site de modsecurity et que je vous conseille vivement de parcourir! Le présent tuto est adapté à une Debian squeeze, pour toute autre distrib, il vous faudra surement adapter le code. Toutes les commandes ci-après seront réalisées en root. <!--more--> A l'heure où j'écris ces lignes les versions de ModSecurity sont les suivantes:

Prérequis :

Activer le module unique_id dans apache (normalement déjà installé):

a2enmod unique_id

Installer les librairies suivantes:

apt-get install libapr1 libapr1-dev
apt-get install libpcre3 libpcre3-dev
apt-get install libxml2 libxml2-dev

Si vous souhaitez installer ModSecurity Log Collector (mlogc - optionnel et non traité dans ce tuto) vous devez installer libcurl:

apt-get install libcurl4-gnutls-dev

Téléchargement et installation de ModSecurity

cd /root
wget http://www.modsecurity.org/download/modsecurity-apache_2.6.0.tar.gz
tar -zxvf modsecurity-apache_2.6.0.tar.gz
cd modsecurity-apache_2.6.0/
./autogen.sh
./configure
make
make install

Ignorer les erreurs de make et make install, elles portent uniquement sur l'absence de libcurl qui n'est pas nécessaire, l'installation se fera quand même. Normalement modsecurity doit être installé dans /usr/local/modsecurity Copier le module dans apache:

cp /usr/local/modsecurity/lib/mod_security2.so /usr/lib/apache2/modules/
chmod 644 /usr/lib/apache2/modules/mod_security2.so

Le module est installé mais n'est pas encore activé. Nous allons donc créer deux fichier, un pour charger le module et l'autre pour le configurer.

Commençons par le fichier de chargement du module:

vi /etc/apache2/mods-available/mod_security2.load

Y insérer le code suivant:

LoadModule security2_module /usr/lib/apache2/modules/mod_security2.so

Ensuite nous allons utiliser la configuration de base proposée par www.modsecurity.org que nous allons modifier légèrement pour l'adapter à nos besoins:

vi /etc/apache2/mods-available/mod_security2.conf

Y insérer le code suivant:

&lt;IfModule mod_security2.c&gt;
# -- 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 On

# -- Request body handling ---------------------------------------------------

# Allow ModSecurity to access request bodies. If you don't, ModSecurity
# won't be able to see any POST parameters, which opens a large security
# hole for attackers to exploit.
#
SecRequestBodyAccess On

# Enable XML request body parser.
# Initiate XML Processor in case of xml content-type
#
SecRule REQUEST_HEADERS:Content-Type &quot;text/xml&quot; \
&quot;phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML&quot;

# Maximum request body size we will accept for buffering. If you support
# file uploads then the value given on the first line has to be as large
# as the largest file you are willing to accept. The second value refers
# to the size of data, with files excluded. You want to keep that value as
# low as practical.
#
SecRequestBodyLimit 134217728
SecRequestBodyNoFilesLimit 131072

# Store up to 128 KB of request body data in memory. When the multipart
# parser reachers this limit, it will start using your hard disk for
# storage. That is slow, but unavoidable.
#
SecRequestBodyInMemoryLimit 131072

# What do do if the request body size is above our configured limit.
# Keep in mind that this setting will automatically be set to ProcessPartial
# when SecRuleEngine is set to DetectionOnly mode in order to minimize
# disruptions when initially deploying ModSecurity.
#
SecRequestBodyLimitAction Reject

# Verify that we've correctly processed the request body.
# As a rule of thumb, when failing to process a request body
# you should reject the request (when deployed in blocking mode)
# or log a high-severity alert (when deployed in detection-only mode).
#
SecRule REQBODY_ERROR &quot;!@eq 0&quot; \
&quot;phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2&quot;

# By default be strict with what we accept in the multipart/form-data
# request body. If the rule below proves to be too strict for your
# environment consider changing it to detection-only. You are encouraged
# _not_ to remove it altogether.
#
SecRule MULTIPART_STRICT_ERROR &quot;!@eq 0&quot; \
&quot;phase:2,t:none,log,deny,status:44,msg:'Multipart request body \
failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DB %{MULTIPART_DATA_BEFORE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_SEMICOLON_MISSING}, \
IQ %{MULTIPART_INVALID_QUOTING}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
IH %{MULTIPART_FILE_LIMIT_EXCEEDED}'&quot;

# Did we see anything that might be a boundary?
#
SecRule MULTIPART_UNMATCHED_BOUNDARY &quot;!@eq 0&quot; \
&quot;phase:2,t:none,log,deny,status:44,msg:'Multipart parser detected a possible unmatched boundary.'&quot;

# PCRE Tuning
# We want to avoid a potential RegEx DoS condition
#
SecPcreMatchLimit 1000
SecPcreMatchLimitRecursion 1000

# Some internal errors will set flags in TX and we will need to look for these.
# All of these are prefixed with &quot;MSC_&quot;.  The following flags currently exist:
#
# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.
#
SecRule TX:/^MSC_/ &quot;!@streq 0&quot; \
&quot;phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'&quot;

# -- Response body handling --------------------------------------------------

# Allow ModSecurity to access response bodies.
# You should have this directive enabled in order to identify errors
# and data leakage issues.
#
# Do keep in mind that enabling this directive does increases both
# memory consumption and response latency.
#
SecResponseBodyAccess On

# Which response MIME types do you want to inspect? You should adjust the
# configuration below to catch documents but avoid static files
# (e.g., images and archives).
#
SecResponseBodyMimeType text/plain text/html text/xml

# Buffer response bodies of up to 512 KB in length.
SecResponseBodyLimit 524288

# What happens when we encounter a response body larger than the configured
# limit? By default, we process what we have and let the rest through.
# That's somewhat less secure, but does not break any legitimate pages.
#
SecResponseBodyLimitAction ProcessPartial

# -- Filesystem configuration ------------------------------------------------

# The location where ModSecurity stores temporary files (for example, when
# it needs to handle a file upload that is larger than the configured limit).
#
# This default setting is chosen due to all systems have /tmp available however,
# this is less than ideal. It is recommended that you specify a location that's private.
#
SecTmpDir /tmp/

# The location where ModSecurity will keep its persistent data.  This default setting
# is chosen due to all systems have /tmp available however, it
# too should be updated to a place that other users can't access.
#
SecDataDir /tmp/

# -- File uploads handling configuration -------------------------------------

# The location where ModSecurity stores intercepted uploaded files. This
# location must be private to ModSecurity. You don't want other users on
# the server to access the files, do you?
#
SecUploadDir /opt/modsecurity/var/upload/

# By default, only keep the files that were determined to be unusual
# in some way (by an external inspection script). For this to work you
# will also need at least one file inspection rule.
#
SecUploadKeepFiles RelevantOnly

# Uploaded files are by default created with permissions that do not allow
# any other user to access them. You may need to relax that if you want to
# interface ModSecurity to an external program (e.g., an anti-virus).
#
#SecUploadFileMode 0600

#Antivirus
SecRule FILES_TMPNAMES &quot;@inspectFile /etc/apache2/modsecurity/util/runav.pl&quot; &quot;phase:2,t:none,log,deny,msg:'Malicous File Attachment Identified.'&quot;

# -- Debug log configuration -------------------------------------------------

# The default debug log configuration is to duplicate the error, warning
# and notice messages from the error log.
#
SecDebugLog /var/log/apache2/modsec_debug.log
SecDebugLogLevel 3

# -- Audit log configuration -------------------------------------------------

# Log the transactions that are marked by a rule, as well as those that
# trigger a server error (determined by a 5xx or 4xx, excluding 404,
# level response status codes).
#
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus &quot;^(?:5|4(?!04))&quot;

# Log everything we know about a transaction.
SecAuditLogParts ABIJDEFHKZ

# Use a single file for logging. This is much easier to look at, but
# assumes that you will use the audit log only ocassionally.
#
SecAuditLogType Serial
SecAuditLog /var/log/apache2/modsec_audit.log

# Specify the path for concurrent audit logging.
#SecAuditLogStorageDir /opt/modsecurity/var/audit/

# -- Miscellaneous -----------------------------------------------------------

# Use the most commonly used application/x-www-form-urlencoded parameter
# separator. There's probably only one application somewhere that uses
# something else so don't expect to change this value.
#
SecArgumentSeparator &amp;

# Settle on version 0 (zero) cookies, as that is what most applications
# use. Using an incorrect cookie version may open your installation to
# evasion attacks (against the rules that examine named cookies).
#
SecCookieFormat 0

Include /etc/apache2/modsecurity/activated_rules/*.conf
&lt;/IfModule&gt;

Modifications apportées au fichier

Ligne 8 : SecRuleEngine On Ici on active ModSecurity pour bloquer et logguer les attaques. Deux autre modes sont possibles: Off: désactivé DetectionOnly: Fonctionnera comme un IDS, c'est à dire qu'il se contentera de logguer les attaques sans pour autant les bloquer.

Ligne 141 : SecUploadDir /opt/modsecurity/var/upload/ On défini l'emplacement sécurisé pour les fichiers uploadés, si le répertoire n'existe pas il faudra le créer:

mkdir -p /opt/modsecurity/var/upload/

Ligne 156 : SecRule FILES_TMPNAMES "@inspectFile /etc/apache2/modsecurity/util/runav.pl" "phase:2,t:none,log,deny,msg:'Malicous File Attachment Identified.'" On défini le chemin vers le script qui va scanner les fichiers uploadé contre les virus, le fichier nécessite que clamav soit installé. Si vous ne souhaitez pas l'utiliser vous pouvez commentez cette ligne.

Ligne 163 : SecDebugLog /var/log/apache2/modsec_debug.log Ici on souhaite dupliquer les erreurs de Error.log dans un autre fichier, c'est plus pratique pour le debug.

Ligne 182 : SecAuditLog /var/log/apache2/modsec_audit.log On défini le fichier de log qui contiendra la trace complète des attaques.

Ligne 201 : Include /etc/apache2/modsecurity/activated_rules/*.conf Cette ligne inclue le chemin des fihiers de regles dont l'installation est decrite ci-dessous.

Mises en place des règles

www.modsecurity.org met à votre disposition des jeux de règles à installer, pour cela nous allons les télécharger:

cd /etc/apache2/
wget http://sourceforge.net/projects/mod-security/files/modsecurity-crs/0-CURRENT/modsecurity-crs_2.2.0.tar.gz
tar -zxvf modsecurity-crs_2.2.0.tar.gz
mv modsecurity-crs_2.2.0 modsecurity
cd modsecurity
ls -la

Vous pouvez remarquer qu'il y a tout un tas de règles diverses et variées qui peuvent rendre votre ModSecurity plus ou moins paranoïaque! Pour le tuto nous allons installer uniquement celle proposées par la configuration decrite dans le fichier INSTALL.

En gros, nous avons un répertoire "activatedrules" qui, dans le même principe que mods-enabled ou sites-enabled va contenir des liens symboliques vers les fichiers de règles que nous souhaitons ajouter. Pour commencer nous allons dupliquer le fichier modsecuritycrs10config.conf.example qui contiendra vos règles personnelles: Note pour la suite: Vérifiez que vous vous trouvez bien dans le répertoire /etc/apache2/modsecurity.

cp modsecurity_crs_10_config.conf.example modsecurity_crs_10_config.conf

Il faut ensuite l'activer ...

ln -s /etc/apache2/modsecurity/modsecurity_crs_10_config.conf /etc/apache2/modsecurity/activated_rules/modsecurity_crs_10_config.conf

Ensuite nous allons activer toutes les règles du répertoire "base_rules" qui contient les règles de base de ModSecurity:

for f in `ls base_rules/` ; do ln -s /etc/apache2/modsecurity/base_rules/$f /etc/apache2/modsecurity/activated_rules/$f ; done

Nous allons activer aussi le jeu de règle comment_spam:

for f in `ls optional_rules/ | grep comment_spam` ; do ln -s /etc/apache2/modsecurity/optional_rules/$f /etc/apache2/modsecurity/activated_rules/$f ; done

Si vous listez le repertoire activated_rules vous devriez voir les liens symboliques de tout les fichiers de règles activés.

ls -la activated_rules

Anti-virus

Vus pouvez également lier ModSecurity à votre antivirus grâce à un script perl. A chaque upload de fichier ModSecurity demandera à l'antivirus de le scanner pour vérifier son intégrité. Dans notre cas nous utiliserons clamav, ce qui tombe bien car un script est déjà mis à disposition dans le répertoire "util"! Il s'agit du fichier runav.pl Ici il n'y a rien à faire car la directive pour utiliser ce script a déjà été définie précédemment dans le fichier /etc/apache2/mods-available/mod_security2.conf ligne 156.

Activation de ModSecurity et Test

Maintenant que tout est prêt, il ne reste plus qu'à activer le module. Attention, si vous êtes sur un serveur en production, je vous conseille de modifier le paramètre SecRuleEngine ligne 8 du fichier /etc/apache2/mods-available/mod_security2.conf à DetectionOnly ce qui permettra en cas de faux positifs de ne pas bloquer les utilisateurs.

a2enmod mod_security2
service apache2 restart

Si apache redémarre correctement c'est que le module est bien paramétré. Sinon désactivez le module, redémarrez apache et essayez de résoudre les erreurs éventuelles.

Normalement vos fichiers de log devraient se créer automatiquement et commencer à se remplir, inspectez donc le fichier /var/log/apache2/modsec_audit.log

tail -f /var/log/apache2/modsec_audit.log

Allez sur un de vos site et ajoutez dans l'url : www.votre_site.com/?p=<script> Vous devriez voir apparaitre un log de tentative d'attaque et si SecRuleEngine est à on, vous vous faites simplement jeter.

Essayez d'uploader un fichier infecté par un virus, un simple fichier test eicar fera l'affaire, créez le fichier testeicar.txt et ajoutez cette ligne:

X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

Essayez ensuite de l'uploader, si vous voyez des logs c'est que le fichier a été scanné et si SecRuleEngine est à on, votre fichier est refusé par le serveur.

Erreurs et Faux positifs

Upload de fichiers: si vous obtenez cette erreur: mod_fcgid: HTTP request length 135714 (so far) exceeds MaxRequestLen (131072) Vous devez modifier le module fcgid et autoriser une plus grosse taille pour les fichiers:

vi /etc/apache2/mods-available/fcgid.conf

et modifiez-le comme ceci:

  AddHandler    fcgid-script .fcgi
  FcgidConnectTimeout 20
  # Accepte de gros fichiers
  MaxRequestLen 15728640

C'est la config de php.ini permettra de limiter la taille des fichiers.

Faux positifs

Il y a de grandes chances pour que certaines pages de vos sites deviennent inaccessibles car détectées par ModSecurity comme contenant du code suspicieux. C'est par exemple le cas de piwik ou de wordpress qui chargent nombre de fichiers javascripts et autres. Plusieurs solutions sont possibles mais la plus simple est de désactiver certaines règles pour des pages demandée. Il suffit de regarder les logs et de prélever l'id de la règle qui nous bloque et de la désactiver. Nous allons commencer par créer un fichier /etc/apache2/modsecurity/whitelist.conf, ce fichier contiendra nos règles de faux positifs

vi /etc/apache2/modsecurity/whitelist.conf

Nous allons prendre comme exemple wordpress et l'accès à l'admin impossible Ajoutons la règles suivante au fichier :

#Ici on désactive 5 règles pour tout le répertoire wp-admin
&lt;LocationMatch &quot;/wp-admin/&quot;&gt;
SecRuleRemoveById 970901 970903 960009 950109 950907
&lt;/LocationMatch&gt;

#Ici on désactive une règle pour un script en particulier
&lt;LocationMatch &quot;/wp-admin/theme-editor.php&quot;&gt;
SecRuleRemoveById 958885
&lt;/LocationMatch&gt;

Ne pas oublier d'ajouter notre fichier au répertoire activated_rules:

ln -s /etc/apache2/modsecurity/whitelist.conf /etc/apache2/modsecurity/activated_rules/whitelist.conf
service apache2 restart

On devrais maintenant pouvoir accéder à l'admin de wordpress et si c'est pas bon, c'est que l'on a pas désactivé les bonne règles! J'en profite pour ajouter que certaines règles on été créées pour coller à certains cms ou sites préconçus. Vous trouverez ces règles dans le répertoire slr_rules.

Maintenant que ModSecurity est installé et configuré, n'hésitez pas à consulter la documentation pour en faire le tour et en maitriser tout ses aspects!

comments powered by Disqus