
Dans ce projet nous allons simuler une attaque avec Slowloris vers notre serveur web 192.168.1.101, par la suite nous allons détecter l’attaque puis protégé le serveur web avec Fail2ban.
Slowloris est un outil d’attaque de type DoS (Denial of Service) qui vise les serveurs web, en particulier ceux qui gèrent les connexions HTTP (comme Apache, Nginx ou HAProxy).
Comment fonctionne Slowloris ?
- Il ouvre plein de connexions TCP vers le serveur web.
- Il commence à envoyer une requête HTTP, mais ne la termine jamais.
- Il envoie très lentement de petits morceaux (headers) toutes les 10 à 15 secondes.
- Le serveur pense qu’un client est lent mais légitime, donc il garde la connexion ouverte.
Résultat : le serveur sature ses connexions et ne peut plus répondre aux vrais utilisateurs.
Son objectif est de faire tomber un serveur web (ou le rendre indisponible) sans envoyer beaucoup de données, contrairement aux attaques DDoS classiques (qui utilisent du volume).
Fail2Ban est un outil de sécurité pour Linux qui surveille les logs du système à la recherche de comportements suspects, et bloque automatiquement les adresses IP malveillantes avec iptables ou un pare-feu.
Que fait Fail2Ban concrètement ?
- Il lit les fichiers de log (comme ceux d’Apache, SSH, etc.).
- Il détecte des motifs d’échec répété : ex. trop de tentatives de connexion ratées.
- Si une IP fait trop de tentatives suspectes, il la bannit temporairement ou définitivement.
Note : L’utilisation de scripts d’attaque doit être limitée à des environnements de test contrôlés.
Configuration :
Serveur web : 192.168.1.101/24 (Défense avec Fail2ban)
VM KALI : 192.168.1.110/24 (Attaque avec Slowloris)
Note : Attention, ce projet consiste à effectuer des tests éthiques, ce script ne doit pas être utiliser à des fins personnelles.
Pour commencer nous allons installer le script de Slowloris, pour cela cliquez sur le lien suivant qui vous explique différentes méthodes pour l’installation : https://github.com/gkbrk/slowloris
Voici les flags disponibles pour ce script :
Commençons notre test sur le serveur web 192.168.1.101, pour cela dirigez-vous vers votre répertoire slowloris puis suivez les étapes suivantes.
- Saisir la commande : sudo python3 slowloris.py 192.168.1.101 -p 80 -s 200 -v
Voici ce que signifie cette commande :
Sudo : Exécute le script avec les droits administrateurs. Nécessaire car certaines opérations réseau (comme ouvrir beaucoup de connexions) peuvent être restreintes.
Python3 : Utilise l’interpréteur Python version 3 pour exécuter un script Python.
Slowloris.py : C’est le script Python qui effectue le test. Il doit être dans le dossier actuel ou bien indiqué avec son chemin.
192.168.1.101 : C’est l’adresse IP de la cible du test, ici un serveur web.
-p 80 : Spécifie le port TCP 80, qui est le port standard pour le protocole HTTP.
-s 200 : Demande au script de lancer 200 connexions simultanées. C’est ce qui va tester la manière dont le serveur gère plusieurs connexions ouvertes.
-v : Active le mode verbeux (verbose), ce qui affiche plus de détails dans le terminal (ex. messages de progression).
Pour résumer cette commande :
- Le script essaie d’ouvrir 200 connexions TCP vers le serveur 192.168.1.101, port 80.
- Chaque connexion envoie un début de requête HTTP lentement, sans jamais terminer complètement la requête.
- Cela simule un client lent, pour tester si le serveur maintient inutilement la connexion ouverte.
Pour arrêter le script : Ctrl+z
Voyons maintenant ce qu’il se passe quand la commande est lancée :
On peut voir que les requêtes sont envoyées simultanément.
On va détailler le mode verbose pour mieux comprendre :
Sending keep-alive headers… : Envoie un en-tête HTTP partiel à chaque socket pour la garder ouverte.
Socket count: 200 : Il y a actuellement 200 connexions actives vers le serveur.
Sleeping for 15 seconds : Pause avant le prochain envoi, pour simuler un client lent.
Creating 149 new sockets… : Le script tente de compenser la perte de connexions (fermées par le serveur).
Maintenant dirigez-vous vers le serveur web 192.168.1.101 puis saisir la commande : sudo netstat -ant | grep ’80’
La commande sudo netstat -ant | grep ’80’ permet de lister toutes les connexions TCP établies (ou en cours) sur le port 80, qui est généralement utilisé pour les requêtes HTTP (web).
Voici ce qui se passe lorsque l’on saisit la commande :
Pour faire simple on peut voir toutes les requêtes en direction de 192.168.1.101, ici l’IP 192.168.1.110 apparait plusieurs fois on peut donc conclure que Slowloris a fonctionné.
Maintenant nous allons configurer Fail2ban pour exclure cette IP, suivez les instructions suivantes :
- Crée un fichier jail.local à partir du fichier de configuration jail.conf
Cela permet de commencer avec la même configuration par défaut et de personnaliser ensuite ce fichier pour nos besoins spécifiques.
- Utiliser nano pour modifier le fichier jail.local
Pour commencer nous allons sécuriser le protocole ssh de notre serveur, pour cela dirigez-vous vers sshd et attribuer les modifications pour avoir ce résultat :
sshd : Il s’agit du jail pour le service SSH. En d’autres termes, c’est la section qui concerne la surveillance des tentatives de connexion SSH.
enabled = true : Cette ligne active la surveillance pour sshd (SSH). Cela signifie que Fail2Ban surveille les tentatives de connexion SSH pour détecter des comportements suspects.
port = ssh : Cela signifie que Fail2Ban surveille le port SSH par défaut, qui est généralement le port 22.
backend = systemd : Le paramètre backend définit quel type de journalisation Fail2Ban utilise. Ici, systemd est utilisé, ce qui est courant sur les systèmes modernes qui utilisent systemd pour la gestion des services.
logpath = /var/log/auth.log : Cela indique l’emplacement du fichier de log où Fail2Ban surveille les tentatives de connexion SSH. Dans ce cas, /var/log/auth.log est utilisé, ce qui est typique pour un serveur basé sur Debian ou Ubuntu.
Pour résumer, si une personne de se connecter 5 fois dans une fenêtre de 10 minutes alors il sera banni pendant 10 minutes.
Un jail dans Fail2Ban est une configuration qui définit une règle de filtrage pour surveiller un service spécifique (comme SSH, Apache, etc.) et bannir les adresses IP suspectes après un certain nombre de tentatives échouées.
Les valeurs de bannissement et d’essaie de connexion sont configurer par défaut dans jail.config mais vous pouvez les personnalisez sans y toucher.
Notre but est de bannir une IP qui envoi trop de requête en peu de temps, pour cela nous allons créer notre propre jail.
- Saisir le jail suivant à la fin du fichier.
[http-ban] : Cela définit le nom du jail, qui ici est http-ban
enabled = true : Cela signifie que ce jail est activé.
filter = http-ban : Cette ligne définit le filtre utilisé par ce jail. Le filtre http-ban est un fichier de configuration qui contient les expressions régulières pour identifier les tentatives d’attaque dans les logs du serveur Apache. Ce fichier se trouve généralement dans /etc/fail2ban/filter.d/http-ban.conf. Il contient les règles pour détecter les attaques comme les tentatives d’injection SQL, les attaques par force brute, etc.
port = http,https : Cela indique que Fail2Ban surveille les ports HTTP (80) et HTTPS (443) pour toute activité suspecte. Si une adresse IP effectue trop de requêtes échouées ou malveillantes sur ces ports, elle sera bannie.
logpath = /var/log/apache2/access.log : Cette ligne définit le chemin d’accès au fichier de logs Apache où Fail2Ban va chercher les événements de connexion. Dans ce cas, /var/log/apache2/access.log est utilisé pour surveiller les requêtes HTTP/HTTPS.
findtime = 60 : Ce paramètre indique la période de temps (en secondes) dans laquelle Fail2Ban va chercher les tentatives échouées. Ici, cela signifie que Fail2Ban va surveiller les tentatives sur une période de 60 secondes. Si plus de 5 tentatives échouées sont détectées pendant cette période, l’adresse IP sera bannie.
maxretry = 5 : Ce paramètre définit le nombre maximum de tentatives échouées autorisées avant qu’une adresse IP ne soit bannie. Ici, 5 tentatives échouées sont autorisées dans une période de 60 secondes.
bantime = 600 : Cela définit la durée du bannissement. Dans ce cas, une adresse IP sera bannie pendant 600 secondes (ou 10 minutes) si elle dépasse les tentatives échouées définies par maxretry.
Pour revenir au filter, il faut le crée dans /etc/fail2ban/filter.d
Ici il se nommera http-ban.conf, voici la configuration :
Cette ligne définit une expression régulière (regex) qui est utilisée par Fail2Ban pour détecter les tentatives de connexion suspectes dans les logs, en particulier les requêtes GET ou POST sur un serveur web. Examinons chaque partie :
^<HOST> : <HOST> est une variable spéciale utilisée par Fail2Ban qui représente l’adresse IP de l’attaquant ou de l’hôte qui effectue la requête.
^ indique que la ligne doit commencer par l’adresse IP.
– – : Ces tirets sont utilisés dans les logs Apache pour représenter des informations manquantes. Typiquement, ils apparaissent lorsqu’il n’y a pas de données d’identification pour la requête.
\[.*\] : Cela correspond à la date et l’heure de la requête dans les logs. Le .* signifie que tout texte entre les crochets sera accepté (cela couvre le format de date et heure dans les logs).
« (GET|POST) /.* HTTP/1\.1 » : (GET|POST) : Correspond à une méthode HTTP, soit GET soit POST, qui sont couramment utilisées pour accéder aux ressources d’un serveur web.
/.* : Correspond à l’URL demandée sur le serveur. Le .* signifie que n’importe quel chemin après le / est accepté, donc toutes les pages ou ressources demandées sont prises en compte.
HTTP/1\.1 : Correspond à la version du protocole HTTP utilisée, ici HTTP/1.1.
.* : Cela permet de capturer tout le reste de la ligne de log après la requête HTTP. Cela couvre les informations comme les codes de statut HTTP (par exemple, 200, 404) et d’autres données qui peuvent suivre dans le log.
ignoreregex : Cette ligne est vide, ce qui signifie qu’il n’y a pas de règles d’ignorance définies ici. Si tu voulais ignorer certains types de logs spécifiques (par exemple, des accès légitimes), tu pourrais ajouter des expressions régulières ici.
Pour faire simple, cette regex permet de détecter toutes les requêtes GET ou POST sur le serveur web (celles qui sont en HTTP/1.1), peu importe l’URL demandée. Si l’adresse IP effectue ce type de requête, elle est potentiellement suspecte.
Cela pourrait être utile pour détecter des attaques comme des scans de vulnérabilités, des tentatives d’injection ou des tentatives de brute force sur un formulaire web.
Conclusion :
- Le failregex est conçu pour détecter les requêtes HTTP suspectes, en particulier les GET et POST.
- ignoreregex est vide, ce qui signifie que toutes les lignes correspondant à failregex seront analysées. Si tu veux ignorer certains types de requêtes (par exemple, des requêtes légitimes), tu devras ajouter des regex dans cette section.
TEST FAIL2BAN
Pour commencer nous allons lancer le script slowloris sur le serveur comme vu précédemment par la suite nous allons voir si le jail http-ban foncrtionne.
Pour voir l’état du jail saisir la commande suivante : sudo fail2ban-client status http-ban
Mais après avoir lancer le script vous devriez avoir ceci :
Analysons cette commande :
Section Filter :
- Currently failed: 0 : Actuellement, aucune tentative suspecte n’a été détectée.
- Total failed: 150 : Depuis que le jail est actif, 150 requêtes suspectes ont été repérées dans les logs.
- File list: /var/log/apache2/access.log : C’est ce fichier log qu’il surveille pour détecter les comportements anormaux.
Section Actions :
- Currently banned: 1 : En ce moment, 1 adresse IP est bloquée.
- Total banned: 1 : Depuis le lancement du jail, une seule IP a été bannie.
- Banned IP list: 192.168.1.110 : L’IP 192.168.1.110 est actuellement bannie pour comportement suspect.
Questions :
Pourquoi le code HTTP 499 est-il utilisé dans le filtre Fail2Ban ?
Le code HTTP 499 est utilisé par Nginx quand un client coupe la connexion avant que le serveur réponde. Dans Fail2Ban, ce code sert à repérer des comportements suspects, comme des robots ou attaques qui envoient des requêtes puis quittent trop vite. Cela peut signaler une tentative de piratage ou de surcharge. En bloquant ces IPs, Fail2Ban aide à protéger le serveur.
Comment adapteriez-vous la configuration de Fail2Ban pour bloquer une attaque plus rapidement ?
Pour bloquer une attaque plus rapidement avec Fail2Ban, il suffit de rendre les paramètres de détection plus stricts. Voici comment faire :
Réduire maxretry : diminue le nombre de tentatives autorisées avant le bannissement.
- Exemple : maxretry = 3 (au lieu de 5)
Réduire findtime : raccourcit le temps pendant lequel les tentatives sont comptées.
- Exemple : findtime = 30 (secondes)
Augmenter bantime : allonge la durée de bannissement.
- Exemple : bantime = 3600 (1 heure)
Utiliser un « action » plus agressif, comme bloquer toute communication avec l’IP via iptables
Quelles sont les limites de Fail2Ban face à une attaque DDoS ?
Fail2Ban n’est pas efficace contre une vraie attaque DDoS. Voici pourquoi :
- Il réagit trop lentement pour bloquer des milliers de connexions en même temps.
- Il lit les logs pour agir, donc si l’attaque est très rapide ou ne laisse pas de traces, il ne peut rien faire.
- Il peut ralentir le serveur si les logs sont trop nombreux.
- Il ne protège pas le réseau, seulement certains services comme SSH ou Apache.