Fail2ban
Qu'est-ce que Fail2ban?
Fail2ban lit des fichiers de log comme /var/log/pwdfail ou /var/log/apache/error_log et bannit les adresses IP qui ont obtenu un trop grand nombre d'échecs lors de l'authentification. Il met à jour les règles du pare-feu pour rejeter cette adresse IP. Ces règles peuvent êtres défines par l'utilisateur. Fail2ban peut lire plusieurs fichiers de log comme ceux de sshd ou du serveur Apache.
Installation
apt-get install fail2ban
Par défaut, le port 22 (ssh) est surveillé, vous pouvez vérifier que les règles ipatbles ont bien prises en compte fail2ban:
# iptables -S | grep fail2ban
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh -A fail2ban-ssh -j RETURN
(Nouveau 2017) si cela ne retourne rien , faire :
sudo iptables -S | grep f2b
qui retourne bien :
-A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd -A f2b-sshd -j RETURN
Configuration
Deux fichiers:
fail2ban.conf
Rien à faire dans ce fichier, vous pouvez laisser les options par défaut:
/etc/fail2ban/fail2ban.conf
loglevel = 3 logtarget = /var/log/fail2ban.log socket = /var/run/fail2ban/fail2ban.sock
jail.conf
Ce fichier est beaucoup plus intéressant, il contient tous les services à monitorer, et vous allez le découvrir, fail2ban ne se limite pas à SSH...
/etc/fail2ban/jail.conf
Vérifiez l'adresse d'envoi des mails d'avertissement:
[DEFAULT] destemail = root@localhost
Erreur commune pour l'envoi des mail d'alertes
N'oubliez pas de modifier la variable action = %(action_)s
Pour envoyer un mail contenant le whois, placez la variable sur :
action = %(action_mw)s
Pour envoyer un mail avec le whois ET les logs, placez la variable sur :
action = %(action_mwl)s
Pour activer la surveillance d'un service, il suffit de placer la variable "enabled" à "true"
Par défaut la protection du service SSH est activée, pas les autres.
Si votre ssh n'écoute pas sur le port 22, pensez à le changer... (port = N° de port).
Rappelez vous également que le loglevel de SSHD doit absolument être positionné sur DEBUG (il arrive qu'on le passe en INFO car trop verbose lorsqu'une surveillance, par exemple monit, est placée dessus), sans quoi, Fail2ban ne bloquera rien concernant SSH.
[ssh] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 6
D'autres services, à activer en fonction de vos besoins:
[xinetd-fail] enabled = true filter = xinetd-fail port = all banaction = iptables-multiport-log logpath = /var/log/daemon.log maxretry = 2
[pam-generic] enabled = true filter = pam-generic port = all banaction = iptables-allports port = anyport logpath = /var/log/auth.log maxretry = 6
[ssh-ddos] enabled = true port = ssh filter = sshd-ddos logpath = /var/log/auth.log maxretry = 6
[apache] enabled = true port = http,https filter = apache-auth logpath = /var/log/apache*/*error.log maxretry = 6
[apache-multiport] enabled = true port = http,https filter = apache-auth logpath = /var/log/apache*/*error.log maxretry = 6
[apache-noscript] enabled = true port = http,https filter = apache-noscript logpath = /var/log/apache*/*error.log maxretry = 6
[apache-overflows] enabled = true port = http,https filter = apache-overflows logpath = /var/log/apache*/*error.log maxretry = 2
[postfix] enabled = true port = smtp,ssmtp filter = postfix logpath = /var/log/mail.log
[sasl] enabled = true port = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s filter = sasl logpath = /var/log/mail.log
n'oubliez pas de redémarrer fail2ban :
# service fail2ban restart
jail.local
Le fichier jail.local vous permet de mettre vos règles personnelles. Voici quelques exemples:
[pure-ftpd] enabled = true port = ftp,ftp-data,ftps,ftps-data filter = pure-ftpd logpath = /var/log/messages maxretry = 3 [dovecot-pop3imap] enabled = true filter = dovecot-pop3imap action = iptables-multiport[name=dovecot-pop3imap, port="pop3,pop3s,imap,imaps", protocol=tcp] logpath = /var/log/mail.log maxretry = 5 [webmin-auth] enabled = true port = https,10000 filter = webmin-auth logpath = /var/log/auth.log maxretry = 3 # Plugin ''roundcube-fail2ban-plugin'' à installer # [roundcube] enabled = true port = http,https filter = roundcube action = iptables-multiport[name=roundcube, port="http,https"] sendmail-whois[name=roundcube, dest=root@localhost, sender=fail2ban@localhost] logpath = /var/www/path/logs/userlogins # Plugin ''squirrel_logger'' à ajouter à squirrelmail [squirrelmail] enabled = true port = http,https filter = squirrelmail logpath = /var/www/path/squirrelmail_access_log bantime = 6000 maxretry = 4 # Règle anti-Kevin... [apache-admin] enabled = true port = http filter = apache-admin logpath = /var/log/apache*/error*.log maxretry = 6 # Règle anti-boulets... [apache-404] enabled = true port = http filter = apache-404 logpath = /var/log/ispconfig/httpd/*/error* maxretry = 10
Les fichiers de conf qui vont bien:
pure-ftpd.conf déjà inclu dans la configuration de base
dovecot-pop3imap.conf déjà inclu dans la configuration de base
webmin-auth.conf
# Fail2Ban configuration file # # Author: Cyril Jaquier # Rule by : Delvit Guillaume # # $Revision: 728 $ # [Definition] # patern : webmin[15673]: Non-existent login as toto from 86.0.6.217 # webmin[29544]: Invalid login as root from 86.0.6.217 # # Option: failregex # Notes.: regex to match the password failure messages in the logfile. The # host must be matched by a group named "host". The tag "<HOST>" can # be used for standard IP/hostname matching and is only an alias for # (?:::f{4,6}:)?(?P<host>[\w\-.^_]+) # Values: TEXT # failregex = webmin.* Non-existent login as .+ from <HOST>$ webmin.* Invalid login as .+ from <HOST>$ # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
roundcube.conf
[Definition] failregex = FAILED login for .*. from <HOST> ignoreregex =
squirrelmail.conf
# Fail2Ban configuration file # # Author: Bill Landry ((email_protected)) # # $Revision: 510 $ [Definition] # Option: failregex # Notes.: regex to match the password failures messages in the logfile. The # host must be matched by a group named "host". The tag "" can # be used for standard IP/hostname matching and is only an alias for # (?:::f{4,6}:)?(?P\S+) # Values: TEXT # Message d'erreur "Utilisateur inconnu ou mot de passe incorrect" à adapter suivant la langue utilisée par le serveur failregex = \[LOGIN_ERROR\].*from <HOST>: Utilisateur inconnu ou mot de passe incorrect # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT ignoreregex =
apache-admin.conf
# Fail2Ban configuration file # # Author: Cyril Jaquier # # $Revision: 471 $ # [Definition] # Option: failregex # Notes.: regex to match the password failure messages in the logfile. The # host must be matched by a group named "host". The tag "<HOST>" can # be used for standard IP/hostname matching. # Values: TEXT # [client x.x.x.x] File does not exist: /home/www/admin/admin, failregex = [[]client <HOST>[]] File does not exist: .*admin|PMA|mysql # # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
apache-404.conf
# Fail2Ban configuration file # # Author: Cyril Jaquier # # $Revision: 471 $ # [Definition] # Option: failregex # Notes.: regex to match the password failure messages in the logfile. The # host must be matched by a group named "host". The tag "<HOST>" can # be used for standard IP/hostname matching. # Values: TEXT # [client x.x.x.x] File does not exist: /home/www/admin/admin, failregex = [[]client <HOST>[]] File does not exist: .* # # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
Option très intéressante pour les logs multiples
Vous avez la possibilité (si vos logs sont "dispersés") de mettre des chemins "relatifs" - Vous pouvez utiliser les * (étoiles)
Par exemple, vos logs pour chaque site sont dispersés dans des répertoires différents... Vous utiliserez alors le chemin suivant (tous les sous-répertoires dans /var/log/ispconfig/httpd/ seront alors pris en compte)
logpath /var/log/ispconfig/httpd/*/error*
Plugins squirrelmail et rouncube
Plugin roundcube-fail2ban-plugin
Ces plugins utilisent PHP pour écrire les logs, il faudra s'assurer qu'il utilise le bon fuseau horaire : dans le fichier /etc/php5/apache2/php.ini vérifier la variable "date.timezone"
Fail2ban avec mod-evasive
Si vous utilisez mod-evasive, le module de protection contre les attaques Ddos de apache2, vous aurez peut-etre envie d'ajouter un filtre à fail2ban:
# $EDITOR /etc/fail2ban/filter.d/apache-dosevasive.conf
# Fail2Ban configuration file # # Author: Xela # # $Revision: 728 $ # [Definition] # Option: failregex # Notes.: regex to match the Forbidden log entrys in apache error.log # maybe (but not only) provided by mod_evasive # # Values: TEXT # #failregex = ^\[[^\]]*\]\s+\[error\]\s+\[client \] client denied by server configuration:\s failregex = ^\[[^\]]*\]\s+\[error\]\s+\[client <HOST>\] client denied by server configuration:\s # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
Ajoutez ensuite ce bloc à /etc/fail2ban/jail.local (adaptez l'emplacement du fichier log à surveiller en fonction de votre configuration)
[apache-dosevasive] enabled = true filter = apache-dosevasive action = iptables-allports[name=apache-dosevasive] logpath = /var/log/ispconfig/httpd/*/error* #logpath = /var/log/apache*/*error.log bantime = 600 maxretry = 10
Cas particulier de mysql
Si vous souhaitez protéger un serveur mysql dont la base est ouverte sur Internet (ce qui n'est pas conseillé et pas très prudent...), voici comment faire:
Activez les logs de mysql
Dans le fichier /etc/mysql/my.cnf
general_log_file = /var/log/mysql/mysql.log general_log = 1
Patchez le fichier de support de date de fail2ban
Une sauvegarde: cp /usr/share/fail2ban/server/datedetector.py /usr/share/fail2ban/server/datedetector.py.sos
Dans le fichier /usr/share/fail2ban/server/datedetector.py ajoutez ceci (ligne 144)
Attention, les espaces sont des tabulations
# AAMMJJ HH:MM:SS template = DateStrptime() template.setName("YearMonthDay Hour:Minute:Second") template.setRegex("\d{2}\d{2}\d{2} \d{2}:\d{2}:\d{2}") template.setPattern("%y%m%d %H:%M:%S") self.__templates.append(template)
Vous devriez obtenir ceci:
... # <09/16/08@05:03:30> template = DateStrptime() template.setName("<Month/Day/Year@Hour:Minute:Second>") template.setRegex("^<\d{2}/\d{2}/\d{2}@\d{2}:\d{2}:\d{2}>") template.setPattern("<%m/%d/%y@%H:%M:%S>") self.__templates.append(template) # AAMMJJ HH:MM:SS template = DateStrptime() template.setName("YearMonthDay Hour:Minute:Second") template.setRegex("\d{2}\d{2}\d{2} \d{2}:\d{2}:\d{2}") template.setPattern("%y%m%d %H:%M:%S") self.__templates.append(template) finally: self.__lock.release() ...
Configurez fail2ban
$editor /etc/fail2ban/jail.conf
[mysql] enabled = true port = 3306 filter = mysqld logpath = /var/log/mysql/mysql.log maxretry = 3
$editor /etc/fail2ban/filter.d/mysqld.conf
# Fail2Ban configuration file # # Author: Darel # [Definition] failregex = Access denied for user '.*'@'<HOST>'
Test
Testez les règles
L'erreur commune est de se tromper de fichier log... Vérifiez et revérifiez que le fichier donné en "logpath" est le bon. Ensuite testez vos règles avec la commande /usr/bin/fail2ban-regex
# /usr/bin/fail2ban-regex /var/www/path/logs/userlogins /etc/fail2ban/filter.d/roundcube.conf
Exemple de sortie:
Running tests ============= Use regex file : /etc/fail2ban/filter.d/roundcube.conf Use log file : /var/www/path/logs/userlogins Results ======= Failregex |- Regular expressions: | [1] FAILED login for .*. from <HOST> | `- Number of matches: [1] 1 match(es) Ignoreregex |- Regular expressions: | `- Number of matches: Summary ======= Addresses found: [1] 41.xxx.xxx.xxx (Wed Dec 28 15:51:14 2011) Date template hits: 0 hit(s): MONTH Day Hour:Minute:Second 0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second Year 0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second 0 hit(s): Year/Month/Day Hour:Minute:Second 0 hit(s): Day/Month/Year Hour:Minute:Second 0 hit(s): Day/Month/Year Hour:Minute:Second 0 hit(s): Day/MONTH/Year:Hour:Minute:Second 0 hit(s): Month/Day/Year:Hour:Minute:Second 0 hit(s): Year-Month-Day Hour:Minute:Second 2 hit(s): Day-MONTH-Year Hour:Minute:Second[.Millisecond] 0 hit(s): Day-Month-Year Hour:Minute:Second 0 hit(s): TAI64N 0 hit(s): Epoch 0 hit(s): ISO 8601 0 hit(s): Hour:Minute:Second 0 hit(s): <Month/Day/Year@Hour:Minute:Second> Success, the total number of match is 1 However, look at the above section 'Running tests' which could contain important information.
Testez l'état des jails
Avec la commande /usr/bin/fail2ban-client vous pouvez vérifier l'état de vos "jails":
Exemples de sortie:
# /usr/bin/fail2ban-client status
Status |- Number of jail: 18 `- Jail list: dovecot-pop3imap, pure-ftpd, roundcube, apache, ssh, dovecot, apache-overflows, apache-noscript, squirrelmail, apache-dosevasive, apache-admin, pam-generic, postfix, ssh-ddos, webmin-auth, apache-404, sasl, named-refused-tcp
# /usr/bin/fail2ban-client status apache-404
Status for the jail: apache-404 |- filter | |- File list: /var/log/path/error.log /var/log/path2/error.log /var/log/path2/error.log Etc... | |- Currently failed: 5 | `- Total failed: 32 `- action |- Currently banned: 2 | `- IP list: 41.xxx.xxx.xxx 84.xxx.xxx.xxx `- Total banned: 2
Testez en violant une règle
Créez par exemple un répertoire dans votre serveur apache, rendez obligatoire l'identification, puis entrez plusieurs fois de suite un mot de passe erroné. Vous devriez avoir dans vols logs ceci:
tail -f /var/log/fail2ban.log
2011-08-08 12:27:18,730 fail2ban.actions: WARNING [apache] Ban 10.9.11.150
Effectivement, iptables à bloqué votre ip:
iptables -L
Chain fail2ban-apache (1 references) target prot opt source destination DROP all -- 10.9.11.150 anywhere RETURN all -- anywhere anywhere
Au bout de 10 minutes (en fonction de ce que vous aurez précisé dans le configuration), l'IP sera de nouveau "libérée":
2011-08-08 12:37:19,585 fail2ban.actions: WARNING [apache] Unban 10.9.11.150
Erreur au démarrage de fail2ban
Si vous surveillez plusieurs services, il existe un bug gênant sur fail2ban (fail2ban: fails to load iptable rules with multiple jails) - Il existe une solution :
Lorsque vous démarrerez fail2ban, surveillez ses logs, vous devriez avoir ceci:
2011-08-08 16:44:40,564 fail2ban.jail : INFO Jail 'apache-noscript' started 2011-08-08 16:44:40,810 fail2ban.jail : INFO Jail 'pam-generic' started 2011-08-08 16:44:41,051 fail2ban.jail : INFO Jail 'xinetd-fail' started 2011-08-08 16:44:41,269 fail2ban.jail : INFO Jail 'ssh-ddos' started 2011-08-08 16:44:41,506 fail2ban.jail : INFO Jail 'apache-multiport' started 2011-08-08 16:44:41,739 fail2ban.jail : INFO Jail 'apache-overflows' started 2011-08-08 16:44:41,976 fail2ban.jail : INFO Jail 'ssh' started 2011-08-08 16:44:42,206 fail2ban.jail : INFO Jail 'postfix' started 2011-08-08 16:44:42,448 fail2ban.jail : INFO Jail 'sasl' started 2011-08-08 16:44:42,667 fail2ban.jail : INFO Jail 'apache' started
Si vous avez ce genre de message d'erreur:
2011-08-08 12:22:52,286 fail2ban.actions.action: ERROR iptables -N fail2ban-pam-generic iptables -A fail2ban-pam-generic -j RETURN iptables -I INPUT -p tcp -j fail2ban-pam-generic returned 400 2011-08-08 15:06:04,467 fail2ban.actions.action: ERROR iptables -D INPUT -p tcp -m multiport --dports 10122 -j fail2ban-ssh-ddos iptables -F fail2ban-ssh-ddos iptables -X fail2ban-ssh-ddos returned 100 2011-08-08 15:06:10,027 fail2ban.actions.action: ERROR iptables -N fail2ban-apache-overflows iptables -A fail2ban-apache-overflows -j RETURN iptables -I INPUT -p tcp -m multiport --dports http,https -j fail2ban-apache-overflows returned 200 2011-08-08 15:06:10,224 fail2ban.actions.action: ERROR iptables -N fail2ban-postfix iptables -A fail2ban-postfix -j RETURN iptables -I INPUT -p tcp -m multiport --dports smtp,ssmtp -j fail2ban-postfix returned 400 2011-08-08 15:06:10,283 fail2ban.actions.action: ERROR iptables -N fail2ban-sasl iptables -A fail2ban-sasl -j RETURN iptables -I INPUT -p tcp -m multiport --dports smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s -j fail2ban-sasl returned 200 2011-08-08 15:14:26,002 fail2ban.actions.action: ERROR iptables -D INPUT -p tcp -m multiport --dports http,https -j fail2ban-apache-overflows iptables -F fail2ban-apache-overflows iptables -X fail2ban-apache-overflows returned 100 2011-08-08 15:14:28,374 fail2ban.actions.action: ERROR iptables -D INPUT -p tcp -m multiport --dports smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s -j fail2ban-sasl iptables -F fail2ban-sasl iptables -X fail2ban-sasl returned 100 2011-08-08 15:14:45,382 fail2ban.actions.action: ERROR iptables -N fail2ban-apache-noscript iptables -A fail2ban-apache-noscript -j RETURN iptables -I INPUT -p tcp -m multiport --dports http,https -j fail2ban-apache-noscript returned 400
Il existe deux solutions:
1) Modifier le fichier /usr/bin/fail2ban-client
Faite une sauvegarde de auparavant...
Editez le fichier /usr/bin/fail2ban-client et ajoutez une temporisation (time.sleep(0.1)) à cet endroit:
def __processCmd(self, cmd, showRet = True): beautifier = Beautifier() for c in cmd: time.sleep(0.1) beautifier.setInputCmd(c)
Si la temporisation à 0.1 ne suffit pas, mettez 0.2. et redémarrez fail2ban.
2) Installer une version supérieure (Fixed in version fail2ban/0.8.5-2)
Installer la version testing (8.6-3 0) ou celle des backports (8.6-3~bpo60+1)
Fail2ban et ipv6 (EXPERIMENTAL)
Attention, ne fonctionne pas avec fail2ban 0.8.13-1 (et je n'ai pas encore trouvé de patch qui fonctionne).
Vous le savez, l'ipv6 se généralise, lancement officiel le 6 juin 2012 Quid de fail2ban ? Malheureusement, fail2ban ne supporte pas encore l'ipv6. Heureusement, il existe un patch qui permet d'avoir fail2ban activé sur votre ipv6...
Mode d'emploi:
Téléchargez le patch:
wget http://thanatos.trollprod.org/sousites/fail2banv6/fail2ban-ipv6.tar.bz2 --2012-04-14 09:30:31-- http://thanatos.trollprod.org/sousites/fail2banv6/fail2ban-ipv6.tar.bz2 Résolution de thanatos.trollprod.org (thanatos.trollprod.org)... 94.23.14.97, 2001:41d0:2:f61::fed1:fe54 Connexion vers thanatos.trollprod.org (thanatos.trollprod.org)|94.23.14.97|:80...connecté. requête HTTP transmise, en attente de la réponse...200 OK Longueur: 2293 (2,2K) [application/x-bzip] Sauvegarde en : «fail2ban-ipv6.tar.bz2» 100%[=============================================================================================>] 2 293 --.-K/s ds 0,001s 2012-04-14 09:30:31 (2,98 MB/s) - «fail2ban-ipv6.tar.bz2» sauvegardé [2293/2293]
mkdir fail2ban-ipv6 tar xvjf fail2ban-ipv6.tar.bz2 -C fail2ban-ipv6
cp /usr/share/fail2ban/server/filter.py /usr/share/fail2ban/server/filter.py.sos cp /usr/share/fail2ban/server/failregex.py /usr/share/fail2ban/server/failregex.py.sos
Testez les patch:
cd /usr/share/fail2ban/server/
root@nas:/usr/share/fail2ban/server# patch -p0 --dry-run < /root/fail2ban-ipv6/patchfilter.patch patching file filter.py Hunk #1 succeeded at 525 (offset 14 lines). Hunk #2 succeeded at 549 (offset 14 lines). Hunk #3 succeeded at 580 (offset 14 lines). root@nas:/usr/share/fail2ban/server# patch -p0 --dry-run < /root/fail2ban-ipv6/regex.patch patching file failregex.py Hunk #1 succeeded at 47 (offset 3 lines).
Si le résultat est positif (pas d'erreur) lancez les patchs
root@nas:/usr/share/fail2ban/server# patch -p0 < /root/fail2ban-ipv6/patchfilter.patch patching file filter.py Hunk #1 succeeded at 525 (offset 14 lines). Hunk #2 succeeded at 549 (offset 14 lines). Hunk #3 succeeded at 580 (offset 14 lines). root@nas:/usr/share/fail2ban/server# patch -p0 < /root/fail2ban-ipv6/regex.patch patching file failregex.py Hunk #1 succeeded at 47 (offset 3 lines).
Copiez les fichiers nécessaires:
root@nas:/usr/share/fail2ban/server# cp /root/fail2ban-ipv6/ip64tables.sh /usr/bin/ root@nas:/usr/share/fail2ban/server# chmod 755 /usr/bin/ip64tables.sh root@nas:/usr/share/fail2ban/server# cp /root/fail2ban-ipv6/iptables46-multiport.conf /etc/fail2ban/action.d/ root@nas:/usr/share/fail2ban/server# chmod 644 /etc/fail2ban/action.d/iptables46-multiport.conf
Créez le bloc de configuration:
nano /etc/fail2ban/jail.conf
... [ssh-ip6tables] enabled = true filter = sshd logpath = /var/log/auth.log maxretry = 6 action = iptables46-multiport[name=SSH, port=22, protocol=tcp] sendmail-whois[name=SSH, dest=root, sender=fail2ban@mail.com] ...
Redémarrez fail2ban et vérifiez qu'il est actif:
service fail2ban restart Restarting authentication failure monitor: fail2ban. ip6tables -S ... -N fail2ban-SSH -A INPUT -p tcp -m multiport --dports 22 -j fail2ban-SSH -A fail2ban-SSH -j RETURN
Avertissement:
- N'a pas encore été testé
- Ne pas activer la résolution de nom dans les logs
Liens externes
Je vous encourage à lire:
- La page de man de fail2ban
- Le Wiki de fail2ban - Très complet
Lol 8 août 2011 à 09:00 (CDT) Zer00CooL 25 Mars 2020 à 17:00 (CDT)