Translation(s): English - Français
Le module mod_evasive pour Apache2 permet de contrer des attaques de déni de service (DoS : Denial of Service), DDOS et Brute force. Ce module va chercher a détecter les demandes trop importantes qui sollicitent une page sur un site web en un délai de temps très court.
Contents
Mod Evasive
Le module mod_evasive pour Apache2 permet de contrer des attaques de déni de service (DoS : Denial of Service), DDOS et Brute force. Ce module va chercher a détecter les demandes trop importantes qui sollicitent une page sur un site web en un délai de temps très court.
Utiliser mod_evasive n'est pas suffisant pour une bonne sécurité, le travail de détection et de filtrage doit s'effectuer à un niveau beaucoup plus proche de la couche réseau, voire, à un niveau matériel. La détection d'attaques et le filtrage sur adresse IP n'est pas le travail normal d'un serveur Web comme Apache. Ce module facile à utiliser pourra tout de même vous aider a améliorer la sécurité de votre serveur.
Il conviendra d'utiliser mod_evasive conjointement à d'autres outils complémentaires comme mod_security et ?Fail2Ban. L'adresse IP de l'attaquant pourra être bloquée sur la durée avec ?Fail2Ban.
Si une attaque est lourde et persistante, il faudra peut-être envisager une solution d’atténuation des attaques DDoS basée sur le matériel. Sans un pare-feu et une bonne infrastructure, une attaque DDoS lourde risque de mettre vos services hors ligne.
Installation
Pour installer mod_evasive, vérifier l'ensemble des modules présents :
sudo apache2ctl -M sudo apache2ctl -M | grep evasive
Installer mod_evasive :
sudo apt-get install libapache2-mod-evasive
Afficher la liste des modules activés :
sudo ls /etc/apache2/mods-enabled/
Les fichiers evasive.conf et evasive.load ont été ajoutés. Le fichier /etc/apache2/mods-available/mod-evasive.conf contient les directives de configuration du module. Le fichier /etc/apache2/mods-available/mod-evasive.load indique à Apache2 où trouver le module dans le système de fichiers.
Le module mod-evasive se charge tout seul. vous pouvez le vérifier avec la commande
sudo a2enmod evasive Module evasive already enabled
Créer le dossier qui va stocker les logs :
sudo mkdir /var/log/apache2/mod_evasive sudo touch /var/log/apache2/mod_evasive/dos_evasive.log sudo chown -R www-data:www-data /var/log/apache2/
Configuration
Pour configurer mod_evasive :
sudo nano /etc/apache2/mods-enabled/evasive.conf
Les directives présentes dans le fichier /etc/apache2/mods-enabled/evasive.conf seront appliquées à tous les sites gérés par Apache. Pour utiliser mod_evasive avec un site en particulier, ajouter les directives de mod_evasive dans le fichier de configuration du site. Configurer le site /etc/apache2/sites-available/mon-site.conf avec les balises <?IfModule mod_evasive20.c> et <?IfModule>. Les directives contenues dans ce fichier remplaceront alors celles de la configuration globale.
<IfModule mod_evasive20.c> DOSHashTableSize 3097 # Pas plus de 2 pages par seconde. DOSPageCount 2 DOSPageInterval 1 # Pas plus de 100 requetes par seconde (Images, CSS, ...) DOSSiteCount 100 DOSSiteInterval 1 # Période en seconde durant laquelle on bloque le client. DOSBlockingPeriod 500 # Ajouter une ou plusieurs adresse IP en liste blanche. # L'adresse IP locale peut être mise en liste blanche. # DOSWhitelist 127.0.0.1 # L'adresse IP du serveur peut être mise en liste blanche. # DOSWhitelist xxx.xx.xxx.xxx # Les 3 adresses IP sont celles du Bot de Google. DOSWhitelist 66.249.65.* DOSWhitelist 66.249.66.* DOSWhitelist 66.249.71.* # Notifier l'alerte avec un mail. DOSEmailNotify admin@example.org # Chemin vers le dossier de log de Apache2, mod_evasive. # Le fichier contiendra les adresses IP blacklistées. # DOSLogDir "/var/log/apache2/mod_evasive" # Retourne un fichier par adresse IP. La valeur contenue est incohérente. # cat dos-127.0.0.1 qui contient 19915. # Il est 19h oui, mais, 41 minutes et pas 16minutes ... # Prévilégier alors la gestion des logs avec sont propre script. # Lancer une commande avec DOSSystemCommand. # Lancer par exemple un script Iptables : # DOSSystemCommand "sudo iptables -A INPUT -s %s -j DROP" # Écrire les logs : DOSSystemCommand "/bin/echo %s >> /var/log/apache2/mod_evasive/dos_evasive.log && /bin/date >> /var/log/apache2/mod_evasive/dos_evasive.log" </IfModule> # Vérifier la syntaxe de la configuration de Apache2 : sudo apache2ctl -t # Syntax OK # Redémarrer Apache2 pour prendre en compte les modifications : sudo /etc/init.d/apache2 restart
Liste des paramètres
DOSHashTableSize
- Taille de la table de hachage.
- Augmenter ce nombre améliore les performances mais consomme d'avantage de mémoire.
- Laisser la valeur par défaut.
DOSPageCount
- Nombre de requête pour une même page dans l’intervalle DOSPageInvernal, au delà, l'adresse IP est bloquée.
DOSSiteCount
- Nombre de requête pour un même site dans l’intervalle DOSPageInvernal, au delà, l'adresse IP est bloquée.
DOSPageInterval
- Nombre de requête pour une même page en secondes.
DOSSiteInterval
- Nombre de requête pour un même site en secondes.
DOSBlockingPeriod
- Période en seconde pendant laquelle l'adresse IP sera bloquée (Un forbidden est retourné).
DOSWhitelist
- Permet de mettre des adresses IP en liste blanche.
- DOSWhitelist 192.168.0.* autorise les requêtes provenant des machine d'un réseau local privé.
DOSEmailNotify admin@example.org
- Notifier l'alerte avec un mail.
- Remarque sur DOSEmailNotify : pour exécuter la commande, le module cherche l'exécutable /bin/mail. Or, celui-ci n'est pas à cet endroit. Pour que cela fonctionne, il faut créer un lien symbolique de /usr/sbin/mail vers /bin/mail :
ln -s /usr/bin/mail /bin/mail
- Pour le moment, aucun mail n'est reçu, je ne trouve pas comment faire pour envoyer et recevoir les mails de DOSEmailNotify.
- On devrait pouvoir consulter les mails avec la commande "tail -f /var/mail/www-data" (Pas testé d'avantage. Non fonctionnel pour le moment). Aucun mail n'est envoyé lors du test avec le script perl.
- Remarque sur DOSEmailNotify : pour exécuter la commande, le module cherche l'exécutable /bin/mail. Or, celui-ci n'est pas à cet endroit. Pour que cela fonctionne, il faut créer un lien symbolique de /usr/sbin/mail vers /bin/mail :
DOSLogDir "/var/log/apache2/mod_evasive/"
- Chemin vers le dossier de log de Apache2, mod_evasive.
- Retourne un fichier par adresse IP. La valeur contenue est incohérente.
- cat dos-127.0.0.1 qui contient 19915.
- Il est 19h oui, mais, 41 minutes et pas 16minutes ...
- Privilégier alors la gestion des logs avec son propre script qui pourra être lancé avec DOSSystemCommand.
?ModEvasive se connecte également à syslog lorsque l'adresse IP est bloquée. Vous pouvez vérifier le fichier journal en utilisant :
sudo tailf /var/log/messages
DOSSystemCommand
- Lancer une commande avec DOSSystemCommand, par exemple, un script Iptables :
DOSSystemCommand "sudo iptables -A INPUT -s %s -j DROP"
- Pour que le ban avec Iptables et mod-evasive fonctionne, il faut que www-data ait le droit de modifier Iptables, or, cela peut s'avérer très dangereux ! Il est conseillé de se servir de Fail2ban.
- Écrire ses propres logs pour mod_evasive plutôt que d'utiliser la commande de log intégrée dans mod_evasive :
DOSSystemCommand "/bin/echo %s >> /var/log/apache2/mod_evasive/dos_evasive.log && /bin/date >> /var/log/apache2/mod_evasive/dos_evasive.log"
- Pour permettre l'écriture dans le dossier mod_evasive/, il faut changer le propriétaire et le groupe du dossier apache2 et mod_evasive/ pour www-data avec chown.
Tests de mod_evasive
- Pour tester le module, on peut changer la configuration avec des valeurs faibles pour regarder ce qui se passe. Normalement, le dossier de log /var/log/apache2/mod_evasive/doc_evasive.log devrait se remplir d'adresses IP blacklistées.
Résultats attendus avec le script test.pl proposé dans l'installation de mod_evasive
- Utiliser le script perl "test.pl" situé dans le répertoire /usr/share/doc/libapache2-mod-evasive/examples/.
#!/usr/bin/perl # test.pl: small script to test mod_dosevasive's effectiveness use IO::Socket; use strict; for(0..100) { my($response); my($SOCKET) = new IO::Socket::INET( Proto => "tcp", PeerAddr=> "127.0.0.1:80"); if (! defined $SOCKET) { die $!; } print $SOCKET "GET /?$_ HTTP/1.0\n\n"; $response = <$SOCKET>; print $response; close($SOCKET); }
Puis, lancer le script depuis le terminal.sudo perl /usr/share/doc/libapache2-mod-evasive/examples/test.pl
Le script effectue 100 demandes sur votre serveur Web. Le code de réponse 403 indique que l'accès est refusé par le serveur Web.
Résultats affichés lors du lancement de test.pl proposé par défaut
- Test effectué sur une machine virtuelle de Debian Stretch avec une installation minimaliste, par défaut, en local.
perl /usr/share/doc/libapache2-mod-evasive/examples/test.pl HTTP/1.1 400 Bad Request HTTP/1.1 400 Bad Request ...
- Test effectué sur un serveur VPS Debian SID.
perl /usr/share/doc/libapache2-mod-evasive/examples/test.pl HTTP/1.1 400 Bad Request HTTP/1.1 400 Bad Request ...
L'erreur 400 semble signifier que la mod_evasive ne fonctionne pas, et/ou, que le script de test.pl ne fonctionne pas. Cela pourrait peut être également signifier que les VirtualHosts sont mal paramétrés.
Adapter le script test.pl
- Remplacer une ligne dans le fichier test.pl comme proposé depuis différents salons de discussions.
nano /usr/share/doc/libapache2-mod-evasive/examples/test.pl
Remplacer la ligne print $SOCKET "GET /?$_ HTTP/1.0\n\n"; par cette nouvelle ligne print $SOCKET "GET /?$_ HTTP/1.0\r\nHost: 127.0.0.1\r\n\r\n"; .
- Depuis la machine virtuelle de Debian Stretch j'obtiens bien une répétition de :
HTTP/1.1 200 OK
- Le script de test semble donc bien fonctionner en local, avec une configuration minimaliste, par défaut, en local.
- L'adresse 127.0.0.1 est en liste blanche dans la configuration proposée pour la mod_evasive.
- Il y a donc répétition de la ligne HTTP/1.1 200 OK, ni plus, ni moins.
- Ne pas mettre l'adresse 127.0.0.1 en liste blanche :
nano /etc/apache2/mods-enabled/evasive.conf
commenter # DOSWhitelist 127.0.0.1 depuis le fichier de configuration.
- Redémarrer Apache2 pour prendre en compte les modifications :
sudo /etc/init.d/apache2 restart
- Toujours depuis la machine virtuelle de Debian Stretch j'obtiens bien une répétition de :
HTTP/1.1 200 OK HTTP/1.1 200 OK ...
J'obtiens alors rapidement une erreur 403 en relançant le script test.pl, c'est donc que mod_evasive fonctionne.HTTP/1.1 403 Forbidden HTTP/1.1 403 Forbidden HTTP/1.1 200 OK HTTP/1.1 403 Forbidden HTTP/1.1 403 Forbidden ...
- Pour le serveur VPS :
- Après avoir modifié le script test.pl de la façon suivante :
# test.pl: small script to test mod_dosevasive's effectiveness use IO::Socket; use strict; for(0..100) { my($response); my($SOCKET) = new IO::Socket::INET( Proto => "tcp", PeerAddr=> "xxx.xx.xxx.xxx:80"); if (! defined $SOCKET) { die $!; } # print $SOCKET "GET /?$_ HTTP/1.0\n\n"; print $SOCKET "GET /?$_ HTTP/1.0\r\nHost: xxx.xx.xxx.xxx:80\r\n\r\n"; $response = <$SOCKET>; print $response; close($SOCKET); }
- Quand je mets 127.0.0.1 dans la liste blanche depuis le fichier de configuration, j'obtiens l'erreur 400.
HTTP/1.1 400 Bad Request HTTP/1.1 400 Bad Request ...
- Quand je ne mets pas 127.0.0.1 dans la liste blanche depuis le fichier de configuration, j'obtiens l'erreur 503 puis l'erreur 403 attendue.
HTTP/1.1 503 Service Unavailable HTTP/1.1 503 Service Unavailable ... HTTP/1.1 403 Forbidden HTTP/1.1 403 Forbidden ...
Test de mod_evasive avec Apache bench
- Utiliser Apache bench (ab) - Apache HTTP outil d'analyse comparative des serveurs (Apache bench (ab) - Apache HTTP server benchmarking tool).
- Lancer la commande suivante pour démarrer un test en local et la même commande pour un test en production.
ab -n152 -c152 127.0.0.1/index.php
- Je mets la valeur 150 pour les variables -n et -c afin d'être sur de dépasser la limite fixée de 150, dans la configuration de mod_evasive.
- -n : Nombre de demandes à exécuter pour la session d'analyse comparative.
- -c : Nombre de requêtes multiples à exécuter à la fois.
This is ApacheBench, Version 2.3 <$Revision: 1757674 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient) Completed 100 requests Finished 152 requests Server Software: Apache/2.4.25 Server Hostname: 127.0.0.1 Server Port: 80 Document Path: /index.php Document Length: 293 bytes Concurrency Level: 152 Time taken for tests: 0.289 seconds Complete requests: 152 Failed requests: 6 (Connect: 0, Receive: 0, Length: 6, Exceptions: 0) Non-2xx responses: 146 Total transferred: 213946 bytes HTML transferred: 185002 bytes Requests per second: 525.74 [#/sec] (mean) Time per request: 289.119 [ms] (mean) Time per request: 1.902 [ms] (mean, across all concurrent requests) Transfer rate: 722.65 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 2 7 12.4 2 41 Processing: 13 96 62.5 80 282 Waiting: 13 95 60.7 80 269 Total: 42 103 58.7 83 287 Percentage of the requests served within a certain time (ms) 50% 83 66% 104 75% 118 80% 118 90% 212 95% 213 98% 286 99% 287 100% 287 (longest request)
- Je mets la valeur 150 pour les variables -n et -c afin d'être sur de dépasser la limite fixée de 150, dans la configuration de mod_evasive.
- Une fois le test terminé, consulter les logs de mod_evasive. Un fichier aura été créé, ou, l'adresse IP aura été ajoutée dans le fichier existant.
- On peut en conclure que mod_evasive fonctionne correctement avec un test d'attaque DOS fait en local.
/var/log/apache2/mod_evasive# ls dos_evasive.log /var/log/apache2/mod_evasive# cat dos_evasive.log 127.0.0.1 Thu Nov 8 20:56:21 CET 2018
Test de mod_evasive avec LOIC pour Windows
LOIC est un programme de Stress Test Réseau fonctionnant sous Windows. Télécharger la version Low Orbit Ion Cannon | When harpoons, air strikes and nukes fails | v. 1.0.8.0 depuis Sourceforge : https://sourceforge.net/projects/loic/files/latest/download . Une version plus transparente et récente est proposée depuis Github : https://github.com/NewEraCracker/LOIC
Pour générer une charge de travail, suivre l'ordre indiqué dans la capture d'écran ci-dessous et ne toucher à rien d'autre :
?Fichier:LOIC.png
Purger le fichier de blacklist
- La crontab suivante permet de purger le fichier de blacklist de temps en temps :
# Vider le fichier mod_evasive 00 5 * * * find /var/log/apache2/mod_evasive -mtime +1 -type f -exec rm -f '{}' \;
Avis complémentaires
Ezra-S, le 7 août 2017 à 18:12 (source : https://serverfault.com/questions/867101/mod-evasive-doesnt-do-anything-on-ubuntu-server-16-04) : Je n’utiliserais jamais les modules httpd (tiers ou non) pour faire le travail d'un pare-feu ou d’ids/ips. Chaque couche a ses outils appropriés pour le travail, et utiliser un serveur http pour bloquer les ips dynamiquement ne convient tout simplement pas.
Lien externes
Libapache2-mod-evasive : https://wiki.debian-fr.xyz/Libapache2-mod-evasive
Fail2ban avec mod-evasive : https://wiki.debian-fr.xyz/Fail2ban#Fail2ban_avec_mod-evasive
Sécurité Apache 2 : mod_evasive : https://jeanphi.net/blog/2013/06/securite-apache-2-mod_evasive
How to harden Apache web server with mod_security and mod_evasive on CentOS : http://xmodulo.com/harden-apache-web-server-mod_security-mod_evasive-centos.html
This French content was sharing by Zer00CooL at the wiki from Visionduweb : https://wiki.visionduweb.fr/index.php?title=Mod_evasive