- Généralités
- Installation
- Les dossiers et fichiers de configuration
- Paramétrage par défaut
- Configuration avancée
- Configurer les filtres
- Créer son propre filtre
- Commandes de base
- Configurer une jail recidive
Généralités
Fail2ban se charge d’analyser les logs de divers services (SSH, Apache, FTP, Postifx, …) installés sur la machine, puis recherche les échecs d’authentification répétés et ajoute automatiquement une règle au pare-feu (iptables, nftables, shorewall ou ufw) pour bannir l’adresse IP de la source.
Installation
Il suffit d’installer le paquet.
apt install fail2ban
Et pour vérifier l’état du service Fail2Ban.
systemctl status fail2ban
Si la ligne commençant par Active contient la mention active (running), cela signifie que le service Fail2Ban est bien installé et en cours d’exécution.
Les dossiers et fichiers de configuration
Le chemin standard de la configuration se trouve dans /etc/fail2ban/.
Une configuration typique ressemble à ceci :
/etc/fail2ban ├── action.d/ → Actions à exécuter lors d’un ban/unban │ ├── apf.conf → Action pour le service apf │ ├── badips.conf → Action pour le service badips │ ├── badips.py → Script associé │ └── … → Autres actions disponibles │ ├── fail2ban.conf → Configuration globale │ ├── fail2ban.d/ → Répertoire de surcharge de config globale │ └── *.conf → Tes propres ajustements généraux │ ├── filter.d/ → Filtres qui détectent les intrusions │ ├── 3proxy.conf → Filtre pour 3proxy │ ├── apache-auth.conf → Détection des échecs d’auth Apache │ ├── apache-badbots.conf → Détection des robots malveillants │ └── … → Autres Filtres disponibles │ ├── jail.conf → Configuration par défaut des jails │ ├── jail.d/ → Répertoire pour tes propres jails │ └── defaults-debian.conf → Paramètres spécifiques à Debian │ └── *.local → Fichiers de tes jails personnalisées │ ├── paths-common.conf → Définitions des chemins de logs ├── paths-debian.conf → Spécifique à Debian (Apache, SSH, etc.) └── paths-opensuse.conf → Spécifique à openSUSE
Pour s’y retrouver et y voir plus clair, voici un récapitulatif.
Fichier / Dossier | Rôle / Description | Usage recommandé |
---|---|---|
fail2ban.conf | Fichier principal de configuration globale (paramètres généraux de Fail2Ban) | Ne pas modifier directement, surcharger via fail2ban.d |
fail2ban.d/ | Répertoire pour ajouter des fichiers de configuration personnalisés pour les paramètres globaux | Créer des fichiers .conf pour personnaliser la config |
jail.conf | Fichier principal définissant les jails (associations service + filtre + action) | Ne pas modifier directement, utiliser jail.d/ |
jail.d/ | Répertoire pour ajouter ou activer des jails personnalisées | Créer un fichier .conf par jail pour surcharger ou ajouter des prisons |
filter.d/ | Contient les filtres (regex) utilisés pour détecter les échecs dans les logs | Ajouter ou modifier un filtre si besoin |
action.d/ | Contient les actions exécutées lorsqu’un filtre détecte un comportement suspect (ban, mail…) | Ajouter ou personnaliser des actions selon l’environnement |
Chaque fichier .conf peut être remplacé par un fichier nommé .local.
Les modifications doivent avoir lieu dans le fichier .local et non dans le fichier .conf, donc il ne faut en aucun cas modifier jail.conf et fail2ban.conf car vous risquez de perdre leur contenu à la prochaine mise à jour de la distribution, ils doivent servir uniquement de référence et de documentation.
Paramétrage par défaut
Sur Debian, par défaut la prison (jail) sshd est active, ainsi elle protège des attaques bruteforce contre le service SSH.
Les paramètres par défaut sont visibles dans le fichier /etc/fail2ban/jail.conf.
La section [DEFAULT] définit les paramètres globaux qui s’appliquent à toutes les prisons (jails) si ceux-ci ne sont pas explicitement redéfinis dans la configuration d’une prison.
Paramètre | Description | Valeur par défaut |
---|---|---|
ignoreip | Liste d’adresses IP ou plages à ne jamais bannir | 127.0.0.1/8 |
bantime | Durée du bannissement d’une IP (en secondes) | 600 (10 min) |
findtime | Intervalle de temps pendant lequel les échecs sont comptés | 600 (10 min) |
maxretry | Nombre d’échecs autorisés avant bannissement | 5 |
backend | Méthode de surveillance des journaux (auto, systemd, polling…) | auto |
usedns | Utilisation de la résolution DNS inverse (yes, no, warn, raw) | warn |
logencoding | Encodage utilisé pour lire les fichiers de log | auto |
enabled | Activation d’une jail | false |
filter | Nom du filtre associé à la jail | %(__name__)s |
port | Ports surveillés (un ou plusieurs) | 0:65535 (tous) |
protocol | Protocole réseau à surveiller | tcp |
chain | Chaîne du pare-feu où ajouter les règles | INPUT |
destemail | Adresse email de destination des alertes | root@localhost |
sender | Adresse email de l’expéditeur | root@localhost |
mta | Agent de transport de mail utilisé | sendmail |
banaction | Action appliquée pour bannir sur les ports spécifiés | iptables-multiport |
banaction_allports | Action appliquée pour bannir sur tous les ports | iptables-allports |
action | Actions exécutées lorsqu’un filtre détecte une correspondance | %(action_)s |
La section # JAILS du fichier, indique les paramètres des prisons (jails).
Paramètre | Description | Exemple |
---|---|---|
[xxx] | Indique le nom de la jail | [sshd] |
enabled | Active la jail | true |
port | Port à surveiller | 22 |
filter | Utilise le filtre /etc/fail2ban/filter.d/xxx.conf (sans le .conf) | sshd |
logpath | Indique le chemin du ou des fichiers journaux (logs) que Fail2Ban doit surveiller pour détecter les échecs ou comportements suspects | /var/log/auth.log |
Les valeurs représentées ainsi %(… …)s sont des variables qui sont définies dans les fichiers de configuration /etc/fail2ban/paths_common.conf et /etc/fail2ban/paths_debian.conf.
La variable %(sshd_logs)s est égale à /var/log/auth.log.
Le parametre port = ssh est égale à port = 22 (on peut mettre directement le numéro du port, 22 pour ssh). Si vous avez changé le port par défaut, changez ici en conséquence.
L’activation de la prison (jail) sshd se trouve dans le fichier /etc/fail2ban/jail.d/defaults-debian.conf grâce au paramètre enabled à true.
Schéma simplifié :
sshd (jail)
|
|---> enabled → true
|---> logpath → /var/log/auth.log
|---> filter → filter.d/sshd.conf
|---> action → action.d/iptables-multiport.conf
Fail2ban va alors scruter le contenu de /var/log/auth.log afin de vérifier les tentatives de connexion SSH.
Ensuite il reporte tout dans son fichier journal. Ainsi pour vérifier si des détections ont lieu, il faut regarder dans le fichier /var/log/fail2ban.log.
Notes :
Found : l’occurrence est trouvée
Ban : le seuil est dépassé (maxfailure) et l’action est réalisée
Explication de l’exemple [sshd] avec les valeurs par défaut :
Si une machine tente de se connecter à SSH et échoue 5 fois (maxretry = 5).
Si ces tentatives se produisent dans une fenêtre de 600 secondes (findtime = 600, soit 10 minutes).
Alors Fail2Ban déclenche la jail [sshd] et bloque uniquement le port 22 (port = 22) en TCP (protocol = tcp).
En résumé :
5 échecs en moins de 10 minutes → IP bannie sur le port SSH pendant 10 minutes.
Configuration avancée
Vous pouvez supprimer le fichier defaults-debian.conf.
rm /etc/fail2ban/jail.d/defaults-debian.conf
Vous pouvez créer un fichier jail.local (nomdevotrechoix.local) dans le dossier /etc/fail2ban/jail.d/.
nano /etc/fail2ban/jail.d/jail.local
Pour configurer les paramètres globaux (qui concerne donc toutes les prisons, si le paramètre n’est pas défini dans la prison), ressaisissez les paramètres comme dans l’exemple.
[INCLUDES]
before = paths-debian.conf
[DEFAULT]
ignoreip = 127.0.0.1/8 192.168.1.1
bantime = 86400
findtime = 3600
maxretry = 5
backend = auto
usedns = warn
logencoding = auto
enabled = false
filter = %(__name__)s
protocol = all
chain = INPUT
port = 0:65535
fail2ban_agent = Fail2Ban/%(fail2ban_version)s
destemail = root@localhost
sender = root@localhost
mta = sendmail
banaction = iptables-multiport
banaction_allports = iptables-allports
action = %(action_mwl)s
Les paramètres globaux sont définis dans la section [DEFAULT].
- [INCLUDES]
- before = paths-debian.conf : contient les chemins vers différents fichiers logs
- [DEFAULT]
- ignoreip = 127.0.0.1/8 192.168.1.1 : ne pas bannir les IP 127.0.0.1 et 192.168.1.1
- bantime = 86400 : temps de bannissement (1 jour)
- findtime = 3600 : intervalle de temps pendant laquelle les essais vont incrémenter maxretry (1 heure)
- maxretry = 5 : nombre de tentatives de connexion échoué
- backend = auto : méthode de surveillance des logs (auto)
- usedns = warn : si un nom d’hôte est rencontré, une recherche DNS sera effectuée
- logencoding = auto : encodage des fichiers logs gérés par les prisons
- enabled = false : désactive par défaut les prisons, pour pouvoir les activer une par une
- filter = %(__name__)s : les prisons ont des noms correspondant à leur nom de filtre
- protocol = all : bloque le(s) port(s) sur tous les protocoles (TCP/UDP/ICMP)
- chain = INPUT : chaîne qui devraient être ajoutés dans les actions iptables
- port = 0:65535 : ports pouvant être bannis
- fail2ban_agent = Fail2Ban/%(fail2ban_version)s : variable utilisé par Fail2Ban
- destemail = root@localhost : adresse email pour envoyer des notifications de banissement
- sender = root@localhost : adresse email de l’émeteur
- mta = sendmail : type de serveur de messagerie électronique utilisé
- banaction = iptables-multiport : bannissement de l’IP sur un port spécifique
- banaction_allports = iptables-allports : bannissement de l’IP sur tous les ports
- action = %(action_mwl)s : bannie l’IP + envoie un mail avec whois + log l’événement
Pour créer une prison (jail) du service SSH, ressaisissez les paramètres comme dans l’exemple.
[sshd]
enabled = true
port = 2222
logpath = /var/log/auth.log
filter = sshd
banaction = %(banaction_allports)s
action = %(action_mwl)s
maxretry = 4
findtime = 3600
bantime = 86400
- [sshd] : nom de la prison (jail)
- enabled = true : active la prison (jail)
- port = 2222 : le port à bloquer
- logpath = /var/log/auth.log : emplacement du fichier de log à surveiller
- backend = %(sshd_backend)s : méthode de surveillance des logs (auto)
- filter = sshd : utilise le filtre /etc/fail2ban/filter.d/sshd.conf (sshd, sans le .conf)
- banaction = %(banaction_allports)s : bannissement de l’IP sur tous les ports (iptables-allports)
- action = %(action_mwl)s : envoye un mail avec le whois et les logs de l’ip bannie
- maxretry = 4 : nombre de tentatives de connexion échoué
- findtime = 3600 : intervalle de temps pendant laquelle les essais de connexion vont incrémenter maxretry (1 heure)
- bantime = 86400 : temps de bannissement (1 jour)
Cela permet d’ajuster la configuration et le filtre associé à cette prison, en spécifiant par exemple un nombre de tentatives différent de la valeur par défaut, un port différent, un temps de bannissement différent de la valeur par défaut, etc…
Explication de l’exemple [sshd] avec ses paramètres :
Si une machine tente de se connecter à SSH et échoue 4 fois (maxretry = 4).
Si ces tentatives se produisent dans une fenêtre de 3600 secondes (findtime = 3600, soit 1 heure).
Alors Fail2Ban déclenche la jail [sshd] et bloque tous les ports (banaction = %(banaction_allports)s) sur tous les protocoles (protocol = all) pendant 86400 secondes (bantime = 86400, soit 1 jour) et envoie un mail & écrit l’événement dans les logs Fail2Ban (action = %(action_mwl)s).
En résumé :
4 échecs en moins de 1 heure → IP bannie sur tous les ports pendant 1 jour + un mail est envoyé + log l’événement.
Le paramètre action correspond à l’exécution d’un ou plusieurs fichier(s) du dossier /etc/fail2ban/action.d/, typiquement, Fail2ban exécutera une action lorsqu’une ligne de log détectée par nos filtres apparaitra un certain nombre de fois. Les actions peuvent alors être des événements de protections (bannir l’IP en question, etc…) ou alors des événements d’alerte (envoyer un mail, etc …).
Le paramètre filter correspond à un fichier de configuration situé dans le dossier /etc/fail2ban/filter.d/, il faut le déclarer sans l’extension (.conf). Ce fichier de configuration va contenir des expressions régulières qui permettent de déterminer si une ligne dans les logs est considérée comme un échec d’authentification.
Configurer les filtres
Fail2ban fournit pas mal de prisons pour la plupart des services réseaux (HTTP, SMTP, SSH, …). Chaque prison est associé à un fichier de filtrage du même nom dans le dossier /etc/fail2ban/filter.d/ (pour la prison [sshd], le filtre sshd.conf).
Ces fichiers contiennent une ou plusieurs expressions régulières qui servent de motif de recherche pour les lignes correspondantes dans les logs. Les expressions sont définies par la directive failregex.
Voici un exemple de l’une des expressions du filtre sshd.conf. Sans détailler toute l’expression, on recherche ici les échecs d’authentification sur le service SSH. On va donc ici appliquer ce filtre sur un fichier de log du service SSH.
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error|failed) for .* from <HOST>( via \S+)?\s*$
Cette expression entrera en correspondance avec toutes les lignes du fichier de log du service SSH (/var/log/auth.log) contenant des erreurs ou des échecs d’authentification.
Créer son propre filtre
Pour rappel, les filtres sont stockés dans /etc/fail2ban/filter.d/, nous allons donc nous y rendre pour créer un nouveau filtre. Chaque filtre est représenté et assigné par son nom dans une configuration de prison (jail) dans Fail2ban. On va donc être attentif au nom que l’on donne à notre filtre.
Un filtre sous Fail2ban va contenir une structure prédéfinie qui ressemble à ceci :
[INCLUDES]
before =
after =
[Definition]
_daemon =
failregex =
ignoreregex =
[Init]
maxlines =
journalmatch =
Dans la partie [Definition], failregex et ignoreregex sont important. Pour s’y retrouver et y voir plus clair, voici un récapitulatif.
- [INCLUDES] (facultatif)
- before : importation d’un autre filtre avant la déclaration de se filtre, ce champ est optionnel
- after : importation d’un autre filtre après la déclaration de se filtre, ce champ est optionnel
- [Definition]
- _daemon : utilisée pour construire l’expression régulière __prefix_line, ce champ est optionnel (utilisé avec common.conf)
- failregex : expression régulière du filtre, on définit ici ce qu’il faut surveiller (toutes les lignes de log analysées qui correspondront aux lignes mis ici seront susceptibles de déclencher l’action associée dans la jail)
- ignoreregex : exceptions que l’on souhaite déclarer, ce champ est optionnel, mais il peut avoir un réel intérêt dans certains cas
- [Init] (facultatif)
- maxlines : nombre de lignes de log à mettre en mémoire tampon pour les recherches regex multi-lignes, ce champ est optionnel
- journalmatch : spécifie la correspondance de log systemd utilisée pour filtrer les entrées de log, ce champ est optionnel
Pour créer un filtre personnalisé, je rappelle qu’il faut avoir clairement identifié :
- La ou les ligne(s) de logs que l’on souhaite surveiller
- Le ou les fichier(s) de logs dans lesquel(s) ces lignes seront ajoutées
imaginons un service fictif qui écrit ses logs dans /var/log/log-perso.log.
Pour l’exemple, je vais créer un filtre nommé filtre-perso.conf, qui va détecter une expression dans le fichier de log fictif.
nano /etc/fail2ban/filter.d/filtre-perso.conf
Je souhaite qu’à chaque fois que mon service fictif génère une ligne du genre, ci dessous, dans ses logs, l’IP source soit bannie.
Apr-07-13 07:08:36 Invalid command user from 192.168.1.4
Je vais donc créer l’expression régulière me permettant de surveiller l’apparition de ce genre de ligne dans mes logs.
[Definition]
failregex = .* Invalid command .* from <HOST>
ignoreregex =
Notez tout d’abord que mon expression régulière n’est pas complexe du tout.
La présence de la chaine <HOST> est obligatoire dans un filtre Fail2ban lorsque l’on souhaite récupérer une IP, par exemple pour la renseigner à iptables en vue d’un bannissement temporaire. La chaine <HOST> est donc positionnée à l’endroit où sera l’IP dans la ligne de logs filtrée.
Une fois votre failregex créé, il est possible de le tester rapidement via la commande fail2ban-regex, pour tester le filtre filtre-perso.conf sur le fichier journal log-perso.log.
fail2ban-regex /var/log/log-perso.log /etc/fail2ban/filter.d/filtre-perso.conf
Ce que fait la commande :
- Scanne le fichier de log ligne par ligne.
- Compare chaque ligne avec le failregex du filtre.
- Affiche un résumé :
- lines = nombre total de lignes analysées
- ignored = lignes ignorées par ignoreregex
- matched = lignes qui correspondent à failregex
- missed = lignes qui ne correspondent pas
- Utile pour valider que votre filtre détecte bien les tentatives échouées avant de l’ajouter à une jail.
Voici mon fichier de log fictif de mon service fictif :
Apr-07-13 07:08:28 Accepted command paul from 192.168.0.15
Apr-07-13 07:08:32 Invalid command thomas from 192.168.0.15
Apr-07-13 07:08:36 Accepted command pierre from 192.168.0.15
Apr-07-13 07:08:41 Accepted command mic from 192.168.0.15
Apr-07-13 07:08:45 Invalid command pierre from 192.168.0.15
La sortie Lines: 5 lines, 0 ignored, 2 matched, 3 missed indique que Fail2Ban a analysé un total de 5 lignes du fichier de log. Aucune ligne n’a été ignorée (0 ignored), 2 lignes correspondent à l’expression régulière du filtre (2 matched), et 3 lignes n’ont pas correspondu (3 missed).
On voit bien les 2 lignes Invalid command.
Modifions maintenant notre fichier de configuration pour activer notre nouveau filtre.
nano /etc/fail2ban/jail.d/jail.local
Ne pas oublier de déclarer le filtre SANS le .conf (filter = filtre-perso).
[filtre-perso]
enabled = true
port = 1234
logpath = /var/log/log-perso.log
filter = filtre-perso
banaction = %(banaction_allports)s
action = %(action_mwl)s
maxretry = 8
findtime = 3600
bantime = 86400
En vrais vous n’avez pas besoin de déclarer le filtre si le nom de la prison (jail) et le même que le nom du filtre (nom de la prison [filtre-perso] et nom du filtre filtre-perso).
Commandes de base
Voir le status des jails
Pour savoir si votre jail est actif, vous devriez le voir affiché, après avoir taper cette commande :
fail2ban-client status
Cette commande affiche tous les jails que fail2ban traite.
Pour savoir si une de vos jails de votre fail2ban a bannis une ou plusieurs IP, taper cette commande :
fail2ban-client status nom_du_jail
Cette commande va afficher le nombre de tentative lu dans vos logs, le nombre de bannis et, le plus intéressant, les IPs qui sont bannis temporairement.
Redémarrer fail2ban
Pour redémarrer fail2ban :
systemctl restart fail2ban
Tester un filtre
Pour tester un filtre sur un fichier de log particulier :
fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/apache-badbots.conf
Cette commande teste le filtre apache-badbots sur le fichier journal d’Apache (prend en premier paramètre une chaine ou un fichier de log, et en second le filtre que l’on souhaite tester)
Dé-bannir une IP de l’un de vos jails
Si une de vos adresse IP se retrouve blacklisté suite à une mauvaise manipulation répété ou un test de sécurité. Vous pouvez la retirer de la liste des IP blacklisté de fail2ban avec cette commande :
fail2ban-client set nom_du_jail unbanip ip_à_débannir
Bannir manuellement une IP sur l’un de vos jails
Vous voulez tester plus rapidement l’interdiction d’un accès d’une adresse IP, ou bloquer une personne malveillante. Renseignez son IP dans cette commande :
fail2ban-client set nom_du_jail banip ip_à_bannir
Configurer une jail recidive
La prison (jail) très intéressante à activer, la jail recidive est une prison (Jail) pour les récidivistes.
Lors de l’activation de cette jail, Fail2ban scanne son propre fichier de log (/var/log/fail2ban.log) et y recherche les IPs récurrentes qui ont été bannies par les règles définies dans les autres jails.
Vous pouvez créer un fichier fail2ban.local (nomdevotrechoix.local) dans le dossier /etc/fail2ban/fail2ban.d/.
nano /etc/fail2ban/fail2ban.d/fail2ban.local
Fail2ban utilise une base sqlite3. Nous allons définir le paramètre dbpurgeage (durée de rétention des informations dans la base de données de Fail2ban) à 648000 (soit 7.5 jours) pour la configuration de la prison (jail) recidive, ressaisissez les paramètres comme dans l’exemple.
[Definition]
loglevel = INFO
logtarget = /var/log/fail2ban.log
dbpurgeage = 648000
Maintenent, il faut paramétrer et activer la prison (jail) recidive.
Dans le fichier jail.local (nomdevotrechoix.local) dans le dossier /etc/fail2ban/jail.d/.
nano /etc/fail2ban/jail.d/jail.local
Ressaisissez les paramètres comme dans l’exemple.
[recidive]
enabled = true
bantime = 2592000
findtime = 604800
maxretry = 3
action = %(action_mwl)s
banaction = %(banaction_allports)s
logpath = /var/log/fail2ban.log
Les IPs sont alors bannies et ceci sur tous les ports pour une période plus longue (bantime = 2592000, ici 30 jours) si sur 7 jours (findtime = 604800), une IP est bannie plus de 3 fois (maxretry = 3). C’est pourquoi le paramètre de rétention dbpurgeage a été fixé à 7.5 jours, sinon la jail recidive ne fonctionnerait pas très bien.