
Fail2ban avance : bannissement incremental, filtres custom et ...
Configuration avancee de Fail2ban pour SSH : ban incremental, recidive, filtres regex personnalises, integration Telegram, hardening complet.
Fail2ban avance : bannissement incremental, filtres custom et alertes
Ce guide suppose que vous avez deja un Fail2ban fonctionnel avec la jail sshd activee. On va aller plus loin : bannissement progressif, detection d'attaques distribuees, filtres regex sur mesure et alertes en temps reel via Telegram.
Version cible : Fail2ban 1.1.0 (derniere stable, avril 2024). Les configurations fonctionnent egalement sur la version 1.0.2 presente dans les depots Ubuntu 24.04 / Debian 12.
Pre-requis
- Serveur Ubuntu 22.04+ ou Debian 11+ avec Fail2ban installe
- Acces root ou sudo
- Jail
sshddeja fonctionnelle - (Optionnel) Un bot Telegram pour les alertes
1. Bannissement incremental
Le ban fixe a un probleme : un attaquant banni 1 heure revient systematiquement apres. Le ban incremental augmente la duree a chaque recidive.
Editez /etc/fail2ban/jail.local :
sudo nano /etc/fail2ban/jail.localConfiguration complete avec bannissement incremental :
## /etc/fail2ban/jail.local
## Configuration avancee avec bannissement incremental
[DEFAULT]
## Adresses IP whitelist (adaptez a votre reseau)
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8 192.168.0.0/16
## Backend systemd pour les distributions recentes
backend = systemd
## Ban incremental : la duree double a chaque recidive
bantime.increment = true
## Premier ban : 10 minutes. Puis 20, 40, 80... jusqu'au max
bantime = 600
## Multiplicateur entre chaque ban (defaut : facteur x2)
bantime.factor = 2
## Duree max de bannissement : 4 semaines
bantime.maxtime = 4w
## Fenetre de detection
findtime = 600
## Echecs avant ban
maxretry = 5
## Utiliser la base de donnees pour persister les bans entre redemarrages
bantime.overalljails = true
## Base de donnees SQLite (chemin par defaut)
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 30d
[sshd]
enabled = true
port = ssh
filter = sshd
maxretry = 3
findtime = 300
bantime = 3600
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 4w
## Mode de detection agressif : attrape plus de patterns
mode = aggressive
[sshd-ddos]
## Protection contre les attaques DDoS sur SSH
enabled = true
port = ssh
filter = sshd-ddos
maxretry = 6
findtime = 60
bantime = 172800
bantime.increment = true
[recidive]
## Ban les recidivistes : IP bannie 3 fois = ban longue duree
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
maxretry = 3
findtime = 86400
bantime = 604800
banaction = iptables-allportsLe filtre sshd-ddos n'existe pas par defaut. On le cree :
sudo nano /etc/fail2ban/filter.d/sshd-ddos.conf## /etc/fail2ban/filter.d/sshd-ddos.conf
## Detecte les connexions SSH excessives (flood)
[Definition]
failregex = ^sshd\[\d+\]: Connection from <HOST> port \d+ on .* rdomain .*$
^sshd\[\d+\]: Received disconnect from <HOST> port \d+:.*\[preauth\]$
^sshd\[\d+\]: Disconnected from authenticating user .* <HOST> port \d+ \[preauth\]$
ignoreregex =Rechargez Fail2ban :
sudo fail2ban-client reloadVerifiez que les trois jails sont actives :
sudo fail2ban-client statusResultat attendu :
Status
|- Number of jail: 3
`- Jail list: recidive, sshd, sshd-ddos2. Filtre regex personnalise
Les filtres par defaut couvrent les cas classiques. Mais si votre serveur subit des attaques specifiques, vous pouvez ecrire vos propres regles.
Exemple : detecter les tentatives avec des noms d'utilisateur inexistants.
sudo nano /etc/fail2ban/filter.d/sshd-invalid-user.conf## /etc/fail2ban/filter.d/sshd-invalid-user.conf
## Ban les tentatives avec des utilisateurs qui n'existent pas
[Definition]
failregex = ^sshd\[\d+\]: Invalid user .* from <HOST>$
^sshd\[\d+\]: Connection closed by invalid user .* <HOST> port \d+ \[preauth\]$
^sshd\[\d+\]: Failed password for invalid user .* from <HOST> port \d+ ssh2$
ignoreregex =
[Init]
journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshdAjoutez la jail correspondante dans jail.local :
[sshd-invalid-user]
enabled = true
port = ssh
filter = sshd-invalid-user
maxretry = 2
findtime = 300
bantime = 86400
bantime.increment = truePour tester un filtre avant de l'activer :
## Tester le filtre contre les logs existants
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd-invalid-user.conf
## Sur systemd (pas de fichier log) :
sudo fail2ban-regex systemd-journal /etc/fail2ban/filter.d/sshd-invalid-user.confLa commande fail2ban-regex affiche le nombre de correspondances trouvees. Si c'est 0 alors que vous savez qu'il y a des tentatives, votre regex a un probleme.
3. Alertes Telegram en temps reel
Recevoir un email pour chaque ban, c'est vite penible. Telegram est plus pratique pour du monitoring en temps reel.
Creer le bot Telegram
- Ouvrez Telegram, cherchez
@BotFather - Envoyez
/newbot, suivez les instructions - Notez le token du bot (format :
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11) - Demarrez une conversation avec votre bot, envoyez
/start - Recuperez votre chat ID :
curl -s https://api.telegram.org/bot<VOTRE_TOKEN>/getUpdates | jq '.result[0].message.chat.id'
Creer l'action Fail2ban
sudo nano /etc/fail2ban/action.d/telegram.conf## /etc/fail2ban/action.d/telegram.conf
## Envoie une notification Telegram a chaque ban/unban
[Definition]
actionstart = /usr/bin/curl -s -X POST \
"https://api.telegram.org/bot%(token)s/sendMessage" \
-d chat_id="%(chatid)s" \
-d parse_mode="HTML" \
-d text="🟢 <b>Fail2ban</b> demarre sur <code>%(hostname)s</code>%0AJail : <code><name></code>"
actionstop = /usr/bin/curl -s -X POST \
"https://api.telegram.org/bot%(token)s/sendMessage" \
-d chat_id="%(chatid)s" \
-d parse_mode="HTML" \
-d text="🔴 <b>Fail2ban</b> arrete sur <code>%(hostname)s</code>%0AJail : <code><name></code>"
actionban = /usr/bin/curl -s -X POST \
"https://api.telegram.org/bot%(token)s/sendMessage" \
-d chat_id="%(chatid)s" \
-d parse_mode="HTML" \
-d text="🚫 <b>BAN</b> sur <code>%(hostname)s</code>%0AJail : <code><name></code>%0AIP : <code><ip></code>%0ATentatives : <failures>%0ADuree : %(bantime)s sec"
actionunban = /usr/bin/curl -s -X POST \
"https://api.telegram.org/bot%(token)s/sendMessage" \
-d chat_id="%(chatid)s" \
-d parse_mode="HTML" \
-d text="✅ <b>UNBAN</b> sur <code>%(hostname)s</code>%0AJail : <code><name></code>%0AIP : <code><ip></code>"
[Init]
## Remplacez par vos valeurs
token = VOTRE_TOKEN_BOT_TELEGRAM
chatid = VOTRE_CHAT_ID
hostname = mon-serveurPuis activez l'action dans jail.local :
[sshd]
enabled = true
port = ssh
filter = sshd
maxretry = 3
findtime = 300
bantime = 3600
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 4w
mode = aggressive
## Action : ban IP + notification Telegram
action = %(action_)s
telegramRechargez et testez :
sudo fail2ban-client reload
## Test : bannir une IP fictive
sudo fail2ban-client set sshd banip 192.0.2.1
## Verifier que la notification Telegram arrive
## Puis debannir
sudo fail2ban-client set sshd unbanip 192.0.2.14. Hardening SSH complementaire
Fail2ban protege contre la force brute, mais durcir la configuration SSH reduit encore la surface d'attaque.
sudo nano /etc/ssh/sshd_config.d/hardening.conf## /etc/ssh/sshd_config.d/hardening.conf
## Durcissement SSH
## Desactiver l'authentification par mot de passe
## (uniquement si vous avez configure les cles SSH !)
## PasswordAuthentication no
## Desactiver la connexion root directe
PermitRootLogin prohibit-password
## Limiter les tentatives d'authentification par connexion
MaxAuthTries 3
## Fermer la connexion si pas d'auth en 30 secondes
LoginGraceTime 30
## Limiter le nombre de sessions SSH simultanees non authentifiees
MaxStartups 3:50:10
## Desactiver les methodes d'auth inutiles
KbdInteractiveAuthentication no
PermitEmptyPasswords no
## Algorithmes modernes uniquement
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.comVerifiez la syntaxe avant de recharger :
## Tester la configuration SSH (ne redemarre rien)
sudo sshd -t
## Si pas d'erreur, recharger
sudo systemctl reload ssh> Ne fermez pas votre session SSH actuelle. Ouvrez un nouveau terminal et testez la connexion. Si ca marche, vous pouvez fermer l'ancienne.
5. Script de monitoring
Un script rapide pour voir l'etat de toutes les jails d'un coup.
sudo nano /usr/local/bin/f2b-status#!/bin/bash
## /usr/local/bin/f2b-status
## Affiche l'etat complet de Fail2ban
echo "=== Fail2ban Status ==="
echo ""
## Liste des jails
JAILS=$(sudo fail2ban-client status | grep 'Jail list' | sed 's/.*://;s/,//g')
TOTAL_BANNED=0
for jail in $JAILS; do
STATUS=$(sudo fail2ban-client status "$jail" 2>/dev/null)
BANNED=$(echo "$STATUS" | grep 'Currently banned' | awk '{print $NF}')
TOTAL=$(echo "$STATUS" | grep 'Total banned' | awk '{print $NF}')
FAILED=$(echo "$STATUS" | grep 'Currently failed' | awk '{print $NF}')
echo "[$jail]"
echo " Bans actifs : $BANNED"
echo " Bans totaux : $TOTAL"
echo " Echecs en cours : $FAILED"
if [ -n "$BANNED" ]; then
TOTAL_BANNED=$((TOTAL_BANNED + BANNED))
fi
# Lister les IP bannies si il y en a
BANNED_IPS=$(echo "$STATUS" | grep 'Banned IP list' | sed 's/.*://')
if [ -n "$(echo $BANNED_IPS | tr -d ' ')" ]; then
echo " IPs bannies : $BANNED_IPS"
fi
echo ""
done
echo "=== Total bans actifs : $TOTAL_BANNED ==="
echo ""
echo "Derniers evenements :"
sudo tail -5 /var/log/fail2ban.log 2>/dev/null || sudo journalctl -u fail2ban -n 5 —no-pager## Rendre executable
sudo chmod +x /usr/local/bin/f2b-status
## Tester
sudo f2b-status6. Depannage
Fail2ban ne demarre pas
## Verifier la syntaxe de la configuration
sudo fail2ban-client -t
## Voir les logs detailles
sudo journalctl -u fail2ban -n 50 —no-pagerErreur frequente : No file(s) found for glob /var/log/auth.log. Sur les systemes recents utilisant journald, il n'y a pas de fichier auth.log. Assurez-vous d'avoir backend = systemd dans votre config.
Fail2ban ne detecte rien
## Tester le filtre manuellement
sudo fail2ban-regex systemd-journal /etc/fail2ban/filter.d/sshd.conf
## Verifier que le bon backend est utilise
sudo fail2ban-client get sshd logpath
sudo fail2ban-client get sshd journalmatchVous vous etes banni vous-meme
Si vous avez encore acces (console VPS, IPMI, KVM) :
## Debannir votre IP
sudo fail2ban-client set sshd unbanip VOTRE_IP
## Ou, en dernier recours
sudo systemctl stop fail2ban
sudo iptables -F
sudo systemctl start fail2banLe ban incremental ne fonctionne pas
Verifiez que la base SQLite est active :
## Verifier le chemin de la base
sudo fail2ban-client get dbfile
## Verifier les bans persistes
sudo sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 "SELECT ip, jail, timeofban, bancount FROM bans ORDER BY timeofban DESC LIMIT 10;"Les notifications Telegram n'arrivent pas
## Tester l'envoi direct
curl -s -X POST "https://api.telegram.org/botVOTRE_TOKEN/sendMessage" \
-d chat_id="VOTRE_CHAT_ID" \
-d text="Test Fail2ban"
## Verifier que curl est installe
which curl || sudo apt install curl -yFail2ban utilise trop de RAM
Sur un petit VPS, la base SQLite peut grossir. Limitez la retention :
## Dans jail.local, section [DEFAULT]
dbpurgeage = 7dLes IPs bannies reviennent apres un reboot
Normal si dbfile n'est pas configure. Fail2ban 1.x persiste les bans par defaut dans SQLite, mais verifiez :
sudo fail2ban-client get dbfileSi la reponse est None, ajoutez dans jail.local :
[DEFAULT]
dbfile = /var/lib/fail2ban/fail2ban.sqlite3Conflit avec UFW ou firewalld
Si vous utilisez UFW, Fail2ban doit utiliser l'action ufw au lieu d'iptables :
[DEFAULT]
banaction = ufwPour firewalld :
[DEFAULT]
banaction = firewallcmd-rich-rules7. Aller plus loin
Une fois Fail2ban en place, envisagez ces couches supplementaires :
- Port knocking avec
knockd: le port SSH n'est visible qu'apres avoir "frappe" sur une sequence de ports - Cles SSH + desactivation mots de passe : la meilleure protection contre la force brute, c'est de supprimer les mots de passe
- CrowdSec : alternative/complement a Fail2ban avec partage communautaire des IPs malveillantes
- Rate limiting au niveau reseau avec
iptablesounftables: limiter les nouvelles connexions SSH a 3/minute
Exemple de rate limiting nftables :
sudo nft add rule inet filter input tcp dport 22 ct state new limit rate 3/minute accept
sudo nft add rule inet filter input tcp dport 22 ct state new drop—-
À lire aussi
Nmap avancé : audit réseau et détection de vulnérabilités
Maîtrisez les techniques avancées de Nmap : scripts NSE, scan furtif, timing, détection d'OS, export automatisé et intégration dans vos workflows de sécurité.
Scanner son réseau avec Nmap : le guide pas à pas
Apprenez à utiliser Nmap pour détecter les appareils connectés, les ports ouverts et les failles de sécurité sur votre réseau. Guide complet pour débutants.
Audit de mots de passe avec KeePassXC : guide technique avancé
Audit complet de votre base KeePassXC : vérification HIBP en CLI, détection de doublons, automatisation avec keepassxc-cli et hardening de la base de données.