Créer un filtre Fail2ban

Classé dans : Linux, Sécurité | 0

Fail2ban est un logiciel pour Linux qui permet de bannir (ban) automatiquement des adresses ip en fonction de leur activité dans différents fichiers de log.

Par exemple Fail2ban par défaut scan le fichier /var/log/auth.log pour détecter les erreurs de connexion SSH. Si plusieurs tentative (3 par défaut) sont issues de la même adresse IP cette adresse est alors bannie. Plus aucun trafic ne sera autorisé sur le serveur depuis cette adresse.

Dans l’exemple ci-dessous le besoin est le suivant dans les logs du serveur Apache j’ai constaté des tentatives d’accès sur des urls du type wp-login.php. Cela indique que des robots tentent des intrusions en essayant les urls connues de logiciels très répandus, comme WordPress.

La première étape consiste à installer fail2ban et iptables : apt-get install fail2ban iptables

Il faut ensuite commencer par créer le filtre qui va permettre de trouve les lignes dans le fichier de log qui nous intéressent (wp-login.php).

le filtre doit être créer dans /etc/fail2ban/filter.d, le nom du fichier reste arbitraire,mais doit se terminer par .conf

dans mon exemple le fichier sera : bad_urls.conf , voici le contenu du fichier

[INCLUDES]
before = common.conf

[Definition]
failregex = ^<HOST> - - \[.*] "GET /(wp-login.php|spip.php) HTTP\/1.1" 404
ignoreregex =  

La ligne la plus importante est failregex.... elle définit l’expression régulière qui va permettre de trouver les lignes avec certains critères. L’objet de l’article n’étant pas d’expliquer en détail les REGEX, je vais juste survoler la chose :

^<HOST> indique que ligne de log commence par l’adresse IP (celle qui sera bannie)
- - \[.*] indique un nombre de caractères variables
"GET /(wp-login.php|spip.php) HTTP\/1.1" 404 détail le reste de la ligne, et on trouve ici les urls recherchées wp-login.php et spip.php

Voici une ligne du fichier de log pour bien comprendre le lien entre la REGEX et le format du fichier de log

52.114.77.236 - - [21/Jun/2023:13:52:01 +0200] "GET /wp-login.php HTTP/1.1" 404 5025 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) SkypeUriPreview Preview/0.5 skype-url-preview@microsoft.com"

Tout ce qui se trouve après 404 est ignoré et inutile dans notre exemple. On voit bien en premier lien une adresse IP, puis - - [xxxx] pour la date, et enfin « GET... » tout ceci correspond à la REGEX et sera donc matché par Fail2ban.

Pour tester le filtre il existe la commande : fail2ban-regex fichier_log fichier_filter

par exemple : fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/bad_urls.conf

Running tests
=============
Use   failregex filter file : esc_url_filter, basedir: /etc/fail2ban
Use      datepattern : ^%d/%m/%Y:%H:%M:%S : ^Day/Month/Year:24hour:Minute:Second
Use         log file : /var/log/apache2/access.log
Use         encoding : UTF-8
Results
=======
Failregex: 5 total
|-  #) [# of hits] regular expression
|   1) [5] ^<HOST> - - \[.*] "GET /(wp-login.php|spip.php) HTTP\/1.1" 404
`-
Ignoreregex: 0 total
Date template hits:
Lines: 583 lines, 0 ignored, 5 matched, 578 missed
[processed in 0.01 sec]

L’information importante ici est ‘5 matched‘ qui indique que 5 lignes correspondent à notre filtre (REGEX) dans le fichier de log.

Pour activer le filtre il faut maintenant le déclarer dans la config générale de Fail2ban dans le fichier /etc/fail2ban/jail.conf. Pour cela il suffit d’éditer ce fichier et d’ajouter le bloc suivant

[badurls]
enabled = true
port = http,https
logpath = /var/log/apache2/access.log
bantime = 1h
maxretry = 1
filter = bad_urls

enabled = true indique que le filtre est actif
port = http,https indique que c’est les ports http (80) et https (443) qui seront bloqués
logpath = /var/log/apache2/acces.log fichier de log à scanner
bantime = 1h les adresses ip seront bannies pendant 1 heure, testez avec de petites valeurs au départ en cas de fausse manip vous ne serez pas bloqué trop longtemp. Car si un filtre est mal défini fail2ban peut avoir des faux positifs et bannir plus large que prévu, y compris l’adresse IP de votre propre poste 🙂
maxretry = 1 nombre de ‘chances’, 1 indique qu’une seule ligne dans le log suffit pour bannir l’IP. Pour le ssh par exemple on a souvent maxretry = 3, ce qui autorise 3 erreur de connexion avant de bannir l’IP
filter = bad_urls nom de notre filtre (sans le .conf)

Tout est maintenant ok pour activer notre filtre et bannir toutes les IP qui tentent d’accéder à wp-login.php ou spip.php. Il suffit pour cela de relancer fail2ban : service fail2ban restart

pour suivre ce qui se passe : tail -f /var/log/fail2ban.log

Quand un accés matche notre filtre dans fail2ban.log vous verrez ces lignes

....
2023-06-21 14:05:45,165 fail2ban.filter  [96713]: INFO    [bad_urls] Found 172.225.160.197 - 2023-06-21 14:05:40
2023-06-21 14:05:45,519 fail2ban.actions [96713]: NOTICE  [bad_urls] Ban 172.225.160.197

Il est très facile de voir la liste des IP bannies avec : iptables -L -n

Chain f2b-bad_urls (1 references)
target     prot opt source               destination
REJECT     all  --  104.28.147.115       0.0.0.0/0            reject-with icmp-port-unreachable
REJECT     all  --  104.28.42.25         0.0.0.0/0            reject-with icmp-port-unreachable
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

On voit ci dessus que 2 adresses sont actuellement bannies !