Comment configurer mod security avec Apache sur Debian/Ubuntu

De Get Docs
Aller à :navigation, rechercher

Prélude


Mod security est un pare-feu d'application Web (WAF) gratuit qui fonctionne avec Apache, Nginx et IIS. Il prend en charge un moteur de règles flexible pour effectuer des opérations simples et complexes et est livré avec un ensemble de règles de base (CRS) qui contient des règles pour l'injection SQL, les scripts intersites, les chevaux de Troie, les mauvais agents utilisateurs, le détournement de session et de nombreux autres exploits. Pour Apache, il s'agit d'un module supplémentaire qui facilite son installation et sa configuration.

Pour terminer ce didacticiel, vous aurez besoin de LAMP installé sur votre serveur.

Installation de mod_security


Modsecurity est disponible dans le dépôt Debian/Ubuntu :

apt-get install libapache2-modsecurity

Vérifiez si le module mod_security a été chargé.

apachectl -M | grep --color security

Vous devriez voir un module nommé security2_module (shared) qui indique que le module a été chargé.

L'installation de Modsecurity inclut un fichier de configuration recommandé qui doit être renommé :

mv /etc/modsecurity/modsecurity.conf{-recommended,}

Recharger Apache

service apache2 reload

Vous trouverez un nouveau fichier journal pour mod_security dans le répertoire des journaux d'Apache :

root@droplet:~# ls -l /var/log/apache2/modsec_audit.log
-rw-r----- 1 root root 0 Oct 19 08:08 /var/log/apache2/modsec_audit.log

Configuration de mod_security


Hors de la boîte, modsecurity ne fait rien car il a besoin de règles pour fonctionner. Le fichier de configuration par défaut est défini sur DetectionOnly qui enregistre les requêtes en fonction des correspondances de règles et ne bloque rien. Cela peut être changé en éditant le fichier modsecurity.conf :

nano /etc/modsecurity/modsecurity.conf

Trouver cette ligne

SecRuleEngine DetectionOnly

et changez-le en :

SecRuleEngine On

Si vous essayez ceci sur un serveur de production, modifiez cette directive uniquement après avoir testé toutes vos règles.

Une autre directive à modifier est SecResponseBodyAccess. Cela configure si les corps de réponse sont mis en mémoire tampon (c'est-à-dire lu par modsecurity). Ceci n'est nécessaire que si la détection et la protection des fuites de données sont requises. Par conséquent, le laisser On utilisera les ressources de droplet et augmentera également la taille du fichier journal.

Trouve ça

SecResponseBodyAccess On

et changez-le en :

SecResponseBodyAccess Off

Nous allons maintenant limiter le nombre maximal de données pouvant être publiées sur votre application Web. Deux directives les configurent :

SecRequestBodyLimit
SecRequestBodyNoFilesLimit

La directive SecRequestBodyLimit spécifie la taille maximale des données POST. Si quelque chose de plus grand est envoyé par un client, le serveur répondra avec une erreur 413 Request Entity Too Large. Si votre application Web n'a pas de fichiers téléchargés, cette valeur peut être considérablement réduite.

La valeur mentionnée dans le fichier de configuration est

SecRequestBodyLimit 13107200

qui est de 12,5 Mo.

La directive SecRequestBodyNoFilesLimit est similaire à celle-ci. La seule différence est que cette directive limite la taille des données POST moins les téléchargements de fichiers - cette valeur doit être "aussi faible que possible".

La valeur dans le fichier de configuration est

SecRequestBodyNoFilesLimit 131072

qui est de 128 Ko.

Dans la lignée de ces directives, il y en a une autre qui affecte les performances du serveur : SecRequestBodyInMemoryLimit. Cette directive est à peu près explicite ; il spécifie la quantité de données du "corps de la requête" (données POSTées) qui doivent être conservées dans la mémoire (RAM), tout ce qui est en plus sera placé sur le disque dur (tout comme swapping). Étant donné que les gouttelettes utilisent des SSD, ce n'est pas vraiment un problème ; cependant, cela peut être défini sur une valeur décente si vous avez de la RAM à revendre.

SecRequestBodyInMemoryLimit 131072

Il s'agit de la valeur (128 Ko) spécifiée dans le fichier de configuration.

Tester l'injection SQL


Avant de poursuivre la configuration des règles, nous allons créer un script PHP vulnérable à l'injection SQL et l'essayer. Veuillez noter qu'il ne s'agit que d'un script de connexion PHP de base sans gestion de session. Assurez-vous de changer le mot de passe MySQL dans le script ci-dessous afin qu'il se connecte à la base de données :

/var/www/login.php

<html>
<body>
<?php
    if(isset($_POST['login']))
    {
        $username = $_POST['username'];
        $password = $_POST['password'];
        $con = mysqli_connect('localhost','root','password','sample');
        $result = mysqli_query($con, "SELECT * FROM `users` WHERE username='$username' AND password='$password'");
        if(mysqli_num_rows($result) == 0)
            echo 'Invalid username or password';
        else
            echo '<h1>Logged in</h1><p>A Secret for you....</p>';
    }
    else
    {
?>
        <form action="" method="post">
            Username: <input type="text" name="username"/><br />
            Password: <input type="password" name="password"/><br />
            <input type="submit" name="login" value="Login"/>
        </form>
<?php
    }
?>
</body>
</html>

Ce script affichera un formulaire de connexion. La saisie des bonnes informations d'identification affichera un message "Un secret pour vous".

Nous avons besoin d'informations d'identification dans la base de données. Créez une base de données MySQL et une table, puis insérez les noms d'utilisateur et les mots de passe.

mysql -u root -p

Cela vous amènera à l'invite mysql>

create database sample;
connect sample;
create table users(username VARCHAR(100),password VARCHAR(100));
insert into users values('jesin','pwd');
insert into users values('alice','secret');
quit;

Ouvrez votre navigateur, accédez à http://yourwebsite.com/login.php et entrez la bonne paire d'informations d'identification.

Username: jesin
Password: pwd

Vous verrez un message indiquant que la connexion a réussi. Maintenant, revenez et entrez une mauvaise paire d'informations d'identification - vous verrez le message Nom d'utilisateur ou mot de passe invalide.

Nous pouvons confirmer que le script fonctionne correctement. Le travail suivant consiste à nous essayer à l'injection SQL pour contourner la page de connexion. Entrez ce qui suit pour le champ nom d'utilisateur :

' or true -- 

Notez qu'il devrait y avoir un espace après -- cette injection ne fonctionnera pas sans cet espace. Laissez le champ mot de passe vide et appuyez sur le bouton de connexion.

Voila ! Le script affiche le message destiné aux utilisateurs authentifiés.

Configurer des règles


Pour vous faciliter la vie, de nombreuses règles sont déjà installées avec mod_security. Ceux-ci sont appelés CRS (Core Rule Set) et sont situés dans

root@droplet:~# ls -l /usr/share/modsecurity-crs/
total 40
drwxr-xr-x 2 root root  4096 Oct 20 09:45 activated_rules
drwxr-xr-x 2 root root  4096 Oct 20 09:45 base_rules
drwxr-xr-x 2 root root  4096 Oct 20 09:45 experimental_rules
drwxr-xr-x 2 root root  4096 Oct 20 09:45 lua
-rw-r--r-- 1 root root 13544 Jul  2  2012 modsecurity_crs_10_setup.conf
drwxr-xr-x 2 root root  4096 Oct 20 09:45 optional_rules
drwxr-xr-x 3 root root  4096 Oct 20 09:45 util

La documentation est disponible sur

root@droplet1:~# ls -l /usr/share/doc/modsecurity-crs/
total 40
-rw-r--r-- 1 root root   469 Jul  2  2012 changelog.Debian.gz
-rw-r--r-- 1 root root 12387 Jun 18  2012 changelog.gz
-rw-r--r-- 1 root root  1297 Jul  2  2012 copyright
drwxr-xr-x 3 root root  4096 Oct 20 09:45 examples
-rw-r--r-- 1 root root  1138 Mar 16  2012 README.Debian
-rw-r--r-- 1 root root  6495 Mar 16  2012 README.gz

Pour charger ces règles, nous devons dire à Apache de regarder dans ces répertoires. Modifiez le fichier modsecurity.conf.

nano /etc/apache2/mods-enabled/modsecurity.conf

Ajoutez les directives suivantes dans <IfModule security2_module> </IfModule> :

Include "/usr/share/modsecurity-crs/*.conf"
Include "/usr/share/modsecurity-crs/activated_rules/*.conf"

Le répertoire activated_rules est similaire au répertoire mods-enabled d'Apache. Les règles sont disponibles dans les répertoires :

/usr/share/modsecurity-crs/base_rules
/usr/share/modsecurity-crs/optional_rules
/usr/share/modsecurity-crs/experimental_rules

Les liens symboliques doivent être créés dans le répertoire activated_rules pour les activer. Activez les règles d'injection SQL.

cd /usr/share/modsecurity-crs/activated_rules/
ln -s /usr/share/modsecurity-crs/base_rules/modsecurity_crs_41_sql_injection_attacks.conf .

Apache doit être rechargé pour que les règles prennent effet.

service apache2 reload

Ouvrez maintenant la page de connexion que nous avons créée précédemment et essayez d'utiliser la requête d'injection SQL sur le champ du nom d'utilisateur. Si vous avez changé la directive SecRuleEngine en On, vous verrez une erreur 403 Forbidden. S'il était laissé à l'option DetectionOnly, l'injection réussira mais la tentative sera consignée dans le fichier modsec_audit.log.

Écrire vos propres règles mod_security


Dans cette section, nous allons créer une chaîne de règles qui bloque la requête si certains mots « spam » sont saisis dans un formulaire HTML. Tout d'abord, nous allons créer un script PHP qui récupère l'entrée d'une zone de texte et l'affiche à l'utilisateur.

/var/www/form.php

<html>
    <body>
        <?php
            if(isset($_POST['data']))
                echo $_POST['data'];
            else
            {
        ?>
                <form method="post" action="">
                        Enter something here:<textarea name="data"></textarea>
                        <input type="submit"/>
                </form>
        <?php
            }
        ?>
    </body>
</html>

Des règles personnalisées peuvent être ajoutées à n'importe quel fichier de configuration ou placées dans des répertoires modsecurity. Nous placerons nos règles dans un nouveau fichier séparé.

nano /etc/modsecurity/modsecurity_custom_rules.conf

Ajoutez ce qui suit à ce fichier :

SecRule REQUEST_FILENAME "form.php" "id:'400001',chain,deny,log,msg:'Spam detected'"
SecRule REQUEST_METHOD "POST" chain
SecRule REQUEST_BODY "@rx (?i:(pills|insurance|rolex))"

Enregistrez le fichier et rechargez Apache. Ouvrez http://yourwebsite.com/form.php dans le navigateur et saisissez le texte contenant l'un de ces mots : pilules, assurance, rolex.

Vous verrez soit une page 403 et une entrée de journal, soit uniquement une entrée de journal basée sur le paramètre SecRuleEngine. La syntaxe de SecRule est

SecRule VARIABLES OPERATOR [ACTIONS]

Ici, nous avons utilisé l'action chaîne pour faire correspondre les variables REQUEST_FILENAME avec form.php, REQUEST_METHOD avec POST et [ X155X]REQUEST_BODY avec l'expression régulière (@rx) chaîne (pills|insurance|rolex). Le ?i: fait une correspondance insensible à la casse. En cas de correspondance réussie de ces trois règles, l'ACTION consiste à deny et log avec le message « Spam détecté ». L'action chaîne simule le ET logique pour correspondre aux trois règles.

Exclure les hôtes et les répertoires


Parfois, il est logique d'exclure un répertoire particulier ou un nom de domaine s'il exécute une application comme phpMyAdmin en tant que modsecurity et bloquera les requêtes SQL. Il est également préférable d'exclure les backends d'administration des applications CMS comme WordPress.

Pour désactiver modsecurity pour un VirtualHost complet, placez ce qui suit

<IfModule security2_module>
    SecRuleEngine Off
</IfModule>

dans la section <VirtualHost>.

Pour un répertoire particulier :

<Directory "/var/www/wp-admin">
    <IfModule security2_module>
        SecRuleEngine Off
    </IfModule>
</Directory>

Si vous ne souhaitez pas désactiver complètement modsecurity, utilisez la directive SecRuleRemoveById pour supprimer une règle ou une chaîne de règles particulière en spécifiant son ID.

<LocationMatch "/wp-admin/update.php">
    <IfModule security2_module>
        SecRuleRemoveById 981173
    </IfModule>
</LocationMatch>

Lectures complémentaires


Documentation officielle sur la sécurité des mods https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual

Soumis par : [[“%3Ca|http://jesin.tk/]] [[“%3C/a|”>Jesin A]]