Comment configurer ModSecurity avec Apache sur Ubuntu 14.04 et Debian 8

introduction

ModSecurity est un pare-feu d’application Web 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. Il est livré avec un ensemble de règles de base comprenant des règles d’injection SQL, de script intersite, de chevaux de Troie, d’agents utilisateurs malveillants, de piratage de session et de nombreux autres exploits. Pour Apache, il est chargé en tant que module supplémentaire, ce qui facilite son installation et sa configuration.

Conditions préalables

Pour suivre ce tutoriel, vous aurez besoin de:

Étape 1 - Installation de ModSecurity

Dans cette étape, nous installerons ModSecurity.

Commencez par mettre à jour les fichiers d’index du paquet.

sudo apt-get update

Ensuite, installez ModSecurity.

sudo apt-get install libapache2-mod-security2 -y

Vous pouvez vérifier que le module ModSecurity a été chargé à l’aide de la commande suivante.

sudo apachectl -M | grep --color security2

Si la sortie lit + security2_module (partagé) +, cela indique que le module a été chargé.

L’installation de ModSecurity inclut un fichier de configuration recommandé qui doit être renommé.

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

Enfin, rechargez Apache.

sudo service apache2 reload

Un nouveau fichier journal pour ModSecurity sera créé dans le répertoire des journaux Apache sous + / var / log / apache2 / modsec_audit.log +.

Étape 2 - Configuration de ModSecurity

ModSecurity ne fait rien du tout parce qu’il a besoin de règles pour fonctionner. Dans cette étape, nous activerons d’abord certaines directives de configuration.

Pour trouver et remplacer les directives de configuration à cette étape, nous allons utiliser + sed +, un éditeur de flux. Vous pouvez consulter la https://www.digitalocean.com/community/tutorial_series/using-sed [série de tutoriels + sed +] pour en savoir plus sur l’outil.

Directives de base à activer

Le fichier de configuration ModSecurity par défaut est défini sur + DetectionOnly +, qui enregistre les demandes en fonction des correspondances de règles et ne bloque rien. Cela peut être changé en modifiant le fichier + modsecurity.conf + et en modifiant la directive + SecRuleEngine +. Si vous essayez ceci sur un serveur de production, modifiez cette directive uniquement après avoir testé toutes vos règles.

sudo sed -i "s/SecRuleEngine DetectionOnly/SecRuleEngine On/" /etc/modsecurity/modsecurity.conf

La directive + SecResponseBodyAccess + configure si les corps de réponse sont mis en mémoire tampon (c’est-à-dire lu par ModSecurity). Cela n’est nécessaire que si une détection et une protection contre les fuites de données sont requises. Par conséquent, le laisser activé consommera les ressources de Droplet et augmentera également la taille du fichier journal. Nous le désactiverons donc.

sudo sed -i "s/SecResponseBodyAccess On/SecResponseBodyAccess Off/" /etc/modsecurity/modsecurity.conf

Directives facultatives à modifier

Vous pouvez personnaliser d’autres directives en modifiant + / etc / modsecurity / modsecurity.conf +. Les directives + SecRequestBodyLimit + et + SecRequestBodyNoFilesLimit + limitent le nombre maximal de données pouvant être publiées dans votre application Web.

En particulier, la directive + SecRequestBodyLimit + spécifie la taille maximale des données POST. Si quelque chose de plus gros est envoyé par un client, le serveur répondra avec une erreur 413 Request Entity Too Large. Si aucun fichier n’a été téléchargé dans votre application Web, vous pouvez laisser cette valeur telle quelle. La valeur préconfigurée spécifiée dans le fichier de configuration est 13107200 octets (12,5 Mo). Si vous souhaitez modifier cette valeur, recherchez la ligne suivante + modsecurity.conf +:

Modification facultative de la directive modsecurity.conf

SecRequestBodyLimit

De même, le + SecRequestBodyNoFilesLimit + limite la taille des données POST moins les téléchargements de fichiers. Cette valeur doit être définie sur une valeur aussi basse que possible pour réduire les risques d’attaques par déni de service (DoS) lorsqu’une personne envoie des corps de requête de très grande taille. La valeur préconfigurée dans le fichier de configuration est 131072 octets (128 Ko). Si vous souhaitez modifier cette valeur, recherchez la ligne suivante + modsecurity.conf +:

Modification facultative de la directive modsecurity.conf

SecRequestBodyNoFilesLimit

Une directive qui affecte les performances du serveur est + SecRequestBodyInMemoryLimit +. Cette directive est assez explicite. il spécifie la quantité de données du «corps de la requête» (données POSTed) qui doivent être conservées dans la mémoire (RAM); tout élément supplémentaire sera placé sur le disque dur (comme pour l’échange). Parce que les Droplets utilisent des disques SSD, ce n’est pas un problème. Cependant, cela peut être changé si vous avez de la RAM à dépenser. La valeur préconfigurée pour cette directive est 128 Ko. Si vous souhaitez modifier cette valeur, recherchez la ligne suivante + modsecurity.conf +:

Modification facultative de la directive modsecurity.conf

SecRequestBodyInMemoryLimit

Étape 3 - Tester une injection SQL

Avant de configurer certaines règles, nous allons créer un script PHP vulnérable à l’injection SQL afin de tester la protection de ModSecurity.

Tout d’abord, accédez à l’invite MySQL.

mysql -u root -p

Ici, créez une base de données MySQL appelée * sample * et connectez-vous dessus.

create database ;
connect ;

Créez ensuite une table contenant des informations d’identification - le nom d’utilisateur * sammy * et le mot de passe * password *.

create table users(username VARCHAR(100),password VARCHAR(100));
insert into users values('sammy','password');

Enfin, quittez l’invite MySQL.

quit;

Créez ensuite le script de connexion dans la racine du document d’Apache.

sudo nano /var/www/html/login.php

Collez le script PHP suivant dans le fichier. Assurez-vous de changer le mot de passe MySQL dans le script ci-dessous pour celui que vous avez défini précédemment afin que le script puisse se connecter à la base de données:

/var/www/html/login.php

<html>
<body>
<?php
   if(isset($_POST['login']))
   {
       $username = $_POST['username'];
       $password = $_POST['password'];
       $con = mysqli_connect('localhost','root','','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>This is text that should only be displayed when logged in with valid credentials.</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. Ouvrez votre navigateur et accédez à + ​​http: /// login.php + pour le voir. Si vous entrez la paire d’identifiants correcte, par exemple, sammy dans le champ * Nom d’utilisateur * et le mot de passe dans le champ * Mot de passe *, le message * s’affiche. Ce texte s’affiche uniquement lorsque vous êtes connecté avec des informations d’identification valides *. Si vous revenez à l’écran de connexion et utilisez des informations d’identification incorrectes, vous verrez le message * Nom d’utilisateur ou mot de passe invalide *.

Le travail suivant consiste à essayer une injection SQL pour contourner la page de connexion. Entrez ce qui suit pour le champ nom d’utilisateur.

Nom d’utilisateur d’injection SQL

' or true --

Notez qu’il devrait y avoir un espace après + - + pour que cette injection fonctionne. Laissez le champ mot de passe vide et cliquez sur le bouton de connexion. Le script montre le message destiné aux utilisateurs authentifiés! Dans la prochaine étape, nous allons empêcher cela.

Étape 4 - Configuration des règles

Dans cette étape, nous allons configurer certaines règles ModSecurity.

Activer le CRS

Pour simplifier les choses, de nombreuses règles sont déjà installées avec ModSecurity. Celles-ci sont appelées CRS (Core Rule Set) et se trouvent dans le répertoire + / usr / share / modsecurity-crs +. Pour charger ces règles, nous devons configurer Apache pour qu’il lise les fichiers + .conf + de ces répertoires. Ouvrez donc le fichier + security2.conf + pour le modifier.

sudo nano /etc/apache2/mods-enabled/security2.conf

Ajoutez les deux directives suivantes, surlignées en rouge, avant la dernière ligne du fichier (+ </ IfModule> +).

Security2.conf mis à jour

       IncludeOptional /etc/modsecurity/*.conf


</IfModule>

Enregistrez et fermez le fichier.

Exclure des répertoires / domaines (facultatif)

Parfois, il est logique d’exclure un répertoire particulier ou un nom de domaine s’il exécute une application, telle que phpMyAdmin, car ModSecurity bloquera les requêtes SQL. Il est également préférable d’exclure les backends administrateurs d’applications CMS telles que WordPress. Si vous suivez ce didacticiel sur un nouveau serveur, vous pouvez ignorer cette étape.

Pour désactiver ModSecurity pour un VirtualHost complet, placez les directives suivantes dans le bloc + <VirtualHost> […​] </ VirtualHost> + dans son fichier hôte virtuel.

<IfModule security2_module>
   SecRuleEngine Off
</IfModule>

Pour omettre un répertoire particulier (par exemple, + / var / www / wp-admin):

<Directory "">
   <IfModule security2_module>
       SecRuleEngine Off
   </IfModule>
</Directory>

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

<LocationMatch "">
   <IfModule security2_module>
       SecRuleRemoveById
   </IfModule>
</LocationMatch>

Activer la règle d’injection SQL

Ensuite, nous activerons le fichier de règles d’injection SQL. Les fichiers de règles requis doivent être liés de manière symétrique au répertoire + activé_rules +, qui est similaire au répertoire + mods-enabled + d’Apache. Allez dans le répertoire + Activated_rules +.

cd /usr/share/modsecurity-crs/activated_rules/

Créez ensuite un lien symbolique à partir du fichier + modsecurity crs_41_sql_injection_attacks.conf.

sudo ln -s ../base_rules/modsecurity_crs_41_sql_injection_attacks.conf .

Enfin, rechargez Apache pour que les règles prennent effet.

sudo service apache2 reload

Ouvrez maintenant la page de connexion créée précédemment et essayez d’utiliser la même requête d’injection SQL dans le champ Nom d’utilisateur. Étant donné que nous avons modifié la directive + SecRuleEngine + en + On + à l’étape 2, une erreur * 403 Forbidden * est affichée. (Si + SecRuleEngine + était laissé à l’option + DetectionOnly +, l’injection aboutira, mais la tentative serait consignée dans le fichier + modsec_audit.log +.)

Étant donné que ce script de connexion PHP est uniquement destiné à tester ModSecurity, vous devez le supprimer maintenant que le test est terminé.

sudo rm /var/www/html/login.php

Étape 5 - Rédigez vos propres règles

Dans cette section, nous allons créer une chaîne de règles qui bloque la demande si certains mots couramment associés au spam sont entrés dans un formulaire HTML.

Tout d’abord, nous allons créer un exemple de script PHP qui extrait l’entrée d’une zone de texte et la réaffiche à l’utilisateur. Ouvrez un fichier nommé + from.php pour le modifier.

sudo nano /var/www/html/form.php

Collez le code suivant:

/var/www/html/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 à l’un des fichiers de configuration ou placées dans des répertoires ModSecurity. Nous allons placer nos règles dans un nouveau fichier séparé appelé + modsecurity_custom_rules.conf +.

sudo nano /etc/modsecurity/.conf

Collez le texte suivant dans ce fichier. Les deux mots que nous bloquons sont * blockword1 * et * blockword2 *.

modsecurity_custom_rules.conf

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

La syntaxe de + SecRule + est + SecRule VARIABLES OPERATOR [ACTIONS] +. Ici, nous avons utilisé l’action en chaîne pour faire correspondre les variables + REQUEST_FILENAME + avec + form.php +, + REQUEST_METHOD + avec + + POST +, et + REQUEST_BODY + avec l’expression régulière + (@ rx) + chaîne ` + (blockword1 | blockword2) + . Le `+? I: + est une correspondance insensible à la casse. En cas de correspondance réussie de ces trois règles, le + ACTION + consiste à refuser et à se connecter avec le msg« Spam détecté ». + L’action en chaîne simule le ET logique pour qu’il corresponde aux trois règles.

Enregistrez le fichier et rechargez Apache.

sudo service apache2 reload

Ouvrez + http: /// form.php + dans le navigateur. Si vous entrez du texte contenant blockword1 ou blockword2, vous verrez une page 403.

Étant donné que ce script de formulaire PHP est uniquement destiné à tester ModSecurity, vous devez le supprimer maintenant que le test est terminé.

sudo rm /var/www/html/form.php

Conclusion

Dans ce didacticiel, vous avez appris à installer et à configurer ModSecurity et à ajouter des règles personnalisées. Pour en savoir plus, vous pouvez consulter la official documentation officieuse ModSecurity.