On ne remarque pas les attaques par force brute sur la messagerie quand elles sont faibles. On les remarque quand le journal IMAP devient un dispositif de déni de service, les ventilateurs CPU commencent à faire du bruit comme un drone, et les utilisateurs jurent que «rien n’a changé» pendant que Outlook retente indéfiniment le même mot de passe.
Fail2ban peut aider. Il peut aussi nuire — silencieusement — en bannissant votre PDG en plein conseil d’administration parce que l’application mail de son téléphone a mis en cache un mauvais mot de passe pendant huit heures. La différence n’est pas «installer fail2ban». La différence tient aux règles, à la tuyauterie des logs et à un déploiement qui respecte la réalité de la production.
Ce contre quoi vous vous défendez réellement
Les serveurs mail attirent les attaquants pour des raisons ennuyeuses : les identifiants ont de la valeur, SMTP est omniprésent, et la réutilisation des mots de passe est une source d’énergie renouvelable pour les assaillants. Les «attaques» les plus volumineuses que vous verrez ne sont généralement pas sophistiquées. Elles sont bruyantes, répétitives et rentables parce qu’un opérateur mise sur un compte faible sur mille.
Schémas d’attaque courants sur lesquels il vaut la peine de bannir
- Brute force d’authentification IMAP/POP (Dovecot, Courier) : échecs de connexion répétés contre des noms d’utilisateur réels.
- Brute force SMTP AUTH (Postfix SASL, Exim) : échecs SASL répétés, souvent depuis des botnets.
- Brute force interface web / admin (Roundcube, Rspamd WebUI, mailcow admin, panneaux personnalisés) : devinettes de mots de passe et sondages de sessions.
- Abus du protocole SMTP : HELO invalides, abus de pipelining, attaques par dictionnaire sur «RCPT TO». Parfois c’est du scan de spam ; parfois c’est le prélude à un abus.
- Credential stuffing : peu de tentatives par IP. C’est là que des configurations naïves de fail2ban échouent, car chaque IP reste sous votre seuil.
Ce pour quoi fail2ban est efficace (et ce qu’il n’est pas)
Fail2ban excelle à limiter le débit par IP à partir des logs. Si votre attaquant utilise une seule IP pour marteler l’authentification, vous pouvez le couper rapidement. S’il répartit les tentatives sur des milliers d’IP, fail2ban devient moins décisif ; dans ce cas, vous avez besoin de contrôles en amont (greylisting, réputation, limites de débit, CAPTCHA sur les interfaces web, MFA ou filtrage côté fournisseur).
Autre point : fail2ban ne remplace pas une sécurité mail correcte. Vous avez toujours besoin de politiques de mot de passe robustes, de MFA quand c’est possible, de désactiver l’auth en clair quand vous le pouvez, et d’une exposition raisonnable (ne publiez pas les panneaux d’administration sur Internet si vous pouvez l’éviter).
Faits intéressants et histoire (les attaques mail n’ont pas commencé hier)
- SMTP précède l’authentification moderne. SMTP a été conçu au début des années 1980 pour des réseaux coopératifs ; l’ajout d’auth et de TLS est venu bien plus tard.
- Les «open relays» étaient autrefois la norme. Dans les années 1990, de nombreux MTAs relaiaient le courrier librement ; le spam a transformé cela en un problème et a entraîné des restrictions de relais généralisées.
- Le greylisting est devenu populaire au début des années 2000. Il exploitait le fait que les MTAs légitimes réessaient la livraison ; beaucoup de bots de spam ne le faisaient pas.
- SASL est plus ancien que beaucoup ne le pensent. Simple Authentication and Security Layer date de la fin des années 1990 et visait à standardiser l’authentification entre protocoles.
- fail2ban a émergé au milieu des années 2000. Il a surfé sur la vague de «l’automatisation pilotée par les logs» sous Linux — simple, efficace, et dangereusement facile à mal configurer.
- Les botnets sont passés d’une source unique à des attaques distribuées. Le credential stuffing actuel utilise souvent de nombreuses IP avec peu de tentatives par IP, réduisant la valeur des bans IP naïfs.
- Journald a changé la donne pour le parsing des logs. Quand les systèmes sont passés des fichiers plats aux logs structurés, les outils supposant /var/log/* ont dû s’adapter.
- IPv6 a rendu «bannir le /24» obsolète. Les attaquants peuvent faire pivoter les adresses sur d’immenses plages, et bannir IPv6 imprudemment peut casser des réseaux légitimes.
- Le mail reste un vecteur majeur de compromission. Pas parce que SMTP est magique, mais parce que les identifiants ouvrent les réinitialisations de mot de passe, les factures et la confiance interne.
Bien configurer les logs d’abord (sinon fail2ban est un placebo)
Fail2ban ne peut agir que sur ce qu’il voit. La plupart des tickets «fail2ban ne marche pas» se résument à l’un des trois problèmes suivants :
- Le service n’enregistre pas les échecs d’auth de façon analysable.
- Les logs vont quelque part que fail2ban ne surveille pas (journald vs fichiers, conteneurs, chroot, syslog réparti).
- La regex ne correspond pas aux lignes réelles (parce que le format de log de votre distribution diffère du modèle mental de l’auteur).
Choisissez votre backend : fichier ou systemd/journald
Sur les distributions modernes, vous voulez souvent le backend systemd pour ne pas courir après des fichiers rotatés et des permissions. Mais si vos MTA écrivent dans des fichiers syslog classiques, le tailing de fichiers suffit. Choisissez-en un par hôte et restez cohérent ; les configurations hybrides sont l’endroit où le dépannage vient mourir.
Également : considérez que les systèmes mail sont fréquemment répartis entre conteneurs ou VM séparées. Si Postfix tourne dans un conteneur et Dovecot dans un autre, fail2ban dans un troisième conteneur ne verra pas les logs à moins que vous ne les acheminez. Votre message «jail enabled» ne veut rien dire s’il regarde une pièce vide.
Blague #1 : La seule chose plus fiable qu’un bot de brute force est un cadre qui «n’a rien changé» juste avant l’incident.
Jails mail qui détectent de vraies attaques
Ci‑dessous des jails qui tendent à fonctionner sur des stacks Postfix + Dovecot du monde réel, plus quelques cibles web liées au mail. L’objectif n’est pas «bannir tout». L’objectif est : bannir rapidement les abus à haute confiance, et traiter les signaux ambigus avec prudence.
Hypothèses de base
- Vous utilisez fail2ban 0.11+ (les versions récentes sont meilleures, surtout pour les améliorations du backend systemd).
- Vos actions de pare‑feu sont cohérentes : nftables sur Debian/Ubuntu modernes, firewalld sur systèmes RHEL‑like, iptables sur installations plus anciennes.
- Vos services mail journalisent l’IP cliente sur la même ligne que l’échec (ou sur une ligne corrélée que le filtre gère).
Échecs SASL Postfix (brute force SMTP AUTH)
Ce jail bannit les échecs répétés d’authentification SASL, qui sont des événements à fort signal. Il attrape l’attaque classique «essayer 10 mots de passe pour user@domain» rapidement.
cr0x@server:~$ sudo sed -n '1,200p' /etc/fail2ban/jail.d/postfix-sasl.local
[postfix-sasl]
enabled = true
backend = systemd
filter = postfix[mode=auth]
maxretry = 6
findtime = 10m
bantime = 4h
bantime.increment = true
bantime.factor = 2
bantime.multipliers = 1 2 4 8 16 32
action = nftables-multiport[name=postfix-sasl, port="smtp,submission,submissions"]
journalmatch = _SYSTEMD_UNIT=postfix.service
Pourquoi ça marche : C’est lié aux échecs d’auth, pas aux bizarreries du protocole. Il utilise un bantime incrémental pour que les récidivistes subissent des bans plus longs sans punir définitivement quelqu’un qui a simplement tapé un mot de passe par erreur une fois.
Échecs d’auth Dovecot (brute force IMAP/POP)
Les logs de Dovecot sont généralement simples et incluent l’IP distante. Cela fait un bon jail — encore une fois, des événements à fort signal.
cr0x@server:~$ sudo sed -n '1,200p' /etc/fail2ban/jail.d/dovecot.local
[dovecot]
enabled = true
backend = systemd
filter = dovecot
maxretry = 5
findtime = 10m
bantime = 6h
bantime.increment = true
bantime.factor = 2
bantime.multipliers = 1 2 4 8 16
action = nftables-multiport[name=dovecot, port="imap,imaps,pop3,pop3s"]
journalmatch = _SYSTEMD_UNIT=dovecot.service
Opinion : Si vous exposez IMAP/POP sur Internet, vous voulez ce jail. «Nous avons seulement quelques utilisateurs» n’est pas une stratégie ; c’est une manière de programmer votre prochain incident.
Roundcube (brute force connexion webmail)
Les logs de Roundcube varient selon la configuration, et beaucoup oublient d’activer une journalisation utile. Fail2ban peut encore aider si vous avez des lignes d’échec de connexion cohérentes dans syslog ou dans les logs de Roundcube.
cr0x@server:~$ sudo sed -n '1,200p' /etc/fail2ban/jail.d/roundcube.local
[roundcube]
enabled = true
backend = auto
filter = roundcube-auth
logpath = /var/log/roundcube/errors.log
maxretry = 5
findtime = 15m
bantime = 12h
action = nftables-multiport[name=roundcube, port="http,https"]
Détail clé : Le brute force webmail provient souvent d’un petit ensemble d’IP, mais le credential stuffing peut ne pas l’être. Ce jail aide pour le premier cas.
Rspamd WebUI (brute force panneau admin)
Si vous exposez le WebUI de Rspamd sur Internet, vous choisissez la douleur. Si vous devez le faire, protégez‑le au minimum.
cr0x@server:~$ sudo sed -n '1,200p' /etc/fail2ban/jail.d/rspamd.local
[rspamd]
enabled = true
backend = systemd
filter = rspamd
maxretry = 4
findtime = 10m
bantime = 24h
action = nftables-multiport[name=rspamd, port="http,https"]
journalmatch = _SYSTEMD_UNIT=rspamd.service
Recidive : attraper les récidivistes à travers tous les jails
Recidive surveille le log de fail2ban lui‑même. Si une IP est bannie à plusieurs reprises dans le temps, elle mérite un ban plus long. C’est une des rares fonctionnalités «set and forget» qui rapporte réellement.
cr0x@server:~$ sudo sed -n '1,200p' /etc/fail2ban/jail.d/recidive.local
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
backend = auto
bantime = 7d
findtime = 1d
maxretry = 3
action = nftables-allports[name=recidive]
Quand ne pas bannir : le bruit des «rejected» SMTP
Vous serez tenté de bannir sur des lignes Postfix «NOQUEUE: reject». Ne commencez pas par là. Beaucoup de rejects proviennent de mauvaises configurations légitimes de la part d’émetteurs réels, et les bannir peut créer des problèmes de délivrabilité difficiles à expliquer.
Si vous implémentez un jail pour l’abus de protocole, gardez‑le conservateur et surveillez‑le comme un faucon. Traitez‑le comme une façon de «réduire le spam de logs», pas comme une mesure de «sécurité» principale.
Atelier regex : prouvez le match avant de bannir
Vos filtres ne sont aussi bons que vos regex. La méthode pratique est :
- Collecter des lignes de log représentatives (bonnes, mauvaises et étranges).
- Utiliser
fail2ban-regexcontre des logs réels. - Ajuster jusqu’à ce que les correspondances soient correctes et que les faux positifs soient ennuyeusement rares.
- Ce n’est qu’ensuite que vous activez le jail.
Une citation que les opérationnels réapprennent souvent à la dure :
«L’espoir n’est pas une stratégie.» — idée paraphrasée souvent citée dans les cercles d’exploitation
Blague #2 : La regex, c’est comme une tronçonneuse : puissante, bruyante, et vous finirez par vous blesser si vous la maniez sans surveillance.
Tâches pratiques : commandes, sorties, décisions (12+)
Tâche 1 : Confirmer que fail2ban tourne et ne redémarre pas en boucle
cr0x@server:~$ systemctl status fail2ban --no-pager
● fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
Active: active (running) since Mon 2026-01-04 08:11:22 UTC; 2h 14min ago
Docs: man:fail2ban(1)
Main PID: 1047 (fail2ban-server)
Tasks: 5 (limit: 18963)
Memory: 64.3M
CPU: 2min 18.541s
Ce que ça signifie : «active (running)» avec une uptime stable suggère qu’il ne plante pas ou ne redémarre pas constamment.
Décision : S’il redémarre ou est inactif, corrigez cela en priorité. Aucun réglage de regex n’aide si le démon est mort.
Tâche 2 : Lister les jails activés (vérification de réalité)
cr0x@server:~$ sudo fail2ban-client status
Status
|- Number of jail: 4
`- Jail list: dovecot, postfix-sasl, recidive, rspamd
Ce que ça signifie : Ce sont les seuls jails qui font quelque chose.
Décision : Si le jail prévu n’est pas listé, il n’est pas activé ou il a échoué au chargement. Allez lire journalctl -u fail2ban.
Tâche 3 : Vérifier les compteurs d’un jail
cr0x@server:~$ sudo fail2ban-client status postfix-sasl
Status for the jail: postfix-sasl
|- Filter
| |- Currently failed: 12
| |- Total failed: 981
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 7
|- Total banned: 103
`- Banned IP list: 198.51.100.23 203.0.113.14 203.0.113.77
Ce que ça signifie : «Currently failed» est le nombre d’échecs dans la fenêtre ; «Currently banned» sont les bans actifs.
Décision : Si «Total failed» augmente mais que les bans sont zéro, votre maxretry peut être trop élevé, le findtime trop court, ou le filtre matche mais l’action ne fonctionne pas.
Tâche 4 : Vérifier l’intégration pare‑feu (exemple nftables)
cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif "lo" accept
tcp dport { 22, 25, 465, 587, 993 } accept
}
}
table inet f2b-table {
set f2b-postfix-sasl {
type ipv4_addr
flags timeout
}
chain f2b-postfix-sasl {
ip saddr @f2b-postfix-sasl drop
}
}
Ce que ça signifie : Il y a une table/ensemble fail2ban pour le jail. S’il manque, l’action n’a pas appliqué de règles.
Décision : Si fail2ban dit avoir banni des IPs mais qu’il n’y a pas d’ensembles/chaînes nftables, vous utilisez la mauvaise action ou il manque des permissions/capacités.
Tâche 5 : Confirmer que Postfix journalise les échecs SASL là où fail2ban peut les voir
cr0x@server:~$ sudo journalctl -u postfix.service -S "30 min ago" | grep -E "SASL|authentication failed" | tail -n 5
Jan 04 10:12:43 mail postfix/smtpd[22901]: warning: unknown[203.0.113.77]: SASL LOGIN authentication failed: authentication failure
Jan 04 10:12:45 mail postfix/smtpd[22901]: warning: unknown[203.0.113.77]: SASL LOGIN authentication failed: authentication failure
Ce que ça signifie : Vous avez les lignes attendues, avec les IP visibles.
Décision : Si vous ne voyez pas cela, votre auth SASL peut être dans une autre unité/facilité de log, ou les échecs d’auth sont supprimés. Corrigez la journalisation avant les filtres.
Tâche 6 : Confirmer le format des échecs d’auth Dovecot
cr0x@server:~$ sudo journalctl -u dovecot.service -S "30 min ago" | grep -i "auth failed" | tail -n 3
Jan 04 10:06:12 mail dovecot: auth: passwd-file(jdoe,203.0.113.14): Password mismatch
Jan 04 10:06:15 mail dovecot: imap-login: Aborted login (auth failed, 1 attempts): user=<jdoe>, method=PLAIN, rip=203.0.113.14, lip=192.0.2.10, TLS
Ce que ça signifie : Il inclut rip= (IP distante), ce sur quoi beaucoup de filtres par défaut se basent.
Décision : Si vos lignes n’incluent pas l’IP, vous aurez besoin d’un filtre différent ou de paramètres de journalisation Dovecot différents.
Tâche 7 : Tester un filtre contre des logs réels avant de l’activer
cr0x@server:~$ sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/postfix.conf --print-all-matched
Running tests
=============
Use failregex file : /etc/fail2ban/filter.d/postfix.conf
Use log file : /var/log/auth.log
Results
=======
Failregex: 18 total
|- #) [# of hits] regular expression
| 1) [18] warning: .*?\[<HOST>\]: SASL .* authentication failed
`-
Lines: 12458 lines, 0 ignored, 18 matched, 12440 missed
Ce que ça signifie : La regex touche exactement les lignes attendues. «Missed» est normal ; c’est tout le reste.
Décision : Si les correspondances sont nulles, corrigez la regex ou le logpath. Si les correspondances sont énormes, vous matchez peut‑être des lignes bénignes et devez resserrer.
Tâche 8 : Simuler vos paramètres de ban avec fail2ban-client get
cr0x@server:~$ sudo fail2ban-client get postfix-sasl maxretry
6
cr0x@server:~$ sudo fail2ban-client get postfix-sasl findtime
600
cr0x@server:~$ sudo fail2ban-client get postfix-sasl bantime
14400
Ce que ça signifie : Les valeurs sont en secondes pour certaines requêtes. 600 secondes = 10 minutes ; 14400 = 4 heures.
Décision : Si votre environnement a des clients mobiles instables ou des bureaux derrière NAT, envisagez un maxretry légèrement plus élevé ou un bantime plus court au début, puis augmentez une fois les faux positifs sous contrôle.
Tâche 9 : Inspecter les logs de fail2ban pour erreurs d’action (le tueur silencieux)
cr0x@server:~$ sudo tail -n 50 /var/log/fail2ban.log
2026-01-04 10:12:49,381 fail2ban.actions [1047]: NOTICE [postfix-sasl] Ban 203.0.113.77
2026-01-04 10:12:49,512 fail2ban.actions [1047]: ERROR Failed to execute ban jail 'postfix-sasl' action 'nftables-multiport': returned 127
2026-01-04 10:12:49,513 fail2ban.actions [1047]: ERROR Invariant check failed. Trying again...
Ce que ça signifie : Fail2ban croit avoir «banni», mais l’action a échoué à s’exécuter (exit 127 signifie souvent binaire manquant ou commande incorrecte).
Décision : Corrigez l’outil d’action (chemin de la commande nft, permissions, définition d’action) avant de faire confiance aux compteurs de ban.
Tâche 10 : Vérifier si vous bannissez un NAT (bureau) et nuisez à de nombreux utilisateurs
cr0x@server:~$ sudo fail2ban-client status dovecot
Status for the jail: dovecot
|- Filter
| |- Currently failed: 2
| |- Total failed: 204
| `- File list: /var/log/mail.log
`- Actions
|- Currently banned: 1
|- Total banned: 9
`- Banned IP list: 198.51.100.10
Ce que ça signifie : Une IP est actuellement bannie. Si cette IP est un NAT d’entreprise, vous venez de bloquer tout le monde derrière.
Décision : Si cela arrive, ajoutez une liste d’ignore ciblée pour les IP d’egress connues du bureau, mais uniquement après vérification que vous ne mettez pas sur liste blanche un attaquant se cachant derrière un «VPN de bureau».
Tâche 11 : Ajouter une IP à ignorer en toute sécurité (et garder la traçabilité)
cr0x@server:~$ sudo sed -n '1,120p' /etc/fail2ban/jail.local
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 192.0.2.0/24 198.51.100.10
Ce que ça signifie : Ces sources ne seront jamais bannies par aucun jail.
Décision : Gardez les listes d’ignore petites. Préférez mettre sur liste blanche uniquement des IP d’egress fixes que vous contrôlez et surveillez. Ne pas mettre des plages d’ISP entières ici parce qu’un VIP s’est plaint.
Tâche 12 : Débannir une IP (puis comprendre pourquoi elle a été bannie)
cr0x@server:~$ sudo fail2ban-client set dovecot unbanip 198.51.100.10
1
Ce que ça signifie : «1» indique un succès (un ban supprimé).
Décision : Débannissez, puis enquêtez immédiatement : était‑ce une erreur utilisateur, du credential stuffing ou un client mal comporté ? Si vous n’y répondez pas, vous reviendrez ici demain.
Tâche 13 : Confirmer que votre jail regarde la bonne source (backend systemd)
cr0x@server:~$ sudo fail2ban-client get postfix-sasl backend
systemd
cr0x@server:~$ sudo fail2ban-client get postfix-sasl journalmatch
_SYSTEMD_UNIT=postfix.service
Ce que ça signifie : Le jail lit les logs depuis journald filtrés sur l’unité Postfix.
Décision : Si journalmatch est vide et que votre système est bruyant, vous pouvez parser des lignes non reliées et générer des bans absurdes. Ajoutez le match.
Tâche 14 : Mesurer le taux d’attaque pour ajuster les seuils
cr0x@server:~$ sudo journalctl -u postfix.service -S "1 hour ago" | grep -c "SASL LOGIN authentication failed"
482
Ce que ça signifie : 482 échecs par heure n’est pas de la «radiation de fond». C’est un abus actif ou un client en panne.
Décision : Si le taux est élevé, gardez findtime raisonnablement court (5–15 minutes) pour déclencher rapidement les bans. Si le taux est faible et que vous craignez les faux positifs, allongez findtime et augmentez maxretry.
Playbook de diagnostic rapide
Quand «le mail est lent» ou «les gens ne peuvent pas se connecter» et que vous soupçonnez fail2ban, vous voulez la vitesse. Pas la perfection. Voici le chemin le plus court vers la vérité.
Première étape : est‑ce que fail2ban bloque réellement le trafic ?
- Vérifiez les bans actifs dans le jail concerné (
fail2ban-client status <jail>). - Vérifiez que les règles/ensembles du pare‑feu existent et contiennent l’IP bannie (sortie nftables/iptables).
- Si vous utilisez un reverse proxy ou un load balancer, confirmez que l’IP source dans les logs est le vrai client, et non le proxy.
Deuxième étape : le jail matche‑t‑il les bonnes lignes de log ?
- Récupérez une ligne d’échec récente depuis journald/syslog.
- Exécutez
fail2ban-regexcontre elle (ou un petit extrait de log) en utilisant le filtre exact du jail. - Validez que l’hôte extrait est correct (surtout avec IPv6, adresses entre crochets, ou wrappers «unknown»).
Troisième étape : est‑ce un problème client qui se fait passer pour une attaque ?
- Cherchez un seul utilisateur générant des échecs répétés depuis une IP NAT unique.
- Vérifiez si un mot de passe a changé récemment (tickets helpdesk, synchronisation d’annuaire, révocation de tokens OAuth).
- Si c’est du mail mobile, supposez des identifiants obsolètes et une logique de retry agressive jusqu’à preuve du contraire.
Quatrième étape : l’«attaque» est‑elle distribuée ?
- Comptez les IP uniques provoquant des échecs d’auth dans la dernière heure.
- Si le nombre est énorme et que chaque IP a peu de volume, fail2ban ne fera que grignoter les bords.
- Orientez vos efforts vers les limites de débit, le filtrage en amont, une authentification plus forte, ou la désactivation temporaire des points d’auth exposés dont vous n’avez pas besoin.
Erreurs courantes : symptôme → cause racine → correctif
1) «fail2ban dit bannir, mais l’attaquant continue»
Symptôme : Le jail affiche des bans ; les logs montrent des échecs d’auth provenant de la même IP.
Cause racine : Action mal configurée (mauvaise action backend, nft/iptables manquant, firewalld inactif), ou les bans s’appliquent à IPv4 alors que le trafic est IPv6.
Correctif : Vérifiez la présence des règles de pare‑feu et que la chaîne est branchée dans INPUT. Assurez‑vous que votre action supporte inet/IPv6 si nécessaire ; utilisez la table inet de nftables ou des actions dual‑stack.
2) «Des utilisateurs derrière un NAT de bureau ne peuvent pas consulter le mail»
Symptôme : Plusieurs utilisateurs signalent des timeouts IMAP/SMTP ; une IP est bannie.
Cause racine : Un client mal configuré derrière un NAT déclenche des bans pour tout le monde.
Correctif : Augmentez légèrement maxretry pour Dovecot/Postfix, activez les bans incrémentaux, et ajoutez un ignoreip strictement limité seulement si vous pouvez surveiller et faire confiance à cet egress.
3) «Aucun ban ne se produit, mais les logs montrent des échecs»
Symptôme : Total failed reste à zéro ; les logs de fail2ban sont calmes.
Cause racine : Mauvais backend/logpath. Exemple : le jail surveille /var/log/auth.log, mais votre système journalise uniquement dans journald.
Correctif : Passez à backend = systemd avec journalmatch, ou assurez‑vous qu’rsyslog écrit le fichier attendu.
4) «Les bans explosent après une mise à jour»
Symptôme : Des milliers de bans, y compris des clients légitimes.
Cause racine : Le format de log a changé (mise à jour de paquet, nouvelle verbosité), et la regex matche maintenant plus que prévu.
Correctif : Lancez fail2ban-regex sur un échantillon des nouveaux logs ; resserrez les expressions ; ajoutez des ignoreregex pour les lignes bénignes connues.
5) «Nous avons banni le load balancer»
Symptôme : Tout casse en une fois ; les logs montrent la même IP interne en échec en boucle.
Cause racine : X-Forwarded-For non transmis, ou le proxy mail masque l’IP client, si bien que tous les échecs semblent venir du proxy.
Correctif : Corrigez la journalisation pour inclure l’IP réelle du client, ou exécutez fail2ban à la frontière où vous voyez les clients. Ne devinez pas.
6) «recidive bannit des réseaux bons pour une semaine»
Symptôme : Bans longs déclenchés après de courtes rafales d’échecs.
Cause racine : Vous avez trop agressivement réglé les jails primaires, causant des faux positifs ; recidive les a amplifiés.
Correctif : Adoucir les jails primaires (augmenter maxretry, raccourcir bantime), puis réactiver recidive une fois que les faux positifs sont rares.
7) «La soumission mail depuis les réseaux mobiles est instable»
Symptôme : Incapacité aléatoire à se connecter depuis LTE, mais le Wi‑Fi fonctionne.
Cause racine : Bans trop larges sur des rejects SMTP génériques ou anomalies de protocole ; les opérateurs mobiles partagent l’espace IP et font beaucoup de NAT.
Correctif : Évitez de bannir sur des rejects SMTP génériques. Bannis sur les échecs d’auth et les abus explicites, pas sur «client a envoyé un HELO étrange».
Trois mini-histoires d’entreprise (comment ça foire en réel)
Mini‑histoire 1 : L’incident causé par une mauvaise hypothèse
Une société de taille moyenne a migré la messagerie d’une VM legacy vers une nouvelle release de distribution. Ils ont copié la config fail2ban ancienne à l’identique : mêmes jails, mêmes chemins de logs, mêmes filtres. Ils ont même célébré : «C’est identique, donc c’est sûr.»
Ce qui a changé est ennuyeux : la journalisation est passée à journald, et rsyslog n’écrivait plus /var/log/auth.log par défaut. Fail2ban tailait un fichier qui existait, mais qui était essentiellement vide. Pendant ce temps, les échecs SASL de Postfix s’accumulaient dans journald, invisibles.
Le premier signal n’a pas été «notre mail est attaqué». Le premier signal a été le CPU : les workers d’auth Dovecot étaient occupés à rejeter des connexions toute la journée. Le second signal fut une compromission de compte : un mot de passe réutilisé, une boîte compromise, puis une rafale de spam sortant qui a ruiné leur réputation IP.
La correction n’a pas été héroïque. Ils sont passés à backend = systemd, ont ajouté des journalmatch par service, ont testé avec fail2ban-regex, et soudain les bans sont apparus pour les bonnes raisons. La leçon n’était pas «utilisez journald». C’était «ne supposez jamais que vos logs sont où ils étaient avant».
Mini‑histoire 2 : L’optimisation qui a mal tourné
Un autre org a eu une idée brillante : réduire le volume de logs. Leurs logs mail étaient énormes, le stockage «trop cher», et quelqu’un a décidé d’abaisser la verbosité sur les échecs d’auth. Moins de disque, moins d’alertes, tout le monde content.
Deux semaines plus tard, ils ont remarqué un nouveau pattern : des utilisateurs étaient intermittents verrouillés. Leur annuaire montrait des tentatives de connexion étranges, mais les hosts mail n’avaient pas assez de détails pour attribuer de façon fiable les sources. Les bans fail2ban devenaient chaotiques parce que les logs restants n’incluaient pas systématiquement l’IP distante sur les lignes d’échec.
Ils ont «optimisé» encore en baissant maxretry et en augmentant bantime pour compenser. C’est comme ça qu’ils se sont retrouvés à bannir des NATs d’hôtels et des réseaux de conférence pendant une journée entière. Les tickets support ont explosé. Les cadres sont intervenus. Vous connaissez la suite.
Ils ont rétabli la journalisation pour inclure le contexte d’auth, ont gardé logrotate raisonnable, et ont déplacé la discussion sur les coûts là où elle devait être : le stockage coûte moins cher que les incidents. Ils ont ensuite ajusté fail2ban en se basant sur des taux d’échecs mesurés, pas des impressions.
Mini‑histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une entreprise réglementée faisait tourner la messagerie dans un environnement segmenté : front‑end SMTP séparé, IMAP séparé, et un réseau de gestion. Leur config fail2ban était peu glamour. Chaque jail était testé avec fail2ban-regex lors des revues de changement. Chaque entrée de liste blanche avait une référence de ticket. Chaque action utilisait un seul backend de pare‑feu (nftables) sur tous les hôtes.
Un vendredi soir, une campagne de credential stuffing a frappé leur endpoint IMAP. Elle était distribuée et lente par IP. Fail2ban n’a pas bloqué toutes les tentatives, car il ne peut pas magiquement bannir ce qui ne franchit jamais les seuils. Mais il a arrêté rapidement la sous‑partie bruyante, ce qui a gardé le service réactif et les logs lisibles.
La vraie victoire est venue de leurs tableaux de bord «ennuyeux» : ils suivaient les taux d’échecs d’auth et le nombre d’IP sources uniques. En une heure ils ont reconnu la signature du stuffing. Ils ont resserré temporairement les limites de débit en périphérie, forcé la réinitialisation des mots de passe pour un petit ensemble de comptes ciblés, et activé une application MFA renforcée pour le webmail.
Le lundi matin était calme. Pas de nuit blanche héroïque. Le rapport d’incident était presque agaçant de simplicité : règles testées, journalisation cohérente et métriques. Le succès opérationnel ressemble souvent à ce que personne ne remarque que vous avez fait quelque chose.
Listes de contrôle / plan pas à pas
Étape 1 : Établir la visibilité (avant de bannir)
- Choisissez votre source de logs : journald ou fichiers. Ne mélangez pas à la légère.
- Confirmez que vous voyez les lignes d’échec Postfix et Dovecot avec les IP.
- Activez la journalisation de fail2ban vers un fichier connu (
/var/log/fail2ban.logest typique).
Étape 2 : Commencez par des jails à fort signal
- Activez le jail Postfix SASL auth.
- Activez le jail Dovecot auth.
- Eventuellement activez les jails web UI (Roundcube, Rspamd) uniquement s’ils sont exposés.
Étape 3 : Ajustez les seuils avec des données mesurées
- Mesurez les échecs d’auth par heure et le nombre d’IP uniques.
- Définissez
maxretrypour attraper les bots, pas les fautes de frappe (commencez à 5–6). - Utilisez
findtimede 10–15 minutes pour capturer les rafales. - Utilisez un bantime incrémental pour punir la récidive sans créer des pièges permanents.
Étape 4 : Déploiement sûr
- Activez un jail à la fois.
- Surveillez les bans pendant 24 heures.
- Auditez les douze premiers IP bannies : confirmez qu’il s’agit d’abus réels.
- Ce n’est qu’ensuite que vous activez recidive.
Étape 5 : Rendre cela supportable pour l’astreinte
- Documentez comment débannir et où vérifier les logs.
- Gardez les listes d’ignore minimales et révisées.
- Assurez‑vous que le backend pare‑feu est cohérent sur tous les hôtes (nftables ou firewalld ; choisissez‑en un).
FAQ
1) Dois‑je exécuter fail2ban sur le serveur mail ou sur le pare‑feu ?
Exécutez‑le là où vous pouvez voir de manière fiable la vraie IP client et où un ban bloque effectivement le trafic. Si les logs montrent une IP de proxy, exécutez fail2ban au proxy/edge ou corrigez la journalisation.
2) Quel point de départ raisonnable pour maxretry/findtime/bantime ?
Pour les échecs d’auth : maxretry=5–6, findtime=10m, bantime=4–12h, plus des bans incrémentaux. Ajustez ensuite selon les faux positifs et le taux d’attaque observés.
3) Pourquoi je vois beaucoup de «failed» mais peu de bans ?
Soit les échecs sont répartis sur de nombreuses IP (attaque distribuée), soit vos seuils sont trop permissifs. Mesurez les IP uniques par heure ; si c’est élevé, fail2ban ne sera pas une solution miracle.
4) Est‑ce que fail2ban arrêtera le credential stuffing ?
Partiellement. Il arrête la sous‑partie bruyante. Pour un vrai stuffing (beaucoup d’IP, peu de tentatives chacune), vous avez besoin de contrôles supplémentaires : limites de débit, MFA, mots de passe meilleurs, et parfois filtrage de réputation en amont.
5) Dois‑je bannir sur des lignes Postfix «NOQUEUE: reject» ?
Pas en premier lieu. Ces lignes contiennent beaucoup d’échecs bénins. Commencez par les échecs d’auth. Si vous ajoutez plus tard des bans pour abuser du protocole, gardez‑les conservateurs et surveillés.
6) Comment éviter de bannir des bureaux entiers derrière un NAT ?
Utilisez un bantime incrémental, maintenez maxretry légèrement plus élevé pour IMAP si vos utilisateurs sont mobiles, et envisagez de mettre sur liste blanche uniquement des IP d’egress stables et possédées. Mieux : éduquez les utilisateurs et imposez le MFA quand c’est possible.
7) Est‑ce que l’IPv6 change quelque chose ?
Oui. Assurez‑vous que vos actions supportent IPv6 et que vos filtres extraient correctement les adresses IPv6. Evitez aussi l’instinct de «bannir toute une plage» ; l’adressage IPv6 rend cela rapidement risqué.
8) Dois‑je activer recidive ?
Oui, mais pas le premier jour. Prouvez d’abord que vos jails de base ont peu de faux positifs. Recidive amplifie vos choix — bons ou mauvais.
9) Quelle est la façon la plus sûre de tester de nouveaux filtres ?
Utilisez fail2ban-regex contre des logs réels et examinez les lignes correspondantes. Ne déployez pas un filtre que vous n’avez pas prouvé sur votre propre format de logs.
10) Comment savoir si fail2ban est le goulot d’étranglement ?
Généralement, ce n’est pas lui. Le goulot est souvent les backends d’auth (LDAP/SQL), l’I/O disque due à une journalisation excessive, ou le CPU des workers TLS/auth. Fail2ban est souvent le messager — et parfois le bouc émissaire.
Conclusion : prochaines étapes sans risquer de tout casser
Si vous voulez que fail2ban pour le mail aide réellement, traitez‑le comme du code de production : observable, testé et déployé par étapes.
- Vérifiez d’abord la journalisation (unité de service, source de logs, IP présente sur les lignes d’échec).
- Activez seulement les jails à fort signal (Postfix SASL, Dovecot auth) et prouvez les correspondances avec
fail2ban-regex. - Utilisez un bantime incrémental pour punir la récidive tout en réduisant les dommages collatéraux.
- Validez l’action pare‑feu (les règles nftables/iptables existent et sont réellement branchées sur le trafic).
- Ajoutez recidive en dernier, une fois que vous maîtrisez votre taux de faux positifs.
- Documentez la procédure de débannissement et gardez les listes blanches petites et traçables.
Faites cela, et fail2ban deviendra ce qu’il devrait être : pas du «security theater», mais un videur utile et peu gourmand en maintenance pour les fauteurs de troubles les plus évidents.