{"id":204,"date":"2026-06-17T08:00:00","date_gmt":"2026-06-17T08:00:00","guid":{"rendered":"https:\/\/shattered.io\/fr\/2026\/06\/17\/fail2ban-tutoriel-serveur-linux\/"},"modified":"2026-06-17T16:22:49","modified_gmt":"2026-06-17T16:22:49","slug":"fail2ban-tutoriel-serveur-linux","status":"publish","type":"post","link":"https:\/\/shattered.io\/fr\/2026\/06\/17\/fail2ban-tutoriel-serveur-linux\/","title":{"rendered":"Fail2ban : prot\u00e9ger un serveur Linux en 12 \u00e9tapes [2026]"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Chaque jour, vos serveurs Linux encaissent des milliers de tentatives de connexion automatis\u00e9es. SSH, Apache, Nginx, Postfix : chaque service expos\u00e9 devient une cible pour les bots de force brute. Fail2ban est l&#8217;outil standard pour y mettre fin, en analysant vos logs en temps r\u00e9el et en bannissant automatiquement les IP malveillantes via iptables ou nftables. Ce tutoriel vous guide de l&#8217;installation \u00e0 la configuration avanc\u00e9e, en 12 \u00e9tapes et 30 minutes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"fail2ban-quest-ce-que-cest\">Fail2ban : qu&#8217;est-ce que c&#8217;est et pourquoi l&#8217;utiliser en 2026<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban est un syst\u00e8me de pr\u00e9vention des intrusions (IPS) \u00e9crit en Python, con\u00e7u pour surveiller les fichiers journaux de vos services et bloquer automatiquement les h\u00f4tes qui pr\u00e9sentent des signes d&#8217;activit\u00e9 malveillante. La logique est simple : apr\u00e8s un nombre configurable de tentatives \u00e9chou\u00e9es (<strong>maxretry<\/strong>), l&#8217;adresse IP source est bannie pour une dur\u00e9e d\u00e9finie (<strong>bantime<\/strong>) via une r\u00e8gle de pare-feu.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En 2026, les attaques par force brute contre SSH restent parmi les vecteurs d&#8217;intrusion les plus courants selon le rapport de menaces ANSSI (CERTFR-2026-CTI-001). Un serveur expos\u00e9 sur internet sans protection re\u00e7oit en moyenne plusieurs centaines de tentatives de connexion SSH par heure. Fail2ban transforme cette menace constante en une protection automatique, sans intervention manuelle.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La version stable actuelle est la <strong>1.1.0<\/strong>, publi\u00e9e le 25 avril 2024, qui apporte la compatibilit\u00e9 compl\u00e8te avec Python 3.12 et 3.13. Le projet est maintenu sur GitHub avec plus de 10 000 \u00e9toiles et une communaut\u00e9 active.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ce-que-fail2ban-protege\">Ce que Fail2ban prot\u00e8ge<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Service<\/th><th>Log surveill\u00e9<\/th><th>Filtre int\u00e9gr\u00e9<\/th><th>Risque bloqu\u00e9<\/th><\/tr><\/thead><tbody><tr><td>SSH (OpenSSH)<\/td><td>\/var\/log\/auth.log<\/td><td>sshd<\/td><td>Brute force, scan de ports<\/td><\/tr><tr><td>Apache HTTP<\/td><td>\/var\/log\/apache2\/error.log<\/td><td>apache-auth<\/td><td>Authentification HTTP<\/td><\/tr><tr><td>Nginx<\/td><td>\/var\/log\/nginx\/error.log<\/td><td>nginx-http-auth<\/td><td>Auth basique, 400\/403<\/td><\/tr><tr><td>Postfix (SMTP)<\/td><td>\/var\/log\/mail.log<\/td><td>postfix<\/td><td>Spam, relais non autoris\u00e9s<\/td><\/tr><tr><td>Dovecot (IMAP)<\/td><td>\/var\/log\/mail.log<\/td><td>dovecot<\/td><td>Brute force messagerie<\/td><\/tr><tr><td>WordPress<\/td><td>\/var\/log\/nginx\/access.log<\/td><td>nginx-botsearch<\/td><td>Scans wp-login.php<\/td><\/tr><tr><td>Proftpd \/ vsftpd<\/td><td>\/var\/log\/proftpd\/*.log<\/td><td>proftpd<\/td><td>Brute force FTP<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"prerequis\">Pr\u00e9requis avant l&#8217;installation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Avant de commencer ce tutoriel, assurez-vous de disposer des \u00e9l\u00e9ments suivants :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Syst\u00e8me d&#8217;exploitation :<\/strong> Ubuntu 22.04 LTS, Ubuntu 24.04 LTS, Debian 11\/12, ou CentOS Stream 9 \/ AlmaLinux 9<\/li>\n<li><strong>Python :<\/strong> version 3.10 minimum (3.12 recommand\u00e9 pour Fail2ban 1.1.0)<\/li>\n<li><strong>Acc\u00e8s root ou sudo<\/strong> sur la machine<\/li>\n<li><strong>Pare-feu actif :<\/strong> iptables, nftables ou firewalld selon votre distribution<\/li>\n<li><strong>Systemd :<\/strong> requis pour l&#8217;int\u00e9gration des journaux systemd (journald)<\/li>\n<li><strong>Services \u00e0 prot\u00e9ger :<\/strong> SSH install\u00e9 et actif (openssh-server)<\/li>\n<li><strong>Connectivit\u00e9 r\u00e9seau<\/strong> pour installer les paquets<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Important :<\/strong> ne lancez jamais ce tutoriel directement depuis une session SSH sans avoir d&#8217;abord configur\u00e9 votre propre adresse IP en liste blanche (<strong>ignoreip<\/strong>). Vous risqueriez de vous bloquer vous-m\u00eame.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"etape-1-installation-fail2ban\">\u00c9tape 1 : Installer Fail2ban sur Ubuntu\/Debian<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Sur les distributions bas\u00e9es sur Debian (Ubuntu 22.04, Ubuntu 24.04, Debian 11, Debian 12), l&#8217;installation est directe via APT :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Mise \u00e0 jour des d\u00e9p\u00f4ts\nsudo apt update\n\n# Installation de Fail2ban\nsudo apt install -y fail2ban\n\n# V\u00e9rification de la version install\u00e9e\nfail2ban-client --version<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Exemple de sortie attendue :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Fail2Ban v1.1.0\n\nCopyright (c) 2004-2024 Cyril Jaquier, Fail2Ban Contributors\nCopyright of modifications held by their respective authors.\nLicensed under the GNU General Public License v2 (GPL-2.0)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Sur <strong>CentOS Stream 9 \/ AlmaLinux 9 \/ Rocky Linux 9<\/strong>, utilisez le d\u00e9p\u00f4t EPEL :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Activer le d\u00e9p\u00f4t EPEL\nsudo dnf install -y epel-release\n\n# Installer Fail2ban\nsudo dnf install -y fail2ban\n\n# V\u00e9rifier l'installation\nfail2ban-client --version<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"etape-2-demarrage-systemd\">\u00c9tape 2 : D\u00e9marrer Fail2ban avec systemd<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban s&#8217;int\u00e8gre nativement avec systemd pour le d\u00e9marrage automatique et la surveillance des journaux. Activez et d\u00e9marrez le service :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Activer Fail2ban au d\u00e9marrage\nsudo systemctl enable fail2ban\n\n# D\u00e9marrer le service\nsudo systemctl start fail2ban\n\n# V\u00e9rifier l'\u00e9tat du service\nsudo systemctl status fail2ban<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Sortie attendue (service actif) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u25cf fail2ban.service - Fail2Ban Service\n     Loaded: loaded (\/lib\/systemd\/system\/fail2ban.service; enabled; vendor preset: enabled)\n     Active: active (running) since Tue 2026-06-17 10:00:00 UTC; 5s ago\n       Docs: man:fail2ban(1)\n   Main PID: 12345 (fail2ban-server)\n      Tasks: 5 (limit: 4915)\n     Memory: 18.3M\n        CPU: 154ms\n     CGroup: \/system.slice\/fail2ban.service\n             \u2514\u250012345 \/usr\/bin\/python3 \/usr\/bin\/fail2ban-server -xf start<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban consomme environ 18 \u00e0 25 Mo de m\u00e9moire RAM en fonctionnement normal, avec une charge CPU n\u00e9gligeable sur un serveur standard. Ce profil de ressources le rend adapt\u00e9 \u00e0 tous les types de serveurs, y compris les VPS d&#8217;entr\u00e9e de gamme \u00e0 512 Mo de RAM.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"etape-3-comprendre-jail-conf\">\u00c9tape 3 : Comprendre jail.conf et jail.local<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban utilise une architecture de configuration en deux niveaux, fondamentale \u00e0 comprendre avant toute modification :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\/etc\/fail2ban\/jail.conf<\/strong> : fichier de configuration principal g\u00e9r\u00e9 par le paquet. Ne le modifiez jamais directement. Il sera \u00e9cras\u00e9 lors des mises \u00e0 jour.<\/li>\n<li><strong>\/etc\/fail2ban\/jail.local<\/strong> : votre fichier de configuration locale, qui prend la priorit\u00e9 sur <code>jail.conf<\/code>. Cr\u00e9ez-le vous-m\u00eame pour vos personnalisations.<\/li>\n<li><strong>\/etc\/fail2ban\/jail.d\/<\/strong> : r\u00e9pertoire pour des fichiers de configuration fragment\u00e9s, un par service.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">La r\u00e8gle d&#8217;or : <strong>ne jamais toucher jail.conf, toujours travailler dans jail.local<\/strong>. Cette s\u00e9paration garantit que vos configurations personnalis\u00e9es survivent aux mises \u00e0 jour du paquet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inspectez d&#8217;abord les param\u00e8tres par d\u00e9faut dans jail.conf pour comprendre la structure :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Lire la configuration par d\u00e9faut (sans la modifier)\nsudo grep -A 20 '\\[DEFAULT\\]' \/etc\/fail2ban\/jail.conf | head -30<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Les param\u00e8tres cl\u00e9s de la section <code>[DEFAULT]<\/code> sont :<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Param\u00e8tre<\/th><th>Valeur par d\u00e9faut<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td>bantime<\/td><td>10m<\/td><td>Dur\u00e9e du bannissement (10 minutes)<\/td><\/tr><tr><td>findtime<\/td><td>10m<\/td><td>Fen\u00eatre de temps pour comptabiliser les \u00e9checs<\/td><\/tr><tr><td>maxretry<\/td><td>5<\/td><td>Nombre d&#8217;\u00e9checs avant bannissement<\/td><\/tr><tr><td>ignoreip<\/td><td>127.0.0.1\/8 ::1<\/td><td>IPs jamais bannies<\/td><\/tr><tr><td>backend<\/td><td>auto<\/td><td>M\u00e9canisme de surveillance des logs<\/td><\/tr><tr><td>usedns<\/td><td>warn<\/td><td>R\u00e9solution DNS pour les h\u00f4tes<\/td><\/tr><tr><td>destemail<\/td><td>root@localhost<\/td><td>Email destinataire des alertes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"etape-4-creer-jail-local\">\u00c9tape 4 : Cr\u00e9er votre fichier jail.local<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Cr\u00e9ez maintenant votre fichier <code>jail.local<\/code> avec une configuration de base s\u00e9curis\u00e9e. Adaptez l&#8217;adresse IP dans <code>ignoreip<\/code> avec votre propre IP publique avant de sauvegarder :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo nano \/etc\/fail2ban\/jail.local<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Contenu recommand\u00e9 pour un serveur de production :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[DEFAULT]\n# Votre IP d'administration - ne sera jamais bannie\n# Remplacez par votre vraie IP publique\nignoreip = 127.0.0.1\/8 ::1 203.0.113.0\/24\n\n# Dur\u00e9e de bannissement : 1 heure\nbantime = 3600\n\n# Fen\u00eatre de d\u00e9tection : 10 minutes\nfindtime = 600\n\n# Nombre maximum de tentatives avant bannissement\nmaxretry = 3\n\n# Backend de surveillance des logs\nbackend = systemd\n\n# R\u00e9solution DNS d\u00e9sactiv\u00e9e pour \u00e9viter les d\u00e9lais\nusedns = no\n\n# Encodage des logs\nlogencoding = utf-8\n\n# Action par d\u00e9faut (ban uniquement, sans email)\naction = %(action_)s\n\n[sshd]\nenabled = true\nport = ssh\nfilter = sshd\nbackend = systemd\nmaxretry = 3\nbantime = 3600\nfindtime = 600<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Apr\u00e8s avoir sauvegard\u00e9 le fichier, rechargez Fail2ban pour appliquer les changements :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl restart fail2ban\nsudo fail2ban-client status<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"etape-5-protection-ssh\">\u00c9tape 5 : Configurer la protection SSH<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SSH est le premier service \u00e0 prot\u00e9ger sur tout serveur expos\u00e9 \u00e0 internet. Le filtre int\u00e9gr\u00e9 <code>sshd<\/code> analyse <code>\/var\/log\/auth.log<\/code> (Debian\/Ubuntu) ou les journaux systemd pour d\u00e9tecter les tentatives d&#8217;authentification \u00e9chou\u00e9es.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">V\u00e9rifiez que le jail SSH est actif et consultez ses statistiques en temps r\u00e9el :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Statut g\u00e9n\u00e9ral de tous les jails actifs\nsudo fail2ban-client status\n\n# Statut d\u00e9taill\u00e9 du jail SSH\nsudo fail2ban-client status sshd<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Sortie typique apr\u00e8s quelques minutes de fonctionnement sur un serveur expos\u00e9 :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Status for the jail: sshd\n|- Filter\n|  |- Currently failed: 3\n|  |- Total failed: 147\n|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd\n`- Actions\n   |- Currently banned: 12\n   |- Total banned: 89\n   `- Banned IP list: 45.33.32.156 198.235.24.22 103.89.91.112 ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pour un port SSH non standard (par exemple 2222), modifiez la section <code>[sshd]<\/code> dans <code>jail.local<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[sshd]\nenabled = true\nport = 2222\nfilter = sshd\nbackend = systemd\nmaxretry = 3\nbantime = 86400\nfindtime = 3600<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Avec <code>bantime = 86400<\/code> (24 heures) et <code>maxretry = 3<\/code>, un attaquant qui \u00e9choue 3 fois en 1 heure est bloqu\u00e9 pendant 24 heures. C&#8217;est le r\u00e9glage recommand\u00e9 pour les serveurs de production soumis \u00e0 des attaques fr\u00e9quentes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"etape-6-protection-apache-nginx\">\u00c9tape 6 : Prot\u00e9ger Apache et Nginx<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Les serveurs web sont expos\u00e9s \u00e0 des scans permanents : tentatives de connexion \u00e0 des interfaces d&#8217;administration, exploitation de <code>wp-login.php<\/code>, recherche de fichiers sensibles. Fail2ban dispose de filtres int\u00e9gr\u00e9s pour Apache et Nginx.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"protection-apache\">Protection Apache<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Ajoutez ces jails dans votre <code>jail.local<\/code> pour une protection Apache multicouche :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[apache-auth]\nenabled = true\nport = http,https\nfilter = apache-auth\nlogpath = \/var\/log\/apache2\/error.log\nmaxretry = 5\nbantime = 3600\n\n[apache-noscript]\nenabled = true\nport = http,https\nfilter = apache-noscript\nlogpath = \/var\/log\/apache2\/error.log\nmaxretry = 6\nbantime = 86400\n\n[apache-overflows]\nenabled = true\nport = http,https\nfilter = apache-overflows\nlogpath = \/var\/log\/apache2\/error.log\nmaxretry = 2\nbantime = 86400\n\n[apache-nohome]\nenabled = true\nport = http,https\nfilter = apache-nohome\nlogpath = \/var\/log\/apache2\/error.log\nmaxretry = 2\nbantime = 86400<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"protection-nginx\">Protection Nginx<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Pour Nginx, les jails essentiels sont :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[nginx-http-auth]\nenabled = true\nport = http,https\nfilter = nginx-http-auth\nlogpath = \/var\/log\/nginx\/error.log\nmaxretry = 5\nbantime = 3600\n\n[nginx-botsearch]\nenabled = true\nport = http,https\nfilter = nginx-botsearch\nlogpath = \/var\/log\/nginx\/access.log\nmaxretry = 2\nbantime = 86400\nfindtime = 300<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Le filtre <code>nginx-botsearch<\/code> est particuli\u00e8rement efficace pour bloquer les scanners qui recherchent des fichiers <code>wp-login.php<\/code>, <code>xmlrpc.php<\/code>, <code>phpMyAdmin<\/code> et autres cibles classiques. Avec <code>maxretry = 2<\/code> et <code>findtime = 300<\/code> (5 minutes), m\u00eame un premier scan agressif d\u00e9clenche un bannissement imm\u00e9diat.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"etape-7-nftables-iptables\">\u00c9tape 7 : Choisir entre nftables, iptables et firewalld<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban applique les bannissements via des r\u00e8gles de pare-feu. En 2026, trois backends sont couramment utilis\u00e9s selon la distribution :<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Backend<\/th><th>Distribution typique<\/th><th>Action Fail2ban<\/th><th>Recommandation<\/th><\/tr><\/thead><tbody><tr><td>iptables<\/td><td>Ubuntu 22.04, Debian 11<\/td><td>iptables-multiport<\/td><td>Compatible universel<\/td><\/tr><tr><td>nftables<\/td><td>Ubuntu 24.04, Debian 12<\/td><td>nftables-multiport<\/td><td>Recommand\u00e9 (moderne)<\/td><\/tr><tr><td>firewalld<\/td><td>CentOS 9, AlmaLinux 9<\/td><td>firewallcmd-rich-rules<\/td><td>RHEL\/CentOS<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Pour v\u00e9rifier quel backend est disponible sur votre syst\u00e8me :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># V\u00e9rifier iptables\nwhich iptables && iptables --version\n\n# V\u00e9rifier nftables\nwhich nft && nft --version\n\n# V\u00e9rifier firewalld\nsystemctl is-active firewalld<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pour forcer l&#8217;utilisation de nftables sur Ubuntu 24.04, configurez l&#8217;action dans <code>jail.local<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[DEFAULT]\n# ...param\u00e8tres pr\u00e9c\u00e9dents...\n\n# Forcer nftables comme backend d'action\nbanaction = nftables-multiport\nbanaction_allports = nftables-allports<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Sur les syst\u00e8mes avec firewalld (Red Hat, CentOS, AlmaLinux) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[DEFAULT]\nbanaction = firewallcmd-rich-rules[actiontype=]\nbanaction_allports = firewallcmd-allports<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pour v\u00e9rifier qu&#8217;une r\u00e8gle de bannissement a bien \u00e9t\u00e9 appliqu\u00e9e via iptables apr\u00e8s qu&#8217;une IP a \u00e9t\u00e9 bannie :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo iptables -L f2b-sshd -n --line-numbers<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"etape-8-jail-recidive\">\u00c9tape 8 : Activer le jail recidive pour les r\u00e9cidivistes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Le jail <strong>recidive<\/strong> est une fonctionnalit\u00e9 avanc\u00e9e qui surveille le journal de Fail2ban lui-m\u00eame. Quand une IP est bannie plusieurs fois dans d&#8217;autres jails, recidive lui applique un bannissement beaucoup plus long. C&#8217;est le deuxi\u00e8me niveau de d\u00e9fense, id\u00e9al pour les attaquants persistants.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ajoutez cette section dans <code>jail.local<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[recidive]\nenabled = true\nfilter = recidive\nlogpath = \/var\/log\/fail2ban.log\naction = %(action_mwl)s\nbantime = 604800\nfindtime = 86400\nmaxretry = 5<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Avec cette configuration, une IP bannie 5 fois en 24 heures dans n&#8217;importe quel jail actif sera ensuite bannie pour 7 jours (604 800 secondes). Les IPs les plus agressives accumulent rapidement ces bans. L&#8217;action <code>%(action_mwl)s<\/code> bannit l&#8217;IP, envoie un email avec les lignes de log concern\u00e9es et effectue un <code>whois<\/code> de l&#8217;adresse IP.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pour les environnements particuli\u00e8rement cibl\u00e9s, certains administrateurs configurent <code>bantime = 2592000<\/code> (30 jours) pour les r\u00e9cidivistes les plus agressifs, comme dans l&#8217;exemple suivant pour un jail SSH ultra-strict :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[sshd-aggressive]\nenabled = true\nfilter = sshd\nbackend = systemd\nport = ssh\nmaxretry = 1\nbantime = 2592000\nfindtime = 86400\naction = %(action_mwl)s<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Notez que <code>maxretry = 1<\/code> est une approche radicale : la moindre tentative \u00e9chou\u00e9e sur SSH d\u00e9clenche un bannissement de 30 jours. Adaptez selon votre tol\u00e9rance aux faux positifs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"etape-9-notifications-email\">\u00c9tape 9 : Configurer les notifications par email<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban peut envoyer des alertes par email \u00e0 chaque bannissement ou d\u00e9bannissement. Pour l&#8217;activer, votre serveur doit disposer d&#8217;un MTA (mail transfer agent) fonctionnel, comme <code>postfix<\/code> ou <code>sendmail<\/code>. V\u00e9rifiez que <code>sendmail<\/code> est disponible :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>which sendmail && sendmail --version 2>&1 | head -3<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Configurez les emails dans <code>jail.local<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[DEFAULT]\n# Email de l'exp\u00e9diteur (adapter \u00e0 votre domaine)\nsender = fail2ban@votredomaine.fr\n\n# Email destinataire des alertes\ndestemail = admin@votredomaine.fr\n\n# MTA utilis\u00e9 pour l'envoi\nmta = sendmail\n\n# Action avec email + whois lors d'un ban\naction = %(action_mwl)s<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Les actions disponibles pour l&#8217;email sont :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>%(action_)s<\/code> : ban uniquement, pas d&#8217;email<\/li>\n<li><code>%(action_m)s<\/code> : ban + email de notification simple<\/li>\n<li><code>%(action_mw)s<\/code> : ban + email + informations whois<\/li>\n<li><code>%(action_mwl)s<\/code> : ban + email + whois + lignes de log pertinentes<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Pour un jail sp\u00e9cifique avec des emails uniquement pour les bannissements SSH (et pas pour les tentatives web mineures), appliquez l&#8217;action selectively :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[sshd]\nenabled = true\nport = ssh\nfilter = sshd\nbackend = systemd\nmaxretry = 3\nbantime = 3600\naction = %(action_mwl)s\n\n[nginx-botsearch]\nenabled = true\nport = http,https\nfilter = nginx-botsearch\nlogpath = \/var\/log\/nginx\/access.log\nmaxretry = 2\nbantime = 86400\n# Pas d'email pour ce jail (trop de volume)\naction = %(action_)s<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"etape-10-gestion-des-bans\">\u00c9tape 10 : G\u00e9rer les bannissements manuellement<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La commande <code>fail2ban-client<\/code> est votre interface principale pour g\u00e9rer les bannissements en temps r\u00e9el, sans avoir \u00e0 red\u00e9marrer le service.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Commandes essentielles pour la gestion quotidienne :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Lister tous les jails actifs\nsudo fail2ban-client status\n\n# Voir les IPs bannies dans le jail SSH\nsudo fail2ban-client status sshd\n\n# D\u00e9bannir une IP sp\u00e9cifique du jail SSH\nsudo fail2ban-client set sshd unbanip 203.0.113.42\n\n# Bannir manuellement une IP dans le jail SSH\nsudo fail2ban-client set sshd banip 198.51.100.10\n\n# Recharger la configuration sans red\u00e9marrage\nsudo fail2ban-client reload\n\n# Recharger un jail sp\u00e9cifique seulement\nsudo fail2ban-client reload sshd\n\n# V\u00e9rifier si une IP est bannie (dans tous les jails)\nsudo fail2ban-client banned 198.51.100.10\n\n# Voir le log de Fail2ban en temps r\u00e9el\nsudo tail -f \/var\/log\/fail2ban.log<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Exemple de sortie du log en temps r\u00e9el lors d&#8217;une attaque :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code\">2026-06-17 10:15:32,421 fail2ban.filter         [12345]: INFO    [sshd] Found 45.33.32.156 - 2026-06-17 10:15:32\n2026-06-17 10:15:34,102 fail2ban.filter         [12345]: INFO    [sshd] Found 45.33.32.156 - 2026-06-17 10:15:34\n2026-06-17 10:15:35,887 fail2ban.filter         [12345]: INFO    [sshd] Found 45.33.32.156 - 2026-06-17 10:15:35\n2026-06-17 10:15:35,901 fail2ban.actions        [12345]: NOTICE  [sshd] Ban 45.33.32.156\n2026-06-17 10:20:35,103 fail2ban.actions        [12345]: NOTICE  [sshd] Unban 45.33.32.156<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"etape-11-filtres-personnalises\">\u00c9tape 11 : Cr\u00e9er un filtre personnalis\u00e9<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban inclut des dizaines de filtres pr\u00e9d\u00e9finis dans <code>\/etc\/fail2ban\/filter.d\/<\/code>, mais vous pouvez en cr\u00e9er de nouveaux pour vos applications sp\u00e9cifiques. Les filtres utilisent des expressions r\u00e9guli\u00e8res Python pour identifier les lignes de log malveillantes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Exemple : cr\u00e9er un filtre pour prot\u00e9ger une application Node.js qui enregistre les tentatives d&#8217;authentification \u00e9chou\u00e9es dans un format personnalis\u00e9. Supposons que les logs contiennent des lignes comme :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code\">2026-06-17 10:15:32 AUTH_FAIL ip=203.0.113.42 user=admin reason=bad_password<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cr\u00e9ez le fichier filtre :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo nano \/etc\/fail2ban\/filter.d\/nodejs-auth.conf<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>[Definition]\n# Filtre pour les \u00e9checs d'authentification Node.js\nfailregex = ^.* AUTH_FAIL ip=<HOST> .*$\n\n# Lignes \u00e0 ignorer (succ\u00e8s, red\u00e9marrages)\nignoreregex = ^.* AUTH_SUCCESS .*$<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Puis ajoutez le jail correspondant dans <code>jail.local<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[nodejs-auth]\nenabled = true\nfilter = nodejs-auth\nlogpath = \/var\/log\/myapp\/auth.log\nmaxretry = 5\nbantime = 3600\nfindtime = 300\nport = 3000<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Testez votre filtre avec <code>fail2ban-regex<\/code> avant de l&#8217;activer en production :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Tester le filtre contre un fichier de log existant\nsudo fail2ban-regex \/var\/log\/myapp\/auth.log \/etc\/fail2ban\/filter.d\/nodejs-auth.conf\n\n# Tester avec une ligne de log directement\nsudo fail2ban-regex \"2026-06-17 10:15:32 AUTH_FAIL ip=203.0.113.42 user=admin reason=bad_password\" \/etc\/fail2ban\/filter.d\/nodejs-auth.conf<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Sortie attendue si le filtre fonctionne :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code\">Running tests\n=============\n\nUse   failregex filter file : nodejs-auth, basedir: \/etc\/fail2ban\nUse         log file : 2026-06-17 10:15:32 AUTH_FAIL ip=203.0.113.42 user=admin reason=bad_password\nUse         encoding : UTF-8\n\nResults\n=======\n\nFailregex: 1 total\n|-  #) [# of hits] regular expression\n|   1) [1] ^.* AUTH_FAIL ip=<HOST> .*$\n`-\n\nIgnoreregex: 0 total\n\nDate template hits:\n|- [# of hits] date format\n|  [1] ExYear(?P<Y>Year)-(?P<M>Month)-(?P<D>Day)(?:T|  +)...\n`-\n\nLines: 1 lines, 0 ignored, 1 matched, 0 missed<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"etape-12-bantime-increment\">\u00c9tape 12 : Bannissements progressifs avec bantime.increment<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La fonctionnalit\u00e9 <strong>bantime.increment<\/strong> permet d&#8217;allonger automatiquement la dur\u00e9e de bannissement \u00e0 chaque r\u00e9cidive d&#8217;une m\u00eame IP. C&#8217;est l&#8217;une des \u00e9volutions les plus importantes de Fail2ban, qui transforme un outil de protection r\u00e9actif en un syst\u00e8me adaptatif.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Activez les bannissements progressifs dans <code>jail.local<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[DEFAULT]\n# Activer les bannissements progressifs\nbantime.increment = true\n\n# Dur\u00e9e de base du premier bannissement\nbantime = 600\n\n# Multiplicateur appliqu\u00e9 \u00e0 chaque r\u00e9cidive (x2 par d\u00e9faut)\nbantime.factor = 2\n\n# Dur\u00e9e maximum du bannissement (1 semaine)\nbantime.maxtime = 604800\n\n# Formule de calcul : base * factor^(nombre de bans pr\u00e9c\u00e9dents)\n# 1er ban : 600s (10 min)\n# 2e ban : 1200s (20 min)\n# 3e ban : 2400s (40 min)\n# 4e ban : 4800s (1h20)\n# 5e ban : 9600s (2h40)\n# ... jusqu'au maximum de 604800s (7 jours)\n\n# Utiliser la base de donn\u00e9es SQLite pour m\u00e9moriser les r\u00e9cidives\ndbfile = \/var\/lib\/fail2ban\/fail2ban.sqlite3\ndbpurgeage = 86400<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cette configuration transforme Fail2ban en un syst\u00e8me d&#8217;apprentissage simple : les attaquants qui reviennent r\u00e9guli\u00e8rement font face \u00e0 des bans exponentiellement plus longs. La base de donn\u00e9es SQLite conserve l&#8217;historique des bannissements pour que la m\u00e9moire persiste m\u00eame apr\u00e8s un red\u00e9marrage du service.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"pieges-frequents\">5 pi\u00e8ges fr\u00e9quents (et comment les \u00e9viter)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ces erreurs reviennent syst\u00e9matiquement lors de la configuration de Fail2ban. Identifiez-les avant qu&#8217;elles ne causent des probl\u00e8mes en production.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"piege-1-se-bloquer-soi-meme\">Pi\u00e8ge 1 : Se bloquer soi-m\u00eame via SSH<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sympt\u00f4me :<\/strong> vous perdez l&#8217;acc\u00e8s SSH \u00e0 votre propre serveur apr\u00e8s avoir configur\u00e9 Fail2ban.<br><strong>Cause :<\/strong> votre IP d&#8217;administration n&#8217;est pas dans <code>ignoreip<\/code>, et vous avez mal tap\u00e9 votre mot de passe 3 fois pendant la configuration.<br><strong>Solution pr\u00e9ventive :<\/strong> avant d&#8217;activer Fail2ban, ajoutez imp\u00e9rativement votre IP publique dans <code>ignoreip<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Trouver votre IP publique depuis le serveur\ncurl -s ifconfig.me\n\n# Puis dans jail.local :\nignoreip = 127.0.0.1\/8 ::1 VOTRE_IP_ICI<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Solution curative :<\/strong> si vous \u00eates bloqu\u00e9, acc\u00e9dez au serveur via la console KVM\/IPMI de votre h\u00e9bergeur, ou via VNC, puis d\u00e9bannissez votre IP depuis le shell local.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"piege-2-modifier-jail-conf\">Pi\u00e8ge 2 : Modifier jail.conf directement<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sympt\u00f4me :<\/strong> vos configurations disparaissent apr\u00e8s une mise \u00e0 jour de Fail2ban.<br><strong>Cause :<\/strong> vous avez modifi\u00e9 <code>\/etc\/fail2ban\/jail.conf<\/code> au lieu de cr\u00e9er <code>jail.local<\/code>.<br><strong>Solution :<\/strong> toujours cr\u00e9er un fichier <code>jail.local<\/code> pour vos personnalisations. La r\u00e8gle est absolue.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"piege-3-backend-incompatible\">Pi\u00e8ge 3 : Utiliser le mauvais backend de log<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sympt\u00f4me :<\/strong> Fail2ban ne d\u00e9tecte aucune tentative malgr\u00e9 des attaques visibles dans les logs.<br><strong>Cause :<\/strong> le param\u00e8tre <code>backend<\/code> est mal configur\u00e9. Sur Ubuntu 22.04+ avec systemd, les logs SSH ne sont pas dans <code>\/var\/log\/auth.log<\/code> par d\u00e9faut, mais dans le journal systemd.<br><strong>Solution :<\/strong> utilisez <code>backend = systemd<\/code> et v\u00e9rifiez avec :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># V\u00e9rifier les logs SSH dans journald\nsudo journalctl -u sshd --since \"1 hour ago\" | grep \"Failed password\" | head -5\n\n# Si des lignes apparaissent, journald fonctionne pour SSH\n# Dans jail.local :\n[sshd]\nbackend = systemd<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"piege-4-regex-incorrect\">Pi\u00e8ge 4 : Regex de filtre incorrect (faux n\u00e9gatifs)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sympt\u00f4me :<\/strong> un jail est actif mais ne banne jamais personne, m\u00eame lors d&#8217;attaques \u00e9videntes.<br><strong>Cause :<\/strong> la regex <code>failregex<\/code> ne correspond pas au format de log r\u00e9el de votre version du service.<br><strong>Solution :<\/strong> testez toujours votre filtre avec <code>fail2ban-regex<\/code> avant de l&#8217;activer :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Tester le filtre sshd contre les vrais logs\nsudo fail2ban-regex \/var\/log\/auth.log \/etc\/fail2ban\/filter.d\/sshd.conf --print-all-matched | tail -20<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"piege-5-bantime-trop-court\">Pi\u00e8ge 5 : bantime trop court face aux botnets distribu\u00e9s<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sympt\u00f4me :<\/strong> Fail2ban banne des centaines d&#8217;IPs diff\u00e9rentes mais les attaques continuent sans rel\u00e2che.<br><strong>Cause :<\/strong> les botnets modernes utilisent des milliers d&#8217;IPs rotatives. Un <code>bantime<\/code> de 10 minutes est inefficace face \u00e0 un botnet de 50 000 IPs qui revient avec une IP diff\u00e9rente toutes les 15 minutes.<br><strong>Solution :<\/strong> combinez un <code>bantime<\/code> long (24h minimum), le jail <code>recidive<\/code>, et <code>bantime.increment = true<\/code>. Envisagez \u00e9galement de bloquer des plages d&#8217;ASN enti\u00e8res pour les attaquants r\u00e9currents.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"depannage\">8 probl\u00e8mes de d\u00e9pannage courants<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Probl\u00e8me<\/th><th>Diagnostic<\/th><th>Solution<\/th><\/tr><\/thead><tbody><tr><td>fail2ban ne d\u00e9marre pas<\/td><td><code>sudo journalctl -u fail2ban -n 50<\/code><\/td><td>V\u00e9rifier la syntaxe de jail.local (souvent une virgule ou espace manquant)<\/td><\/tr><tr><td>Jail inactif apr\u00e8s reload<\/td><td><code>sudo fail2ban-client status<\/code><\/td><td>V\u00e9rifier <code>enabled = true<\/code> dans le jail et red\u00e9marrer (pas juste reload)<\/td><\/tr><tr><td>Aucun ban d\u00e9tect\u00e9<\/td><td><code>sudo fail2ban-regex \/var\/log\/auth.log sshd<\/code><\/td><td>V\u00e9rifier que le filtre correspond aux logs, changer backend<\/td><\/tr><tr><td>IP bannie mais toujours accessible<\/td><td><code>sudo iptables -L f2b-sshd -n<\/code><\/td><td>V\u00e9rifier la cha\u00eene iptables, tester avec nftables si disponible<\/td><\/tr><tr><td>Se retrouver banni<\/td><td>Console KVM de l&#8217;h\u00e9bergeur<\/td><td><code>sudo fail2ban-client set sshd unbanip MON_IP<\/code><\/td><\/tr><tr><td>Trop de faux positifs<\/td><td><code>sudo tail -f \/var\/log\/fail2ban.log<\/code><\/td><td>Augmenter maxretry, r\u00e9duire findtime, ajouter l&#8217;IP dans ignoreip<\/td><\/tr><tr><td>Fail2ban consomme trop de CPU<\/td><td><code>top -p $(pgrep fail2ban-server)<\/code><\/td><td>R\u00e9duire le nombre de jails actifs ou utiliser backend systemd<\/td><\/tr><tr><td>Base de donn\u00e9es SQLite corrompue<\/td><td><code>sudo sqlite3 \/var\/lib\/fail2ban\/fail2ban.sqlite3 \".tables\"<\/code><\/td><td>Arr\u00eater fail2ban, supprimer le .sqlite3, red\u00e9marrer<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Pour un diagnostic complet de Fail2ban, activez le mode debug temporairement :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Arr\u00eater le service\nsudo systemctl stop fail2ban\n\n# Lancer en mode debug (foreground)\nsudo fail2ban-server -f -x -l DEBUG\n\n# Dans un autre terminal, surveiller les sorties\n# Appuyer sur Ctrl+C pour arr\u00eater, puis relancer normalement :\nsudo systemctl start fail2ban<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"configuration-compl\u00e8te-production\">Configuration compl\u00e8te pour un serveur de production<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Voici un fichier <code>jail.local<\/code> complet et op\u00e9rationnel pour un serveur web de production h\u00e9bergeant SSH, Nginx et WordPress. Copiez-le, adaptez l&#8217;adresse IP et le domaine, et vous disposerez d&#8217;une protection multi-couches imm\u00e9diatement fonctionnelle :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code\">[DEFAULT]\n# Remplacez par votre IP d'administration\nignoreip = 127.0.0.1\/8 ::1 203.0.113.0\/24\n\n# Bannissements progressifs\nbantime = 3600\nbantime.increment = true\nbantime.factor = 2\nbantime.maxtime = 604800\n\n# Fen\u00eatre et seuil de d\u00e9tection\nfindtime = 600\nmaxretry = 3\n\n# Backend systemd (recommand\u00e9 Ubuntu 22.04+)\nbackend = systemd\n\n# Pas de r\u00e9solution DNS pour les performances\nusedns = no\n\n# Base de donn\u00e9es pour la persistance des bans\ndbfile = \/var\/lib\/fail2ban\/fail2ban.sqlite3\ndbpurgeage = 86400\n\n# Action par d\u00e9faut sans email\naction = %(action_)s\n\n# --- SSH ---\n[sshd]\nenabled = true\nport = ssh\nfilter = sshd\nbackend = systemd\nmaxretry = 3\nbantime = 3600\naction = %(action_mwl)s\ndestemail = admin@votredomaine.fr\nsender = fail2ban@votredomaine.fr\n\n# --- NGINX ---\n[nginx-http-auth]\nenabled = true\nport = http,https\nfilter = nginx-http-auth\nlogpath = \/var\/log\/nginx\/error.log\nmaxretry = 5\nbantime = 3600\n\n[nginx-botsearch]\nenabled = true\nport = http,https\nfilter = nginx-botsearch\nlogpath = \/var\/log\/nginx\/access.log\nmaxretry = 2\nbantime = 86400\nfindtime = 300\n\n# --- R\u00c9CIDIVISTES ---\n[recidive]\nenabled = true\nfilter = recidive\nlogpath = \/var\/log\/fail2ban.log\nbantime = 604800\nfindtime = 86400\nmaxretry = 5<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conseils-avances\">Conseils avanc\u00e9s pour aller plus loin<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Une fois la configuration de base en place, ces optimisations avanc\u00e9es renforceront significativement la protection de votre serveur.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Int\u00e9grer des listes de blocage externes (threatfeeds) :<\/strong> combinez Fail2ban avec des listes de menaces connues comme AbuseIPDB. Un script cron peut t\u00e9l\u00e9charger quotidiennement les IP \u00e0 fort score de menace et les injecter directement dans un jail Fail2ban via <code>fail2ban-client set jail banip<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Surveiller les m\u00e9triques avec Prometheus :<\/strong> l&#8217;exporteur officiel <code>fail2ban-exporter<\/code> expose des m\u00e9triques Prometheus sur le nombre de bans actifs, le total de bans par jail, et la dur\u00e9e moyenne des bannissements. C&#8217;est particuli\u00e8rement utile pour Grafana et les tableaux de bord de s\u00e9curit\u00e9.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Partager les bannissements entre plusieurs serveurs :<\/strong> si vous g\u00e9rez une infrastructure multi-serveurs, utilisez une base de donn\u00e9es MySQL ou PostgreSQL partag\u00e9e \u00e0 la place de SQLite. Configurez <code>dbfile = mysql:\/\/user:pass@host\/fail2ban<\/code> pour que tous vos serveurs partagent le m\u00eame historique de r\u00e9cidives.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Bloquer les scanners Shodan et Censys :<\/strong> cr\u00e9ez un jail sp\u00e9cifique pour bannir automatiquement les plages d&#8217;IP connues des scanners l\u00e9gaux comme Shodan (plages 198.20.0.0\/16) qui, bien qu&#8217;inoffensifs, g\u00e9n\u00e8rent du bruit dans vos logs et peuvent masquer de vraies attaques.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Combiner avec fail2ban-geoip-stats :<\/strong> l&#8217;outil <code>fail2ban-geoip-stats<\/code> g\u00e9n\u00e8re des statistiques g\u00e9ographiques des IP bannies et produit des rapports HTML hebdomadaires. Il permet d&#8217;identifier les pays d&#8217;origine des attaques les plus fr\u00e9quentes pour affiner votre strat\u00e9gie de blocage.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"faq\">Questions fr\u00e9quentes (FAQ)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"fail2ban-ralentit-il-mon-serveur\">Fail2ban ralentit-il mon serveur ?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Non. En fonctionnement normal, Fail2ban consomme entre 18 et 25 Mo de RAM et moins de 1 % de CPU. L&#8217;impact sur les performances est n\u00e9gligeable, m\u00eame sur un VPS \u00e0 1 vCPU. Le seul sc\u00e9nario o\u00f9 la charge augmente est lors d&#8217;attaques massives g\u00e9n\u00e9rant des milliers de lignes de log par seconde.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"faut-il-utiliser-fail2ban-avec-un-pare-feu-dedie-comme-ufw\">Faut-il utiliser Fail2ban avec un pare-feu d\u00e9di\u00e9 comme UFW ?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Oui, les deux sont compl\u00e9mentaires. UFW (ou firewalld sur RHEL) g\u00e8re les r\u00e8gles statiques permanentes : ports ouverts, flux autoris\u00e9s. Fail2ban g\u00e8re les r\u00e8gles dynamiques temporaires : bannissements bas\u00e9s sur le comportement. Sur Ubuntu 22.04+, UFW et Fail2ban coexistent sans conflit, mais v\u00e9rifiez que les deux n&#8217;entrent pas en conflit sur la cha\u00eene INPUT d&#8217;iptables.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"quelle-est-la-difference-entre-bantime-findtime-et-maxretry\">Quelle est la diff\u00e9rence entre bantime, findtime et maxretry ?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>findtime<\/code> est la fen\u00eatre de temps (en secondes) pendant laquelle Fail2ban compte les tentatives \u00e9chou\u00e9es. <code>maxretry<\/code> est le nombre maximum d&#8217;\u00e9checs autoris\u00e9s dans cette fen\u00eatre avant un bannissement. <code>bantime<\/code> est la dur\u00e9e du bannissement une fois d\u00e9clench\u00e9. Exemple : <code>findtime=600, maxretry=5, bantime=3600<\/code> signifie que 5 \u00e9checs en 10 minutes entra\u00eenent un bannissement d&#8217;1 heure.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"comment-verifier-que-fail2ban-fonctionne-reellement\">Comment v\u00e9rifier que Fail2ban fonctionne r\u00e9ellement ?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Utilisez <code>sudo fail2ban-client status sshd<\/code> pour voir le nombre de bans actifs et le total de tentatives d\u00e9tect\u00e9es. Surveillez <code>\/var\/log\/fail2ban.log<\/code> pour les entr\u00e9es NOTICE de type &#8220;Ban [IP]&#8221;. Si le &#8220;Total failed&#8221; augmente et que des &#8220;Ban&#8221; apparaissent, Fail2ban fonctionne correctement.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"peut-on-utiliser-fail2ban-avec-ipv6\">Peut-on utiliser Fail2ban avec IPv6 ?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Oui. Fail2ban supporte nativement IPv4 et IPv6. Assurez-vous que votre action iptables est configur\u00e9e pour les deux protocoles, ou utilisez l&#8217;action <code>iptables-allports<\/code> combin\u00e9e avec ip6tables. Avec nftables, le support IPv6 est natif et transparent.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"fail2ban-suffit-il-pour-securiser-un-serveur\">Fail2ban suffit-il pour s\u00e9curiser un serveur ?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Non. Fail2ban est un outil de mitigation, pas une solution de s\u00e9curit\u00e9 compl\u00e8te. Il compl\u00e8te mais ne remplace pas : l&#8217;authentification par cl\u00e9 SSH (d\u00e9sactiver les mots de passe), les mises \u00e0 jour de s\u00e9curit\u00e9 r\u00e9guli\u00e8res, un pare-feu strict (UFW\/firewalld), la surveillance des vuln\u00e9rabilit\u00e9s avec des outils comme Nmap, et la gestion des acc\u00e8s par le principe du moindre privil\u00e8ge.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"fail2ban-est-il-compatible-avec-les-conteneurs-docker\">Fail2ban est-il compatible avec les conteneurs Docker ?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Avec pr\u00e9caution. Fail2ban doit \u00eatre install\u00e9 sur l&#8217;h\u00f4te Docker, pas dans un conteneur. Il doit acc\u00e9der aux logs des conteneurs (mont\u00e9s via volumes) et aux tables iptables de l&#8217;h\u00f4te. Les r\u00e8gles Fail2ban n&#8217;affectent pas les r\u00e8gles iptables de Docker par d\u00e9faut, donc une configuration sp\u00e9cifique est n\u00e9cessaire pour que les bans bloquent \u00e9galement le trafic vers les ports mapp\u00e9s.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"comment-migrer-de-iptables-vers-nftables-avec-fail2ban\">Comment migrer de iptables vers nftables avec Fail2ban ?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Installez nftables (<code>sudo apt install nftables<\/code>), activez le service (<code>sudo systemctl enable nftables<\/code>), puis dans <code>jail.local<\/code> changez <code>banaction = nftables-multiport<\/code> et <code>banaction_allports = nftables-allports<\/code>. Red\u00e9marrez Fail2ban. V\u00e9rifiez les r\u00e8gles cr\u00e9\u00e9es avec <code>sudo nft list ruleset<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"liens-internes\">Couverture associ\u00e9e<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"articles-connexes\">Articles connexes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"\/fr\/openssl-cles-certificats-tutoriel\/\">OpenSSL : cl\u00e9s et certificats en 12 \u00e9tapes<\/a> &#8211; G\u00e9n\u00e9rer des cl\u00e9s priv\u00e9es et des certificats TLS\/SSL avec OpenSSL<\/li>\n<li><a href=\"\/fr\/nmap-scanner-reseau-tutoriel\/\">Nmap : scanner un r\u00e9seau en 12 \u00e9tapes<\/a> &#8211; Identifier les ports ouverts et vuln\u00e9rabilit\u00e9s sur votre infrastructure<\/li>\n<li><a href=\"\/fr\/ssh-keygen-cle-ssh-authentification\/\">ssh-keygen : cl\u00e9 SSH en 12 \u00e9tapes, 20 min<\/a> &#8211; S\u00e9curiser SSH avec des cl\u00e9s cryptographiques plut\u00f4t que des mots de passe<\/li>\n<li><a href=\"\/fr\/oauth2-openid-connect-nodejs\/\">OAuth2 en Node.js : flux s\u00e9curis\u00e9 en 12 \u00e9tapes<\/a> &#8211; Impl\u00e9menter l&#8217;authentification moderne dans vos applications web<\/li>\n<li><a href=\"\/fr\/faille-idor-services-publics-france-2026\/\">Faille IDOR : 31 millions de comptes publics expos\u00e9s<\/a> &#8211; Comprendre les vuln\u00e9rabilit\u00e9s d&#8217;acc\u00e8s aux objets pour mieux les pr\u00e9venir<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Chaque jour, vos serveurs Linux encaissent des milliers de tentatives de connexion automatis\u00e9es. SSH, Apache, Nginx, Postfix : chaque service expos\u00e9 devient une cible pour les bots de force brute.\u2026<\/p>\n","protected":false},"author":3,"featured_media":205,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,3],"tags":[],"class_list":["post-204","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-10","category-security"],"_links":{"self":[{"href":"https:\/\/shattered.io\/fr\/wp-json\/wp\/v2\/posts\/204","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/shattered.io\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/shattered.io\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/shattered.io\/fr\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/shattered.io\/fr\/wp-json\/wp\/v2\/comments?post=204"}],"version-history":[{"count":1,"href":"https:\/\/shattered.io\/fr\/wp-json\/wp\/v2\/posts\/204\/revisions"}],"predecessor-version":[{"id":206,"href":"https:\/\/shattered.io\/fr\/wp-json\/wp\/v2\/posts\/204\/revisions\/206"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/shattered.io\/fr\/wp-json\/wp\/v2\/media\/205"}],"wp:attachment":[{"href":"https:\/\/shattered.io\/fr\/wp-json\/wp\/v2\/media?parent=204"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/shattered.io\/fr\/wp-json\/wp\/v2\/categories?post=204"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/shattered.io\/fr\/wp-json\/wp\/v2\/tags?post=204"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}