Sécurisation de son serveur : fail2ban
Cet article a été publié par Benjamin
le 27-12-10 à 21:34 dans la catégorie Auto hébergement
Tags :
- auto-hebergement
- Libre
- Serveur
Comme l'a très bien dit Tancrède dans son article "La sécurité sera-t-elle l'argument anti auto-hébergement ?" :
S'il y a bien une raison qui pourrait s'opposer à l'auto-hébergement, je pense que ce serait celle de la sécurité. C'est probablement le point noir qui empêchera, voire interdira, l'auto-hébergement.
Je suis assez d'accord avec lui et vous invite à lire son article. Aussi, j'ai décidé de partager mon experience en vous montrant une première sécurisation quasi-indispensable pour votre serveur => fail2ban, un logiciel qui scrute les fichiers de logs à la recherche d'actions suspectes et bannit les utilisateurs mal intentionnés grâce aux iptables.
I. Installation
Mon serveur tourne avec une Debian Lenny. Fail2ban est déjà dans les dépôts officiels, un simple apt-get install sera suffisant :
apt-get install fail2ban
II. Configuration
Toute la configuration se passe dans le répertoire /etc/fail2ban/.
Le fichier fail2ban.conf défini le niveau de verbosité de logs ainsi que le fichier de log utilisé. Par défaut, /var/log/fail2ban.log.
Les services à monitorer sont stockés dans le fichier jail.conf. Il est recommandé d'en effectuer une copie nommée jail.local qui sera automatiquement utilisée à la place du fichier d'origine.
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
J'ai modifié l'en-tête de ce fichier jail.local :
[DEFAULT]
# "ignoreip" les adresses IP qui seront ignorées par fail2ban
ignoreip = 127.0.0.1
#3600 secondes = 1 heure
de banissement
bantime = 3600
# Le laps de temps pendant lequel les tentatives vont être possibles
findtime = 600
# Le nombre d'essais maximum avant bannissement
maxretry = 3
Les jails sont les "actions/logs/chaines" à surveiller. Par exemple, le jail [ssh] :
[ssh]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 6
- enabled est là pour activer le jail (ou le désactiver s'il est positionné à false)
- port du service. Si vous avez décidé d'ouvrir ssh sur un autre port, remplacez le mot ssh par le numéro du port
- filter est le nom du filtre utilisé pour ce jail (les filtres se trouvent dans le répertoire filter.d) = sshd.conf dans notre exemple
- logpath est le fichier de log qui doit être analysé
- maxretry est le nombre d'essais autorisés (écrase la valeur positionnée à 3 ci-dessus)
Pour redémarrer :
fail2ban-client reload
Pour voir la conf actuelle :
fail2ban-client status
iptables -L -v
Voici les services que j'ai activé :
root@wario:/etc/fail2ban# fail2ban-client status
Status
|- Number of jail: 8
`- Jail list: apache-w00tw00t, apache-noscript, ssh-ddos, apache-multiport, apache-overflows, ssh, apache, apache-phpmyadmin
Note : Lors du redémarrage de la machine, il se peut que fail2ban ne charge pas toutes les iptables (voir erreurs dans fichier de log fail2ban). Dans ce cas, il faut recharger le fail2ban-client ou bien ajouter une commande sleep dans les jails (expliqué ici).
III. Mes jails perso
apache-wOOtwOOt
Ce jail est là pour bannir les requêtes DFind w00tw00t.
Dans le fichier /etc/fail2ban/jail.local tout en bas, j'ajoute :
#Mes jails
[apache-w00tw00t]
enabled = true
filter = apache-w00tw00t
action = iptables[name=Apache-w00tw00t,port=80,protocol=tcp]
logpath = /var/log/apache2/access*.log
maxretry = 1
On notera que contrairement aux autres règles, celle-ci s'attaque au fichier de log des accès (/var/log/apache2/access*.log).
Voici le fichier de règles /etc/fail2ban/filter.d/apache-w00tw00t.conf
[Definition]
failregex = ^
ignoreregex =
apache-phpmyadmin
Pour bannir les requêtes du style :
[Mon Dec 27 06:22:13 2010] [error] [client 67.212.67.6] File does not exist: /home/www/phpmyadmin
[Mon Dec 27 06:22:13 2010] [error] [client 67.212.67.6] File does not exist: /home/www/phpMyAdmin
[Mon Dec 27 06:22:13 2010] [error] [client 67.212.67.6] File does not exist: /home/www/PHPmyadmin
[Mon Dec 27 06:22:14 2010] [error] [client 67.212.67.6] File does not exist: /home/www/sqldmin
[Mon Dec 27 06:22:14 2010] [error] [client 67.212.67.6] File does not exist: /home/www/admin
[Mon Dec 27 06:22:14 2010] [error] [client 67.212.67.6] File does not exist: /home/www/scripts
Je créé le fichier /etc/fail2ban/filter.d/apache-phpmyadmin.conf
# Fail2Ban configuration file
# Bans bots scanning for non-existing phpMyAdmin installations on your webhost.
[Definition]
docroot = /home/www
badadmin = PMA|phpmyadmin|myadmin|mysql|mysqladmin|sqladmin|mypma|admin|xampp|mysqldb|mydb|db|pmadb|phpmyadmin1|phpmyadmin2|webdb|sqlmanager|sqlweb|websql
failregex = [[]client
ignoreregex =
[apache-phpmyadmin]
enabled = true
port = http,https
filter = apache-phpmyadmin
logpath = /var/log/apache2/error*.log
maxretry = 2
VI. Conclusion
Si vous avez mis en place fail2ban et que vous avez des jails perso supplémentaires à partager, n'hésitez pas à m'en faire part, je les ajouterai à cet article. Merci par avance :)
Commentaires
Fail2ban est vraiment un excellent logiciel, et il suffit d'aller vérifier les logs pour se rendre compte du nombre d'attaques contrés.
Perso, je l'utilise sur mon serveur et j'en suis très content. Il est aussi possible de lui demander d'envoyer un mail à chaque blocage. J'en reçois environ 5 par jour et la grande majorité est dûe à des blocages d'IP ayant tenté de se loguer en SSH avec le login "root". Concernant la provenance des IP bloquées sur mon serveur, la palme d'or revient à la Chine, suivie d'assez près par l'Egypte et la Corée.
Bonjour,
Je n'arrive pas à faire marcher cette regexp. Fail2ban me dit qu'il manque 'host'. Je l'ai ajouté, mais l'expression n'est pas reconnue.
Pourriez-vous m'expliquer comment on passe de :
Mon Dec 27 06:22:14 2010 error client 67.212.67.6 File does not exist: /home/www/scripts
à :
[[]client []] File does not exist: %(docroot)s/(?:%(badadmin)s)
(notamment ce que signifient les crochets droits []).
Merci.
Bonjour, pour la regex, faites attention en cas de copier/coller à ce que tout se remette correctement dans votre fichier (je pense notamment au "=" après le badadmin). Cette regex (que j'ai trouvé sur internet) fonctionne bien chez moi.
Bonsoir,
Je n'ai pas de problème de syntaxe. L'expression est évaluée mais ne trouve pas de correspondance dans mes logs.
Cette syntaxe avec double crochet me perturbe. Je ne la comprends pas. Je continue mes recherches sur Internet.
Salut à tous
J'ai été un utilisateur satisfait de fail2ban pendant quelques années, cependant le projet semble dormant/abandonné.
Une solution un poil différente, plus bas niveau, plus complexe à mettre en place mais plus efficace, est l'utilisation du module recent de iptables.
Ce module permet de bannir une IP que demanderait trop souvent l'établissement d'une connexion (SSH ou autre) durant un laps de temps donné. Notez qu'il ne s'agit pas là de s'occuper de échec de connexion mais bien de toutes les tentatives de connexions.
Une exemple de l'utilisation du module recent.
J'utilise depuis quelque temps cette solution couplée à une liste blanche pour me prévenir d'une erreur.
L'utilisation de iptables/recent me semble plus élégante et plus efficace au niveau ressource que faill2ban.
Bien évidement pour ce qui est des attaques sur le serveur http fail2ban reste une solution plus adapté.
Merci pour ton article
k
Je viens de mettre en place fail2ban, simple et efficace, rien à redire....
Je l'ai configuré pour m'envoyer un email à chaque ban... Problème, il m'envoie aussi un email quand le service redémarre. Ça tient de la broutille mais je n'ai pas trouvé comment lui dire de ne pas m'envoyer d'email lorsque le service redémare.
Je ne sais pas si le fonctionnement de fail2ban a changé depuis 2010 mais aujourd'hui (2014), il a fallut que j'adapte un peu sinon ça ne marche pas (ou presque pas) :
badadmin = (?i)PMA|phpmyadmin|myadmin|mysql|mysqladmin|sqladmin|mypma|admin|xampp|mysqldb|mydb|db|pmadb|phpmyadmin1|phpmyadmin2|webdb|sqlmanager|sqlweb|websql|scripts
failregex = ^.*[client <HOST>] File does not exist: %(docroot)s/(?:%(badadmin)s)
la regexp est case sensitive par défaut, ce qui fait qu'avec la liste badadmin les deux lignes
Mon Dec 27 06:22:13 2010 error client 67.212.67.6 File does not exist: /home/www/phpMyAdmin
Mon Dec 27 06:22:13 2010 error client 67.212.67.6 File does not exist: /home/www/PHPmyadmin
ne sont pas détectées. Il faut ajouter au début :
(?i)
pour que la recherche soit case insensitive.
Ensuite aujourd'hui (je ne sais pas en 2010), il faut OBLIGATOIREMENT que la regexp inclut le tag <HOST> (http://www.fail2ban.org/wiki/index....):
In every line of failregex, the part that matches the host name or IP address must be wrapped in a (?P<host> ... ) sandwich. As a convenience, you can use the predefined entity <HOST> in your regexes. <HOST> is an alias for (?:::f{4,6}:)?(?P<host>\S+), which matches either a hostname or an IPv4 address (possibly embedded in an IPv6 address).
Ensuite penser à tester avec un faux fichier de log :
fail2ban-regex /etc/fail2ban/exemple_log_phpmyadmin.log /etc/fail2ban/filter.d/apache-phpmyadmin.conf