Augmenter (un peu) la sécurité de WordPress avec Fail2ban
Le trafic du blog augmente. Rançon de ce succès, j’ai eu droit à quelques tentatives de brute-force sur la page d’administration de WordPress. Et si j’utilise Fail2ban sur le serveur, je me suis donc rendu compte que je ne lui avais pas donné toute l’attention qu’il mérite, et qu’on peut s’en servir pour protéger WordPress. Plusieurs méthodes, dont une que j’aime un peu plus.
En effet, même si la tentative pour accéder à l’administration échoue, comme le site répond normalement d’un point de vue HTTP, les requêtes sont enregistrées dans le log access comme n’importe quelle requête. Il faut donc dire à fail2ban d’agir différemment.
Pour ceux qui ne le sauraient pas, c’est un logiciel qui surveille les fichiers journaux de vos applications et prend des décisions en fonction de la situation. Typiquement, par exemple du côté du serveur SSH, si une même adresse est repérée trop de fois dans un laps de temps très court, et tout particulièrement sur le compte root, fail2ban va ajouter l’adresse IP aux règles du pare-feu du noyau Linux pour bannir le malandrin.
Pour installer fail2ban, sous Debian ça tient à une seule ligne :
1 |
apt-get install fail2ban |
Il est déjà actif sur certains critères par défaut : SSH, Apache, serveurs FTP, mais il va nous falloir une nouvelle règle spécifique au login WordPress. Histoire de ne pas mélanger les règles, ouvrez le fichier /etc/fail2ban/jail.conf, cherchez la section HTTP servers, et à la fin de celle-ci, ajoutez les lignes suivantes :
1 2 3 4 5 6 |
[apache-wp-login] enabled = true port = http,https filter = apache-wp-login logpath = /var/log/apache2/access.log maxretry = 6 |
Adaptez le chemin du fichier de log à votre situation. Maintenant qu’on a le cas et le fichier à sniffer, il nous reste le filtre. On l’a appelé apache-wp-login, on crée donc un fichier /etc/fail2ban/filter.d/apache-wp-login.conf, et on y met les lignes suivantes :
1 2 3 |
[Definition] failregex = ^<HOST> -.*POST /wp-login.php HTTP.* ignoreregex = |
Il suffit ensuite de redémarrer fail2ban, et de laisser la magie opérer :
1 |
service fail2ban restart |
Bizarrement, pendant plusieurs jours après avoir mis la règle en place, j’ai eu la paix. Rageant. Mais un bon appât permet toujours d’attraper quelque chose, et finalement, j’ai vu apparaître des lignes intéressantes dans le fichier /var/log/fail2ban.log :
1 2 3 4 5 6 7 8 9 10 11 12 |
2015-01-26 01:34:55,814 fail2ban.actions: WARNING [apache-wp-login] Ban 178.32.129.31 2015-01-26 01:44:56,455 fail2ban.actions: WARNING [apache-wp-login] Unban 178.32.129.31 2015-01-26 04:46:16,637 fail2ban.actions: WARNING [apache-wp-login] Ban 159.8.8.178 2015-01-26 04:56:17,261 fail2ban.actions: WARNING [apache-wp-login] Unban 159.8.8.178 2015-01-26 06:04:26,432 fail2ban.actions: WARNING [apache-wp-login] Ban 173.198.228.112 2015-01-26 06:14:27,111 fail2ban.actions: WARNING [apache-wp-login] Unban 173.198.228.112 2015-01-26 10:55:54,515 fail2ban.actions: WARNING [apache-wp-login] Ban 37.9.169.19 2015-01-26 11:05:55,156 fail2ban.actions: WARNING [apache-wp-login] Unban 37.9.169.19 2015-01-26 20:36:13,243 fail2ban.actions: WARNING [apache-wp-login] Ban 92.63.133.65 2015-01-26 20:46:13,874 fail2ban.actions: WARNING [apache-wp-login] Unban 92.63.133.65 2015-01-26 20:47:19,947 fail2ban.actions: WARNING [apache-wp-login] Ban 5.231.220.46 2015-01-26 20:57:20,574 fail2ban.actions: WARNING [apache-wp-login] Unban 5.231.220.46 |
Par contre, l’adresse IP n’est bannie que pendant dix minutes. C’est une mesure de sécurité : déjà, normalement dix minutes suffisent aux robots de login pour laisser tomber s’ils n’ont plus de réponse. Mais surtout si jamais vous vous faites attraper, parce que vous ratez votre coup, vous n’avez qu’à attendre dix minutes pour recommencer.
Si vous souhaitez malgré tout augmenter la durée, il faut retourner dans le fichier /etc/fail2ban/jail.conf, dans la section qu’on a ajouté plus haut, et ajouter la ligne suivante :
1 |
bantime = 3600 |
Redémarrez une fois de plus fail2ban pour que la nouvelle durée soit prise en compte. Et c’est à peu près tout.
Une autre méthode est possible, toujours avec fail2ban. Je ne la chéris pas trop puisqu’elle fait appel à une extension, et que ça peut impacter les performances. Je n’ai pas besoin de détailler plus, tout est décrit dans cet article très bien fait.
Il y a beaucoup de choses à faire pour sécuriser une instance WordPress, que ce soit les logiciels utilisés pour la servir, que l’application elle-même. Je n’ai pas encore poussé le concept des fonctions « custom », qui permettent de redéfinir le comportement de certains éléments de l’application, dont font partie la page de connexion.
Merci !
Salut, pour moi le regex qui marche est .*POST /wp-login.php HTTP.*
Pour avoir une vue rapide des ban du jour : egrep $(date +%m »-« +%d) /var/log/fail2ban.log | grep Ban |cut -d » » -f7 | sort | uniq -c | mail -s « [« $(hostname -f ) »]Ban du jour » user@domail.com Avec une cron qui se lance tout les soirs a 23h59 Pour le mois : #!/bin/bash rm ~/stat_month.txt egrep $(date +%m) /var/log/fail2ban.* | grep Ban |cut -d » » -f2-3,7 | sort >> ~/stat_month.txt cat ~/stat_month.txt | cut -d » » -f3 | sort | uniq -c | mail -s « [« $(hostname -f ) »] Ban du mois » user@domain La cron est plus velue : 59 23 28-31… Lire la suite »
Excellent, ça m’a bien servi pour WordPress !
Merci pour ce partage, c’est encore d’actualité en 2019 😉
J’ai juste modifié le chemin des logs par celui-ci pour chercher dans tous les sites hébergés (sous i-mscp) :
logpath = /var/log/apache2/*.*/access.log
Renseigner la ligne ignoreip avant de modifier quoi que ce soit pour ne pas se faire bloquer en testant :
ignoreip = 127.0.0.1/8 votreIP votreIP2 votreIP3
puis en profiter pour passer le bantime a 360000 (4 jours environ) pour calmer les plus virulents 🙂
Ne pas oublier de redémarrer fail2ban avec /etc/init.d/fail2ban restart