Sécurité

Fail2ban en production : au-delà du tutoriel SSH

Installer fail2ban prend cinq minutes ; le faire fonctionner correctement en production est une autre histoire. Backend journald, bannissement progressif, jails HTTP derrière un reverse proxy, et les pièges vécus : la vraie IP client, le proxy d'entreprise qu'il ne faut jamais bannir, le restart nftables qui purge tout.

Bouclier devant une baie de serveurs, les tentatives de connexion répétées se brisent dessus
Sommaire (6 sections)
  1. Remettre fail2ban à sa place
  2. La base, version 2026 : journald, pas auth.log
  3. L'étage au-dessus : les jails HTTP derrière un reverse proxy
  4. Les deux pièges qui coûtent cher
  5. Le proxy d'entreprise : une IP = des dizaines d'humains
  6. nftables : le restart qui purge tout

Exposez un port SSH sur Internet et regardez les journaux : les tentatives arrivent en continu, par milliers, depuis des botnets qui essaient des couples utilisateur/mot de passe en boucle. Fail2ban est la réponse classique : lire les journaux, repérer les échecs répétés, bannir l'adresse source. Cinq minutes à installer, et c'est bien le problème : la plupart des installations en restent au tutoriel, avec une jail SSH par défaut qui rassure plus qu'elle ne protège. Voici ce que change une configuration de production, pièges vécus compris.

Remettre fail2ban à sa place #

Disons-le d'abord clairement : fail2ban est un réducteur de bruit, pas une défense principale. Si votre SSH accepte les mots de passe, fail2ban ralentit les attaquants ; si votre SSH n'accepte que les clés (PasswordAuthentication no), le brute force est déjà mort : fail2ban ne fait plus qu'assainir les journaux et économiser des ressources. L'ordre des priorités est donc : authentification par clé uniquement, exposition minimale (un pare-feu qui n'ouvre que le nécessaire, des allowlists d'IP pour l'administration), et ensuite fail2ban pour le bruit résiduel. C'est l'architecture de nos serveurs frontaux : le pare-feu de l'hyperviseur ne laisse passer que HTTP/HTTPS du public, SSH est sur clé, et fail2ban nettoie ce qui reste.

La base, version 2026 : journald, pas auth.log #

Premier piège des tutoriels anciens : ils pointent fail2ban vers /var/log/auth.log… qui n'existe plus sur les systèmes modernes sans rsyslog, où tout vit dans le journal systemd. Une jail qui lit un fichier absent ou gelé ne banni personne, en silence. La parade : backend = systemd. Voici notre socle jail.local, avec le second réglage qui change tout, le bannissement progressif :

INI
# /etc/fail2ban/jail.local
[DEFAULT]
backend = systemd
banaction = nftables-multiport

# Bannissement progressif : chaque récidive multiplie la peine.
bantime = 1h
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 1w

findtime = 10m
maxretry = 5

# IP à ne JAMAIS bannir : supervision, admin. Liste courte et justifiée.
ignoreip = 127.0.0.1/8 ::1 <ip-supervision>

[sshd]
enabled = true
mode = aggressive

Le progressif est ce qui fait la différence sur la durée : un scanner occasionnel prend une heure, un récidiviste finit banni une semaine. Et vérifiez toujours qu'une jail travaille réellement : fail2ban-client status sshd doit montrer des correspondances qui augmentent : une jail à zéro depuis des semaines sur un serveur exposé est une jail cassée, pas un serveur épargné.

L'étage au-dessus : les jails HTTP derrière un reverse proxy #

Le brute force ne vise pas que SSH : les pages de connexion des applications web, les endpoints d'API et les chemins d'administration prennent le même trafic. Fail2ban sait les protéger, à condition de lire les journaux du reverse proxy (Traefik, nginx…) et d'y matcher les rafales de 401/403. Deux conditions non négociables, toutes deux apprises à nos dépens :

  • Bannir la vraie IP client, jamais celle du proxy. Si votre application est derrière un reverse proxy (ou pire, si Docker fait du NAT devant), les journaux peuvent n'afficher que l'IP interne du proxy. Bannissez-la et vous coupez tout le trafic. Il faut que la chaîne préserve l'adresse source de bout en bout ; sur l'un de nos serveurs, cela a imposé de passer le proxy en réseau hôte, faute de quoi les visiteurs IPv6 apparaissaient tous avec la même IP interne de passerelle Docker.
  • Journaux structurés. Un access log JSON se parse sans regex fragile : le filtre fail2ban devient une ligne fiable au lieu d'une expression qui casse à la première mise à jour du format.

Les deux pièges qui coûtent cher #

Le proxy d'entreprise : une IP = des dizaines d'humains #

Vécu en production : des rafales de requêtes suspectes depuis une IP unique, le réflexe de bannir… et c'était un proxy d'entreprise (type Zscaler) : derrière cette adresse, des dizaines de salariés légitimes, dont peut-être votre client. Même chose pour les sondes de supervision externes, dont le comportement (requêtes régulières, ports variés) ressemble à s'y méprendre à un scan. Avant de bannir une IP « bizarre », un whois prend dix secondes ; les proxys d'entreprise et vos sondes vont dans ignoreip, documentés, avec la raison en commentaire.

nftables : le restart qui purge tout #

Fail2ban écrit ses bannissements dans le pare-feu (nftables aujourd'hui). Or systemctl restart nftables purge l'intégralité du ruleset avant de recharger le fichier, emportant les tables dynamiques de fail2ban et, si Docker tourne, ses règles NAT : nous avons vu un restart anodin couper le DNS d'un conteneur en production. Pour recharger une configuration nftables, utilisez nft -f (atomique, additif), jamais un restart du service sur une machine qui porte fail2ban ou Docker.

Fail2ban illustre bien notre conviction : la sécurité n'est pas un produit qu'on installe, c'est une série de détails qu'on vérifie. C'est ce que couvre notre infogérance : durcissement, supervision des jails, et sauvegardes immuables pour le jour où tout le reste a échoué. Un doute sur l'exposition réelle de vos serveurs ? Parlons-en.

À propos
À lire ensuite

Articles liés

Sécurité

Pare-feu Proxmox : le piège du firewall=1 qui ne filtre rien

Un audit de notre propre parc l'a montré : des machines avec le pare-feu « activé » sur leur interface étaient en réalité ouvertes au monde. Le pare-feu Proxmox exige deux conditions, pas une, et les règles du datacenter ne protègent jamais les invités. Anatomie du piège, vérification en une commande, et la recette complète.

proxmoxfirewall
Sécurité

Subscription bombing : autopsie d'un formulaire newsletter détourné en relais de spam

Une nuit, quatorze mails de confirmation sont partis d'un site que nous hébergeons vers des adresses qui n'avaient rien demandé. Le captcha était résolu, le plafond par destinataire contourné, le rate-limit inutile, CrowdSec aveugle. Reconstitution complète depuis les logs : ce que le robot faisait, comment on l'a reconnu, et pourquoi la seule vraie parade a été de lui retirer son arme.

sécuritébots
Infrastructure

Autopsie d'une panne NVMe : les condensateurs morts qui ralentissaient tout

Pendant deux mois et demi, un hyperviseur a accumulé des timeouts de réplication sans qu'aucun disque ne soit « mort ». Le coupable : les condensateurs de Power Loss Protection d'un NVMe, tombés en panne en silence. Autopsie complète : du symptôme au smartctl, du remplacement OVH au resilver qui a révélé 20 000 erreurs latentes.

nvmeplp

Une infrastructure infogérée et supervisée 24/7 ?

Bastion, SIEM, correctifs décidés, sauvegardes testées : ce que nous appliquons à nos clients. Premier échange gratuit.

Premier échange gratuit · réponse sous 24 h ouvrées