Aller au contenu

Pare-feu : Fail2ban, jails et filtres

Protéger des services précis avec des jails et écrire ses propres filtres.

[sshd]
enabled = true
maxretry = 3
findtime = 10m
bantime = 1h
mode = aggressive
mode Échecs comptés
normal (défaut) Mots de passe erronés, clés refusées
ddos + connexions interrompues avant l’authentification
extra normal + ddos
aggressive Tout, y compris les utilisateurs inexistants

Voir SSH : durcissement du serveur.

[nginx-http-auth]
enabled = true
[nginx-limit-req]
enabled = true
[nginx-botsearch]
enabled = true
Jail Détecte
nginx-http-auth Échecs d’authentification basique
nginx-limit-req Dépassements de limit_req
nginx-botsearch Recherche de scripts inexistants

Ces filtres lisent /var/log/nginx/error.log.

[apache-auth]
enabled = true
[apache-badbots]
enabled = true
[apache-noscript]
enabled = true

Caddy n’a pas de jail intégrée. Il écrit un journal d’accès JSON (voir Exemple : VPS avec Caddy) :

{"level":"info","ts":1791217629.04,"logger":"http.log.access.log0","msg":"handled request","request":{"remote_ip":"203.0.113.9","client_ip":"203.0.113.9","method":"GET","host":"exemple.com","uri":"/admin/"},"status":401}

Filtre /etc/fail2ban/filter.d/caddy-auth.conf (401 et 403) :

[Definition]
failregex = ^.*"client_ip":"<ADDR>".*"status":(?:401|403),
datepattern = "ts":{EPOCH}
ignoreregex =

Filtre /etc/fail2ban/filter.d/caddy-sondes.conf (sondes de scanners) :

[Definition]
failregex = ^.*"client_ip":"<ADDR>".*"uri":"[^"]*(?:/\.env|/\.git|wp-login\.php|xmlrpc\.php|phpmyadmin|/admin\.php|/cgi-bin)[^"]*".*"status":404,
datepattern = "ts":{EPOCH}
ignoreregex =

Jails :

[caddy-auth]
enabled = true
port = http,https
filter = caddy-auth
logpath = /var/log/caddy/acces.log
maxretry = 5
findtime = 10m
bantime = 1h
[caddy-sondes]
enabled = true
port = http,https
filter = caddy-sondes
logpath = /var/log/caddy/acces.log
maxretry = 3
bantime = 1d

<ADDR> désigne une adresse IP (IPv4 ou IPv6) ; {EPOCH} indique une date en horodatage Unix (champ ts de Caddy).

  1. Repérer une ligne de journal représentative d’un échec.
  2. Écrire failregex en remplaçant l’adresse par <ADDR>.
  3. Vérifier avec fail2ban-regex, sans rien bannir.
Fenêtre de terminal
sudo fail2ban-regex /var/log/caddy/acces.log caddy-auth
sudo fail2ban-regex 'ligne copiée' 'regex'
sudo fail2ban-regex systemd-journal sshd
sudo fail2ban-regex --print-all-missed /var/log/caddy/acces.log caddy-auth | head
Lines: 17 lines, 0 ignored, 8 matched, 9 missed

matched : lignes reconnues comme échec ; missed : lignes non reconnues (normal pour les accès réussis). Si matched vaut 0 alors que des échecs existent, ajuster failregex et vérifier datepattern.

Réglage Usage
logpath = /var/log/… Surveille un fichier (jokers possibles)
backend = systemd Lit le journal systemd
journalmatch = _SYSTEMD_UNIT=ssh.service Limite à une unité

Un fichier de journal absent empêche la jail de démarrer : le créer ou corriger le chemin.

[recidive]
enabled = true
bantime = 1w
findtime = 1d
maxretry = 3

recidive lit /var/log/fail2ban.log : trois bannissements en un jour valent une semaine de blocage.

Pour une base exposée à un réseau, restreindre l’accès par adresse avec UFW (voir UFW : écrire des règles) plutôt que de compter sur Fail2ban.

Fenêtre de terminal
sudo grep -E "Ban |Unban " /var/log/fail2ban.log | tail -20
sudo fail2ban-client status

Les alertes par e-mail (action_mwl) exigent un serveur de messagerie local configuré.

Symptôme Piste
Failed to initialize any backend Fichier de journal absent ou illisible
No file(s) found for glob logpath incorrect
Aucune ligne reconnue fail2ban-regex ; format JSON, datepattern
Échecs comptés, pas de bannissement maxretry non atteint, ignoreip, ignoreself
Adresse du proxy bannie Configurer trusted_proxies (Caddy) ou le module realip (Nginx)
Jail active, rien n’est bloqué Mauvais port ; sudo nft list ruleset | grep f2b

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Les filtres livrés évoluent entre 1.0.2 et 1.1.0 (prise en charge de sshd-session, filtres supplémentaires) ; les filtres personnalisés ci-dessus sont indépendants de la version.