Outils pour utilisateurs

Outils du site


Mise en œuvre

Principe de fonctionnement

Fail2ban observe en permanence les journaux des services que l'on souhaite protéger des agressions. Lorsqu'il découvre une action frauduleuse:

  1. il mémorise l'adresse IP (v4 aussi bien que v6) du malfaiteur,
  2. il vérifie combien de fois il a capturé cette adresse dans un certain laps de temps,
  3. si il l'a capturée un certain nombre de fois, il va ajouter une règle de filtrage qui va bloquer cette adresse, pendant un certain temps,
  4. il peut même, s'il constate que cette adresse a déjà fait l'objet d'un blocage dan un (autre) certain laps de temps, il en conclut que c'est un récidiviste et, comme tout récidiviste, il sera plus lourdement puni en étant à nouveau bloqué pendant un (autre) certain laps de temps.
  5. à chaque intervention de sa part, il peut envoyer un e-mail au responsable de la sécurité du machin.

Tout ceci est bien évidemment entièrement paramétrable.

La version utilisée ici (1.1.0 du 25/04/2024) est celle qui est distribuée dans la Debian Trixie. La date pourrait laisser penser que le projet se meurt mais ce n'est pas le cas. Il a au contraire atteint une belle maturité.

Il sait utiliser nftables, sait lire les journaux créés par «systemd», il est supervisé par systemd, il gère les adresses IPv6.

Installation et visite

La partie facile:

apt install fail2ban

La visite, c'est autre chose…
Dans /etc/fail2ban:

drwxr-xr-x 2 root root  4096 20 juin  17:02 jail.d
drwxr-xr-x 3 root root  4096 20 juin  17:02 filter.d
drwxr-xr-x 2 root root  4096 20 juin  17:02 action.d
drwxr-xr-x 2 root root  4096  9 mai   12:19 fail2ban.d
-rw-r--r-- 1 root root   930  9 mai   12:19 paths-debian.conf
-rw-r--r-- 1 root root  3017 25 avril  2024 fail2ban.conf
-rw-r--r-- 1 root root 25847 25 avril  2024 jail.conf
-rw-r--r-- 1 root root   645 25 avril  2024 paths-arch.conf
-rw-r--r-- 1 root root  2727 25 avril  2024 paths-common.conf
-rw-r--r-- 1 root root   738 25 avril  2024 paths-opensuse.conf
Plusieurs sous-répertoires qu'il faudra visiter par la suite.

fail2ban.conf

Dans fail2ban.conf (nettoyé de ses commentaires):

[DEFAULT]
loglevel = INFO
logtarget = /var/log/fail2ban.log
syslogsocket = auto
socket = /var/run/fail2ban/fail2ban.sock
pidfile = /var/run/fail2ban/fail2ban.pid
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 1d
dbmaxmatches = 10
[Definition]
[Thread]
Il y a un socket UNIX. Nous verrons qu'un client fail2ban-client est en mesure de communiquer avec le démon pour… Nous verrons plus tard.

Un fichier au format sqlite va conserver les adresses interceptées, ce qui permettra de conserver les bannissements actifs, même en cas de redémarrage du système.

Les autres paramètres, bien qu'utiles seront pour l'instant. passés sous silence.

paths-debian.conf

[INCLUDES]
before = paths-common.conf
after  = paths-overrides.local
[DEFAULT]
syslog_mail = /var/log/mail.log
syslog_mail_warn = %(syslog_mail)s
syslog_user  =  /var/log/user.log
syslog_ftp = /var/log/syslog
syslog_daemon =  /var/log/daemon.log
exim_main_log = /var/log/exim4/mainlog
proftpd_log = /var/log/proftpd/proftpd.log
roundcube_errors_log = /var/log/roundcube/errors.log
syslog_backend = systemd
sshd_backend = systemd
dropbear_backend = systemd
proftpd_backend = systemd
pureftpd_backend = systemd
wuftpd_backend = systemd
postfix_backend = systemd
dovecot_backend = systemd
Retenons pour l'instant que les «backends» (les sources d'informations pour fail2ban) qui nous intéressent le plus sont issues de systemd. Autrement dit, pour les distributions Debian, fail2ban s'intéressera pour ces services aux journaux gérés par systemd.

jail.conf

«jail» voulant dire: «prison». Ce fichier est le point de départ de la définition du comportement de fail2ban.

Ce très volumineux fichier contient essentiellement deux parties:

[INCLUDES]
before = paths-debian.conf
[DEFAULT]
ignorecommand =
bantime  = 10m
findtime  = 10m
maxretry = 5
maxmatches = %(maxretry)s
backend = auto
usedns = warn
logencoding = auto
enabled = false
mode = normal
filter = %(__name__)s[mode=%(mode)s]
destemail = root@localhost
sender = root@<fq-hostname>
mta = sendmail
protocol = tcp
chain = 
port = 0:65535
fail2ban_agent = Fail2Ban/%(fail2ban_version)s
banaction = iptables-multiport
banaction_allports = iptables-allports
action_ = %(banaction)s[port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
action_mw = %(action_)s
            %(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
action_mwl = %(action_)s
             %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
action_xarf = %(action_)s
             xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
                %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
action_blocklist_de  = blocklist_de[email="%(sender)s", service="%(__name__)s", apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"]
action_abuseipdb = abuseipdb
action = %(action_)s
Le surlignage jaune indique les paramètres qui seront pris par défaut pour un filtre donné. Nous verrons dans un exemple ce que ceci implique. Les parties en gras étant les plus remarquables en première approche:

  • bantime = 10m
    Durée du bannissement, lorsqu'il est décidé.
  • findtime = 10m
    la durée pendant laquelle fail2ban s'intéresse à une IP repérée.
  • maxretry = 5
    le nombre d'essais auquel à droit cette IP durant le «findtime».
  • maxmatches = %(maxretry)s
    le nombre de fois que l'IP a exécuté une opération frauduleuse durant le «findtime», par défaut égal au nombre d'essais.
  • backend = auto
    La source d'informations à scruter, «auto» faisant référence aux sources vues plus haut.
banaction = iptables-multiport
banaction_allports = iptables-allports

Notons que par défaut, ce serait à iptables de gérer les filtres, ce qui ne doit pas être notre cas puisque nous avons choisi nftables. Il faudre intervenir pour modifier ceci.

Le surlignage orange décrit les actions possibles lorsqu'il est décidé qu'une IP est malveillante. la syntaxe permettant de décrire ces actions n'est pas très complexe, mais laissons tomber pour l'instant :

  • action_
    action la plus simple, elle ne déclenche qu'un simple bannissement.
  • action_mw
    en plus du bannissement, un e-mail est envoyé au destinataire défini plus haut, avec un rapport «whois».
  • action_mwl
    e-mail avec rapport «whois» et les lignes de log qui ont déclenché l'alerte.
  • action_xarf
    Complètement inutile, dans la mesure où en plus du bannissement, elle envoie un e-mail au contact «abuse» décrit dans le whois, qui le plus souvent n'en a rien à faire…
  • action_cf_mwl
    concerne les abonnés à Cloudflare, ce qui est ici hors-sujet.
  • action_blocklist_de
    hors de propos en première approche.
  • action_abuseipdb
    hors de propos en première approche.
  • action = %(action_)s
    L'action qui sera menée par défaut étant définie ici comme étant la plus simple: «action_»

Pour approfondir la question, il est utile de lire les commentaires inscrits dans jail.conf et non retranscrits ici.

En ce qui concerne l'action «action_cf_mwl» celle-ci n'affichera les lignes de logs que si le «backend» est un fichier de logs «à l'ancienne». Dans le cas de journaux gérés par systemd il faudra, si l'on souhaite les ligne de logs, créer une action supplémentaire…

La seconde partie définit justement des «prisons» que l'on veut activer pour différents services. Aucune n'est active par défaut puisque le paramètre «enabled» est justement positionné par défaut sur «faux».

Ce qui est inscrit dans cette seconde partie ne devrait servir que de modèle et en aucun cas être activé dans ce fichier. C'est ce que l'on va inscrire dans le répertoire jail.d qui sera décisif.

action.d

Ce répertoire contient une collection d'actions. Il n'est absolument pas question d'analyser ces configurations tant qu'on n'est pas devenu un spécialiste de ce logiciel. Il est cependant utile d'identifier certaines configurations d'actions dont on peut retrouver les noms dans les définitions d'actions vues dans jail.conf.

En premier lieu:

nftables-allports.conf
nftables.conf
nftables-multiport.conf

qui vont devoir remplacer les:

iptables-allports.conf
iptables.conf
iptables-multiport.conf

Nous allons voir comment opérer proprement.

D'autres actions comme les mail-*.conf peuvent être intéressantes à lire, si l'on souhaite modifier le contenu des notifications.

filter.d

Ce répertoire contient les filtres spécifiques à chaque service que fail2ban sait surveiller. Nous y trouvons par exemple:

sshd.conf
dovecot.conf
postfix.conf

Mais également une série de filtres concernant apache, nginx etc.

Ce sont des expressions régulières (aussi nommées «expressions rationnelles»). Il faut beaucoup de patience et de persévérance arriver à les maîtriser. Retenons que leur fonction consiste à identifier les messages d'erreur intéressants dans les logs, concernant un service donné ou pour un service donné, concernant un type d'attaque donné.

jail.d

Celui dans lequel nous allons intervenir pour activer les filtres qui nous intéressent, car il est écrit en commentaire dans jail.conf:

# Changes:  in most of the cases you should not modify this
#           file, but provide customizations in jail.local file,
#           or separate .conf files under jail.d/ directory, e.g.:
#
# HOW TO ACTIVATE JAILS:
#
# YOU SHOULD NOT MODIFY THIS FILE.
#
# It will probably be overwritten or improved in a distribution update.
#
# Provide customizations in a jail.local file or a jail.d/customisation.local.
# For example to change the default bantime for all jails and to enable the
# ssh-iptables jail the following (uncommented) would appear in the .local file.
# See man 5 jail.conf for details.

Les divers fichiers contenus dans ce répertoire seront lus par ordre alphabétique et leur contenu écrasera éventuellement ce qui a pu être défini précédemment.

Mise en œuvre: Dernière modification le: 06/07/2025 à 15:50 par prof