Par défaut, Drupal permet de "bannir" des adresses IP manuellement, via la console d'administration.
Ceci est une première étape, mais peut vite devenir ingérable sur un site fréquenté. De plus, les requêtes http vont quand même arriver jusqu'au CMS, puisque c'est lui qui gère ces exclusions.
La solution dans ce cas est de coupler les logs Drupal avec fail2ban, qui s'occupe de scruter différents fichiers logs et de repérer, via des expressions régulières, des motifs qui permettront de bannir des adresses IP au niveau systèmes, via des règles iptables.
Pré-requis
Pour que fail2ban fonctionne avec Drupal, il faut activer le module syslog, et le paramétrer pour qu'il envoie ses logs dans un fichier séparé (voir à ce sujet http://www.vincentliefooghe.net/content/drupal-activer-les-traces-en-sy…).
Installation et paramétrage de fail2ban
Sur une distribution debian-like, simplement :
sudo apt-get install fail2ban
Les fichiers de configuration se trouvent dans /etc/fail2ban :
- fail2ban.conf : fichier de configuration assez général, avec le fichier de logs de fail2ban, le niveau de logs et le socket unix
- jail.conf : définition des "jails", c'est à dire les paramètres et les actions par défaut. Il est fortement recommandé d'en faire une copie dans un fichier jail.local pour éviter l'écrasement lors des mises à jour
- filter.d : répertoire dans lequel se trouvent les définitions des filtres (regex)
- action.d : répertoire dans lequel se trouvent les définitions des actions.
Dans le fichier jail.local, je vous recommande de renseigner la ligne
ignoreip = 127.0.0.1/8
et d'ajouter les adresses IP de vos PC clients ou serveurs, ce qui peut vous éviter un "auto-bannissement" en cas de manipulations douteuses sur le ssh, des accès à des scripts php, etc.
Paramétrage propre à Drupal
Pour bannier des adresses IP qui tenteraient des connexions, on ajoute un fichier de définition de règle dans le répertoire filter.d. Par exemple, drupal-user.conf, qui va contenir :
# filter to ban IP for Login attempt [Definition] failregex = \|user\|<HOST>\|.*\|Login attempt failed (.+)\.$ #failregex = \|user\|<HOST>\|.*spambot.Failed (.+)\. ignoreregex =
Le filtre recherche les occurences de "Login attempt failed". La ligne est formatée avec *|user|adresse IP|*. Par exemple (cas réel) :
Sep 24 10:03:12 vps35701 drupal: http://www.vincentliefooghe.net|1411545792|user|89.66.70.109|http://www.vincentliefooghe.net/?q=user/login|http://www.vincentliefooghe.net/?q=user/login|0||Login attempt failed for Marcferozi.
Puis dans le fichier jail.local, on ajoute une nouvelle section :
# # Drupal # [drupal-user] enabled = true port = http,https protocol = tcp filter = drupal-user logpath = /var/log/drupal.log maxretry = 3 # 1 hour findtime = 3600 # 20 hours bantime = 72000
On déclare donc à fail2ban qu'il doit utiliser le filtre drupal-user, sur le fichier de logs /var/log/drupal.log. Dans celui-ci, il cherche pendant une heure maximum 3 tentatives de connexions.
Si fail2ban détecte une "attaque", il le signale dans ses logs :
2014-09-23 00:41:56,025 fail2ban.actions: WARNING [drupal-user] Ban 89.66.70.109
On peut également voir les adresses IP bannies via iptables -L :
Chain INPUT (policy ACCEPT) target prot opt source destination fail2ban-drupal-user tcp -- anywhere anywhere multiport dports http,https fail2ban-ssh-ddos tcp -- anywhere anywhere multiport dports ssh fail2ban-ssh tcp -- anywhere anywhere multiport dports ssh ACCEPT all -- was59-4-88-175-36-21.fbx.proxad.net anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain fail2ban-drupal-user (1 references) target prot opt source destination DROP all -- qqa.1113460302.com anywhere DROP all -- seo7.heilink.com anywhere RETURN all -- anywhere anywhere
On peut également ajouter d'autres règles, si l'on a mis en place des modules de type honeypot ou botcha, pour bannier les spammeurs.
Tester un nouveau filtre
Il est possible de tester un filtre avec la commande fail2ban-regex, suivi du fichier à analyser et du nom du filtre
fail2ban-regex /var/log/apache2/drupal_access.log drupal-user.conf
Ceci permet par exemple de créer un fichier de test comprenant des vrais positifs