Fail2ban

fail2ban-logo

Fail2ban n’est pas la panacée mais il permet de limiter bon nombre de problèmes. Son travail est de vérifier les logs et de bloquer les IP qui tentent des attaques par force brute. Ce type d’attaque est d’une simplicité enfantine, ce qui en fait une attaque privilégié par tout les petits geek du dimanche…
Le site avec toute la documentation se trouve à http://www.fail2ban.org

Installation

L’installation se fait via aptitude (à adapter suivant votre distribution)

aptitude install fail2ban

Pour info les durées sont données en seconde, donc 600s = 10minutes, 3600s = 1heure, 86400s = 1 journée, 604800s = 1semaine.

Configuration

Deux fichiers principaux permettent de configurer fail2ban : /etc/fail2ban/jail.conf et les règles se trouve dans /etc/fail2ban/filter.d

Dans jail.conf des bloques définissent les services à surveiller, les chemins et les durées de blocage.
Le bloque DEFAULT permet de définir les paramètres par défaut (logique)

[DEFAULT]
ignoreip = 127.0.0.1 8.8.8.8
findtime = 3600
bantime = 86400

Les paramètres de base sont :

  • ignoreip : permet de ne pas filtrer, ni emprisonner ces IP, il est possible de noté des classes d’IP en format CIDR (192.168.1.0/16) par exemple. L’espace est le séparateur.
  • findtime : intervalle de recherche des occurrences donc le temps où l’on cumule les erreurs. (par exemple 3 erreurs en 1h de temps, cela correspond à 1h et 3 erreurs au paramètre maxretry)
  • bantime : temps de bannissement (ici 1h), il est possible de mettre -1 cela correspond à un bannissement à vie.

Les paramètres destemail, sendername, mta …permettent de recevoir des alertes sur un mail d’administration.
Changer action = %(action_)s en action = %(action_mw)s
Attention si votre serveur est en ligne en permanence sur internet, vous allez avoir un paquet de mails.

Ensuite il faut configurer les services à surveiller, ici nous allons prendre comme exemple SSH

[ssh]
enabled  = true
port     = 22
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 6
  • enable : active ou désactive la surveillance de ce service
  • port : port du service (ou le nom du service s’il est dans /etc/services)
  • filter : le filtre à appliquer (voir plus bas)
  • logpath : les logs qui permettent de vérifier les connections
  • maxretry : nombre d’échec avant bannissement.

Attention : il faut bien réfléchir au bantime, au maxretry et findtime car si ce n’est pas bien paramétrer un utilisateur ne sera jamais bloqué.

Les règles

Les règles sont dans /etc/fail2ban/filter.d voici la liste par défaut.

  • 3proxy.conf
  • asterisk.conf
  • exim.conf
  • perdition.conf
  • roundcube-auth.conf
  • uwimap-auth.conf
  • apache-auth.conf
  • common.conf
  • exim-spam.conf
  • php-url-fopen.conf
  • selinux-common.conf
  • vsftpd.conf
  • apache-badbots.conf
  • courierlogin.conf
  • gssftpd.conf
  • postfix.conf
  • selinux-ssh.conf
  • webmin-auth.conf
  • apache-common.conf
  • couriersmtp.conf
  • lighttpd-auth.conf
  • postfix-sasl.conf
  • sieve.conf
  • wuftpd.conf
  • apache-nohome.conf
  • cyrus-imap.conf
  • mysqld-auth.conf
  • proftpd.conf
  • sogo-auth.conf
  • xinetd-fail.conf
  • apache-noscript.conf
  • dovecot.conf
  • named-refused.conf
  • pure-ftpd.conf
  • sshd.conf
  • apache-overflows.conf
  • dropbear.conf
  • nginx-http-auth.conf
  • qmail.conf
  • sshd-ddos.conf
  • assp.conf
  • exim-common.conf
  • pam-generic.conf
  • recidive.conf
  • suhosin.conf

Comme vous pouvez le voir, il y a déjà de quoi faire et il suffit de s’inspirer de ces règles pour créer les siennes.

Voici le fichier de règle pour ssh (n’aillez pas peur …)

[INCLUDES]
before = common.conf

[Definition]

_daemon = sshd
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
^%(__prefix_line)sFailed \S+ for .*? from <HOST>(?: port \d*)?(?: ssh\d*)?(: (ruser .*|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".*", client host ".*")?))?\s*$
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$
^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
ignoreregex =

Ce sont de simples expressions régulières 🙂

exemple de règle pour wordpress

Dans /etc/fail2ban/filter.d créer un fichier du style apache-login-wordpress

[Definition]
failregex = ^<HOST> -.*POST /wp-login.php HTTP.*
ignoreregex =

Puis dans /etc/fail2ban/jail.conf dans la rubrique HTTP servers (c’est mieux si cela est un peu organiser) entrez ceci :

[apache-login-wordpress]
enable = true
port = http, https
filter ) apache-login-wordpress
logpath = /var/log/apache2/nomdevotrevhost.log
/var/log/apache2/nomdevotrevhost2.log
maxretry = 6

Et on relance fail2ban

# service fail2ban restart

Vérifier les IP bloqué

Une commande est fournie pour cela (en root ou via sudo)

fail2ban-client status

fail2ban utilise iptables pour bloquer les IP, il est donc possible de vérifier en regardant la liste iptables :

iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
fail2ban-ssh  tcp  --  anywhere             anywhere             multiport dports ssh

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain fail2ban-ssh (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

Vous pouvez voir les chaînes standard d’iptables : INPUT FORWARD et OUTPUT (pour les nat c’est autre chose et pas pertinent ici) et la chaîne fail2ban-ssh qui correspond à la mise en place de la surveillance de ssh par fail2ban.

Débloquer une IP

Il arrive que des personnes soient bloqués par fail2ban, et qui sont légitimes. Pour les débloquer il faut connaître la règle et la ligne à débloqué.

Ceci est un exemple avec des règles pour Zimbra, mais c’est valable pour n’importe quelle règle.

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
fail2ban-Zimbra-recipient  tcp  --  anywhere             anywhere
fail2ban-Zimbra-account  tcp  --  anywhere             anywhere
fail2ban-Postfix  tcp  --  anywhere             anywhere             multiport dports smtp
fail2ban-ssh  tcp  --  anywhere             anywhere             multiport dports 22

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain fail2ban-Postfix (1 references)
target     prot opt source               destination
REJECT     all  --  xxx.xxx.xxx.xxx      anywhere             reject-with icmp-port-unreachable
REJECT     all  --  xxx.xxx.xxx.xxx      anywhere             reject-with icmp-port-unreachable
REJECT     all  --  xxx.xxx.xxx.xxx      anywhere             reject-with icmp-port-unreachable
REJECT     all  --  111.222.111.222      anywhere             reject-with icmp-port-unreachable
REJECT     all  --  xxx.xxx.xxx.xxx      anywhere             reject-with icmp-port-unreachable
REJECT     all  --  xxx.xxx.xxx.xxx      anywhere             reject-with icmp-port-unreachable
REJECT     all  --  xxx.xxx.xxx.xxx      anywhere             reject-with icmp-port-unreachable
REJECT     all  --  xxx.xxx.xxx.xxx      anywhere             reject-with icmp-port-unreachable
REJECT     all  --  xxx.xxx.xxx.xxx      anywhere             reject-with icmp-port-unreachable
REJECT     all  --  xxx.xxx.xxx.xxx      anywhere             reject-with icmp-port-unreachable
RETURN     all  --  anywhere             anywhere

Chain fail2ban-Zimbra-account (1 references)
target     prot opt source               destination
REJECT     all  --  xxx.xxx.xxx.xxx  anywhere             reject-with icmp-port-unreachable
RETURN     all  --  anywhere             anywhere

Chain fail2ban-Zimbra-recipient (1 references)
target     prot opt source               destination
REJECT     all  --  xxx.xxx.xxx.xxx  anywhere             reject-with icmp-port-unreachable
REJECT     all  --  xxx.xxx.xxx.xxx  anywhere             reject-with icmp-port-unreachable
RETURN     all  --  anywhere             anywhere

Chain fail2ban-ssh (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

Les xxx.xxx.xxx.xxx sont des IPs. Admettons que l’on veuille débloquer la ligne 111.222.111.222 de la chaîne fail2ban-Postfix la commande est (en root ou sudo ) :

iptables -D fail2ban-Postfix 4

se qui veut dire « supprimer la règle numéro 4 dans la chaîne fail2ban-Postfix

Autre manière d’unbanner une ip (dans cet exemple pour ssh)

Il faut passer via le client de fail2ban:

fail2ban-client -i

on vérifie pour le service ssh

status sshd

Là vous allez avoir la liste des IP bloqué pour la supprimer il suffit de faire :

set sshd unbanip xxx.xxx.xxx.xxx

ou xxx.xxx.xxx.xxx est l’ip bannie

puis exit .

Interface graphique

Pour information il y a un projet d’interface graphique de gestion de fail2ban, mais je ne l’ai pas testé.

https://github.com/Sean-Der/fail2web


Fatal error: Uncaught exception 'wfWAFStorageFileException' with message 'Unable to verify temporary file contents for atomic writing.' in /var/www/alternc/c/cinfo/www/courbeil.com/documentation/wp-content/plugins/wordfence/vendor/wordfence/wf-waf/src/lib/storage/file.php:51 Stack trace: #0 /var/www/alternc/c/cinfo/www/courbeil.com/documentation/wp-content/plugins/wordfence/vendor/wordfence/wf-waf/src/lib/storage/file.php(658): wfWAFStorageFile::atomicFilePutContents('/var/www/altern...', '<?php exit('Acc...') #1 [internal function]: wfWAFStorageFile->saveConfig('livewaf') #2 {main} thrown in /var/www/alternc/c/cinfo/www/courbeil.com/documentation/wp-content/plugins/wordfence/vendor/wordfence/wf-waf/src/lib/storage/file.php on line 51