fail2ban - Protection Anti-Brute-Force
Service de détection et bannissement automatique d'IPs malveillantes.
Principe
fail2ban surveille logs système (SSH, services web, etc.) et bannit IPs avec trop de tentatives échouées.
Fonctionnement :
- Monitor logs en temps réel
- Détecte patterns échecs (failed password, 404, etc.)
- Ban IP temporairement via iptables
- Unban automatique après expiration
Installation
Configuration
Structure Fichiers
/etc/fail2ban/
├── jail.conf # Config par défaut (NE PAS MODIFIER)
├── jail.local # Overrides locaux (CRÉER CE FICHIER)
├── filter.d/ # Patterns regex pour détection
└── action.d/ # Actions (iptables, mail, etc.)
jail.local Principal
Configuration Recommandée :
[DEFAULT]
# Ban duration (secondes)
bantime = 3600 # 1 heure
# Time window pour comptage tentatives
findtime = 600 # 10 minutes
# Max tentatives avant ban
maxretry = 3
# Whitelist IPs (ne jamais ban)
ignoreip = 127.0.0.1/8 192.168.1.0/24 ::1
# Ban action (iptables)
banaction = iptables-multiport
banaction_allports = iptables-allports
# Email notifications (optionnel)
destemail = admin@domain.com
sendername = Fail2Ban-Proxmox
mta = sendmail
action = %(action_mwl)s # Ban + mail with logs
# Logs
logtarget = /var/log/fail2ban.log
# Backend
backend = systemd
#
# JAILS - Services Protégés
#
[sshd]
enabled = true
port = 2222 # Port SSH custom
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
[proxmox]
enabled = true
port = 8006
filter = proxmox
logpath = /var/log/daemon.log
maxretry = 3
bantime = 7200 # 2 heures
[nginx-http-auth]
enabled = false # À activer si nginx installé
port = http,https
logpath = /var/log/nginx/error.log
Filtre Proxmox Custom
Créer filtre pour authentification Proxmox Web :
Contenu :
[Definition]
failregex = pvedaemon\[.*authentication failure; rhost=<HOST>
authentication failure; rhost=<HOST>
ignoreregex =
Démarrage
# Enable au boot
systemctl enable fail2ban
# Start service
systemctl start fail2ban
# Status
systemctl status fail2ban
# Vérifier jails actifs
fail2ban-client status
Output attendu :
Utilisation
Commandes Principales
# Status global
fail2ban-client status
# Status jail spécifique
fail2ban-client status sshd
# Bannir IP manuellement
fail2ban-client set sshd banip 192.168.1.100
# Débannir IP
fail2ban-client set sshd unbanip 192.168.1.100
# Reload configuration
fail2ban-client reload
# Restart jail
fail2ban-client restart sshd
Vérifier IPs Bannies
Output exemple :
Status for the jail: sshd
|- Filter
| |- Currently failed: 5
| |- Total failed: 127
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 2
|- Total banned: 15
`- Banned IP list: 203.0.113.42 198.51.100.23
Voir Règles iptables
# Liste rules fail2ban
iptables -L -n | grep f2b
# Chain fail2ban spécifique
iptables -L f2b-sshd -n -v
Monitoring
Logs fail2ban
# Tail logs temps réel
tail -f /var/log/fail2ban.log
# Derniers bans
grep "Ban" /var/log/fail2ban.log | tail -20
# Derniers unbans
grep "Unban" /var/log/fail2ban.log | tail -20
# Statistiques jail
grep "sshd" /var/log/fail2ban.log | grep "Ban" | wc -l
Logs Services Surveillés
# SSH attempts
grep "Failed password" /var/log/auth.log | tail -20
# Proxmox auth failures
grep "authentication failure" /var/log/daemon.log | tail -20
Script Monitoring
#!/bin/bash
# /usr/local/bin/fail2ban-report.sh
echo "=== fail2ban Status Report ==="
echo
fail2ban-client status | grep "Jail list"
echo
for jail in $(fail2ban-client status | grep "Jail list" | sed 's/.*Jail list:\s*//' | tr ',' '\n'); do
echo "--- $jail ---"
fail2ban-client status $jail | grep "Currently banned"
fail2ban-client status $jail | grep "Total banned"
echo
done
Usage :
Jails Additionnels
Nginx (si installé)
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
[nginx-noscript]
enabled = true
port = http,https
filter = nginx-noscript
logpath = /var/log/nginx/access.log
maxretry = 6
[nginx-badbots]
enabled = true
port = http,https
filter = nginx-badbots
logpath = /var/log/nginx/access.log
maxretry = 2
Docker Services (optionnel)
[jellyfin]
enabled = false
port = 8096
filter = jellyfin
logpath = /var/lib/docker/containers/*/*.log
maxretry = 5
Note : Nécessite création filtres custom pour apps Docker.
Notifications
Email Alerts
Nécessite MTA configuré (postfix, sendmail).
[DEFAULT]
destemail = admin@domain.com
sendername = Fail2Ban-Homelab
# Actions avec email
action = %(action_mwl)s # Mail with logs
Telegram Bot (Advanced)
[Definition]
actionban = curl -X POST "https://api.telegram.org/bot<TOKEN>/sendMessage" \
-d "chat_id=<CHAT_ID>" \
-d "text=🚨 Ban: <ip> on <name>"
actionunban = curl -X POST "https://api.telegram.org/bot<TOKEN>/sendMessage" \
-d "chat_id=<CHAT_ID>" \
-d "text=✅ Unban: <ip> on <name>"
Usage dans jail :
Testing
Tester Détection
# Depuis autre machine - tentatives failed password
ssh root@192.168.1.21 -p 2222
# Taper mauvais password 3 fois
# Vérifier ban
fail2ban-client status sshd
Tester Filtre
# Test regex filtre
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
# Output montre matches
Simuler Ban
# Bannir IP test
fail2ban-client set sshd banip 192.0.2.1
# Vérifier iptables
iptables -L f2b-sshd -n -v
# Unban
fail2ban-client set sshd unbanip 192.0.2.1
Troubleshooting
fail2ban Ne Démarre Pas
# Vérifier config
fail2ban-client -t
# Logs erreurs
journalctl -u fail2ban -n 50
# Test config jail.local
fail2ban-client -d
Règles iptables Persistent
fail2ban gère automatiquement, mais pour persist après reboot :
# Installer iptables-persistent
apt install iptables-persistent
# Sauvegarder rules (si nécessaire)
iptables-save > /etc/iptables/rules.v4
IP Auto-Banni (lockout)
Prévention :
Si déjà banni :
- Accès console Proxmox (physique/VNC)
- Unban :
Jail Ne Fonctionne Pas
# Vérifier jail actif
fail2ban-client status
# Vérifier logpath correct
ls -la /var/log/auth.log
# Test filtre
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
# Restart jail
fail2ban-client restart sshd
Performance
Impact Système
Optimisation
Statistiques
Rapport Mensuel
#!/bin/bash
# Total bans par jail dernier mois
echo "=== fail2ban Monthly Report ==="
date
echo
for jail in $(fail2ban-client status | grep "Jail list" | sed 's/.*://'); do
count=$(grep "Ban" /var/log/fail2ban.log | grep "$jail" | wc -l)
echo "$jail: $count bans"
done