WordPress & fail2ban : stopper la brute-force « POST /wp-login.php »

Edit : azerttyu, dans son commentaire signale une solution plus propre (bien que celle-ci fonctionne)

WordPress étant très populaire il est (malheureusement) de fait très attaqué.. La principale (hors SPAM sur les commentaires) est faite par brute-force sur la page wp-login.php. Je l’avais déjà remarqué, mais j’ai récement eu des problèmes d’indisponibilités suite à plusieurs attaques venant de multiple adresse IP (l’attaque passant donc de brute-force à DDOS) J’ai donc dû réagir et pour ce faire j’ai configuré fail2ban pour bloquer les IP’s faisant plus de 6 tentatives de connexions sur tous les sites wordpress du serveur.

Configuration de fail2ban

Note : mon installation de fail2ban est existante et fonctionne déjà pour le FTP & le SSH

Créer le fichier /etc/fail2ban/jail.d/apache-wp-login.conf  :

> [apache-wp-login]
> 
> enabled = true
> port    = http,https
> filter  = apache-wp-login
> logpath = /var/log/apache2/un.autre.blog.wordrepp/access.log
>         /var/log/apache2/mercereau.info/access.log
> maxretry = 6

Puis créer la définition de la regex « apache-wp-login » dans le fichier /etc/fail2ban/filter.d/apache-wp-login.conf

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

Pour finir : un restart du service fail2ban & vous n’avez plus qu’à tester en faisant plus de 6 tentatives de mot de passe sur la page votreblog/wp-admin/

$ service fail2ban restart
$ tail -f /var/log/fail2ban.log
2013-09-05 16:33:39,559 fail2ban.actions: WARNING [apache-wp-login] Ban XX.XX.XX.XX

Pour information, le lendemain 47 IP ont été bloquées grâce à ce système…

$ fail2ban-client status apache-wp-login
Status for the jail: apache-wp-login
|- Filter
| |- Currently failed: 7
| |- Total failed: 59966
| `- File list: /var/log/apache2/mercereau.info/access.log
`- Actions
|- Currently banned: 0
|- Total banned: 4128
`- Banned IP list:

Si comme moi vous gérez un hébergement mutualiser vous pouvez ajouter un script qui toutes les nuits scan votre /var/www à la recherche de wp-login.php et ajout le log dans fail2ban. Ce script est adapté à l’architecture d’ISPconfig :

#!/bin/bash

# Détection des wordpress sur le serveur
# Ajout des logs du site en question dans fail2ban
# Fonctionne avec l'arbo du panel ISPconfig3
# A mettre en tâche planifié

fail2banConf='/etc/fail2ban/jail.d/apache-wp-login.conf'

echo -n "[apache-wp-login]
enabled = true
port    = http,https
filter  = apache-wp-login
maxretry = 8
logpath = " > $fail2banConf

find /var/www/clients -name wp-login.php | while IFS=$'\n' read f ; do
    clientId=`echo $f | cut -d"/" -f5`
    siteId=`echo $f | cut -d"/" -f6`
    # Test si le lien symbolique n'est pas mort
    readlink=`readlink /var/www/clients/$clientId/$siteId/log/access.log`
    ls /var/www/clients/$clientId/$siteId/log/${readlink} &amp;>/dev/null
    if ! (($?)) ; then
		echo "	/var/www/clients/$clientId/$siteId/log/access.log " >> $fail2banConf
    fi
done

/etc/init.d/fail2ban restart >/dev/null

Vous pouvez aussi faire la même chose pour bloquer wp-xmlrpc (qui est très sollicitée en brute force. Dans le script d’automatisation je télécharge les IP utilisé par JetPack (non pas que j’aime ce plugin mais certain de mes utilisateurs l’utilise et c’est bloquant pour xmlrpc…

#!/bin/bash

# Détection des wordpress sur le serveur
# Ajout des logs du site en question dans fail2ban
# Fonctionne avec l'arbo du panel ISPconfig3
# A mettre en tâche planifié

# https://wpchannel.com/wordpress/tutoriels-wordpress/lutter-attaques-ddos-xml-rpc-php-fail2ban/

cd /tmp
wget https://jetpack.com/ips-v4.txt
if ! (($?)) ; then
	ips=`sed ':a;N;$!ba;s/\n/ /g' /tmp/ips-v4.txt`
else 
	ips=''
fi

fail2banConf='/etc/fail2ban/jail.d/apache-wp-xmlrpc.conf'

echo -n "[apache-wp-xmlrpc]
enabled = true
filter = apache-wp-xmlrpc
bantime = 86400
maxretry = 1
port    = http,https
ignoreip = 127.0.0.1/8 ns1.wordpress.com ns2.wordpress.com ns3.wordpress.com ns4.wordpress.com jetpack.wordpress.com $ips 
logpath = " > $fail2banConf

find /var/www/clients -name wp-login.php | while IFS=$'\n' read f ; do
    clientId=`echo $f | cut -d"/" -f5`
    siteId=`echo $f | cut -d"/" -f6`
    # Test si le lien symbolique n'est pas mort
    readlink=`readlink /var/www/clients/$clientId/$siteId/log/access.log`
    ls /var/www/clients/$clientId/$siteId/log/${readlink} &amp;>/dev/null
    if ! (($?)) ; then
		echo "	/var/www/clients/$clientId/$siteId/log/access.log " >> $fail2banConf
    fi
done

/etc/init.d/fail2ban restart >/dev/null

Et le fichier : /etc/fail2ban/filter.d/apache-wp-xmlrpc.conf

[Definition]
failregex = ^ .(GET|POST) /xmlrpc.php .
ignoreregex =

6 réflexions au sujet de « WordPress & fail2ban : stopper la brute-force « POST /wp-login.php » »

  1. Bonjour

    N’y aurait il pas un plugin permettant de mettre en place cette protection (utile pour les sites hébergés en mode mutualisé donc sans possibilité d ‘accès à l’adminstration système et donc à l’installation / configuration de fail2ban) ?

  2. Bonjour

    WordPress ayant écrasé une bonne partie de mon commentaire,  voici une version synthétique 🙂

    On peut utiliser des variables nommées dans le filtre comme  url_preserved = wp-login\.php et  %(url_preserved)s

    Pour tester que le fonctionnement du filtre, nous avons le script fail2ban-regex : fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/apache-wp-login.conf

    Pour contrôler le comportement de fail2ban autant préférer : fail2ban-client status apachewp-login

    Je me suis permis de synthétiser ces informations sur cette page :  http://km.azerttyu.net/Wordpress-et-les-attaques-brute-force

    Merci encore 🙂

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.