Lutter contre les attaques DDOS sur XML-RPC avec fail2ban

Les attaques DDOS consistent à lancer un grand nombre de requêtes sur votre serveur afin de le rendre inaccessible. En s’intéressant aux journaux d’événements – les fameux logs serveur, on s’aperçoit rapidement que le fichier xmlrpc.php est l’un des plus attaqués avec le formulaire de connexion de votre WordPress. Pour se protéger, une solution radicale consiste à intercepter les adresses IP qui viennent faire des requêtes successives sur ledit fichier et à les bloquer dans le pare-feu de votre serveur.

Pré-requis

Ce tutoriel s’adresse aux utilisateurs hébergés sur des VPS ou des serveurs dédiés maitrisant les connexions en SSH. On part également du principe que fail2ban est installé. Une debian sera utilisée dans ce tutoriel, à vous de l’adapter en fonction.

Pour les utilisateurs hébergés en mutualisé, renseignez-vous auprès de votre hébergeur pour savoir si des filtres de protections spécifiques à WordPress sont activés. Je vous recommande vivement le plugin SF Move Login et Limit Login Attempts – ancien mais parfaitement fonctionnel, ou équivalent.

Enfin, notez que cette technique est à proscrire dans le cas où le fichier xmlrpc.php est nécessaire à votre projet. En théorie, vous devriez le savoir au regard de ce que cela implique techniquement. Si vous n’en avez aucune idée, alors foncez et ajuster le tir en conséquence.

Modification de la configuration de fail2ban

Connectez-vous sur votre serveur et localisé le fichier jail.local situé dans /etc/fail2ban/

Faites une copie de sauvegarde par prudence puis rajoutez les lignes ci-dessous :

[wordpress-xmlrpc]
enabled = true
filter = wordpress-xmlrpc
action = iptables[name=WordPressXMLRPC, port=http, protocol=tcp]
logpath = /var/log/apache2/other_vhosts_access.log
bantime = 86400
maxretry = 1

Concrètement, nous allons ajouter une règle supplémentaire pour que le pare-feu vienne scanner les journaux d’événements de notre machine virtuelle. Ensuite, nous recherchons toutes les requêtes effectuées sur le fichier xml-rpc.php situé à la racine de votre installation WordPress. Si une IP est trouvée, on la bannit pour une durée de 86 400 secondes, soit 24 heures. Le paramètre maxretry limite à 1 tentative de connexion sur ce fichier en 60 secondes, autant dire que nous sommes sans pitié.

Ajout d’un filtre pour fail2ban

Comme vous avez du le noter, le code ci-dessous indique le recours au filtre intitulé wordpress-xmlrpc. Il nous faut simplement aller créer un nouveau fichier wordpress-xmlrpc.conf que vous placerez dans le dossier filter.d.

# wordpress-xmlrpc.conf
[INCLUDES]
before = common.conf

[Definition]
_daemon = wordpress
failregex = .*:(80|443) <host> .*(GET|POST) .*/xmlrpc.php
ignoreregex =</host>

Ce filtre va scanner le fichier other_vhosts_access.log à la recherche d’une requête se terminant par xmlrpc.php sur les ports 80 et 443 qui correspondent respectivement aux protocoles HTTP et HTTPS.

Redémarrez le service fail2ban pour appliquer les changements via la commande SSH :

sudo /etc/init.d/fail2ban restart

Vérifier l’efficacité du filtre

Si vous êtes régulièrement attaqué par des IP suspectes sur votre serveur, le filtrage devrait très rapidement fonctionner en rajoutant des IP dans la liste noire.

Pour ce faire, exécutez la commande suivante :

sudo iptables -L -n

Recherchez fail2ban-WordPressXMLRPC et constatez le résultat :

Pour ma part, j’ai bloqué plus de 400 adresses IP en quelques heures.

wordpress-ddos-xml-rpc

Pour les utilisateurs de MainWP

Si vous gérez votre maintenance à l’aide de l’outil MainWP, vous devez ajouter votre IP dans la liste blanche de sorte qu’elle soit ignorée. En effet, vous aurez besoin de XML-RPC pour accéder à distance à vos différentes installations WordPress.

Pour ce faire, connectez-vous sur votre serveur et modifiez le fichier jail.conf dans /etc/fail2ban/

À la ligne 21 ignoreip, ajoutez l’IP de votre choix en séparant par un espace.

mainwp-ip-fail2ban

Vous pouvez maintenant utiliser MainWP sans soucis.

Vous voici à présent protéger des attaques sur xmlrpc.php activé par défaut depuis WordPress 3.5 ce qui à mon sens est une erreur. La case à cocher en back-office qui existait auparavant ne gênait pourtant pas grand monde…

16 commentaires

    1. Aurélien Denis auteur de l’article

      Merci du compliment !

      Le blocage par htaccess a 2 inconvénients : il doit être mis en place pour chaque site sur ton serveur et ne retourne accès bloqué (une erreur donc). Ainsi, l’IP distante n’est pas bloquée par ta machine, uniquement l’accès au fichier l’est. De fait, ça ne filtre pas les DDOS.

  1. Dominique Ⓦ (@doopix)

    Oui, c’est bien ce qu’il me semblait. La version htaccess est intéressante si le parefeu de l’hébergeur détecte le DDOS (genre plus de « n » accès en 5 secondes par ex.) et intercepte celui-ci. Du coup le blocage htaccess n’est plus qu’une simple sécurité supplémentaire. Ou pour être plus spécifique le blocage htaccess protège « seulement » l’accès à ce fichier « sensible ». Du coup le DDOS est toujours possible.

  2. wil

    Bonjour Aurélien,

    Super merci pour le tips..

    Voilà plusieurs jours que je souhaitais trouver une solution pour ces attaques qui n’arrêtent pas.

    Comme je n’ai pas forcément un accès au VPS/dédié, et qu’aucun utilisateur se sert de XML-RPC, j’ai essayé une redirection dans le fichier .htaccess. vers un site qui n’existe pas (on est bien d’accord..) J’en ai aussi profiter pour mettre à jour le robots.txt pour éviter que les moteurs de recherches ne soient éventuellement impactés.

    D’après ce que je peux voir sur les VPS/dédiés auquel j’ai accès, les machines ne semblent plus souffrir des attaques.
    Est-ce que vous pensez que ça pourrait impacter quelques choses à laquelle je n’aurai pas penser ?

    L’idée étant, au final, de laisser les amateurs de DDOS de l’été devoir payer leurs kimsufi ou VPS, qu’ils puissent s’amuser, sans que ça n’impacte personne

  3. wil

    Je dirai que si on fait un deny, il y a beaucoup de chance que WordPress utilise quand même php soit pour la page 404 soit pour la page 401 ou 403.
    C’est peut être pour ça que le serveur continue d’être surchargé. Enfin, je crois

    Par contre, la redirection vers un site inexistant, pas de php, pas de surcharge.. A moins certainement d’un nombre conséquent de machines utilisées pour les requêtes vers xml-rpc.php.

    Sur un VPS, j’ai vu, en direct, 2 machines envoyant simultanément entre 12 et 15 requêtes par seconde… Le VPS n’a pas bronché. Il serait tombé sans la redirection.

    Ce n’est pas une recette miracle. Vu qu’elle vient en plus de mon crâne de piaf, je suis loin d’être certain qu’elle soit efficace. D’où ma question…

  4. wil

    Ah si bien sûr. C’est pour ça que je te remerciais pour le filtre fail2ban en premier lieu
    J’aimais bien l’idée de « hacker » le hackeur sans que ça ne gène personne. Mais, sans être certains à 100% non plus qu’il n’y ait pas un effet de bord.

  5. pascalp37

    j’essayais de faire la modif, mais je suis sur centos 6.7 et bien sur j’ai une erreur d’adresse « /var/log/apache2/other_vhosts_access.log » . j’ai fait une recheche pour ce fichier et rien trouvé, dois-je le créer ou où le trouver.!!!!!!!

  6. lucywaou

    Sur CentOS,, tu peux remplacer le répertoire « apache2 » par « httpd » et créer le other_vhosts_access.log manuellement
    Dans le failregex, le HOST doit être en majuscule

  7. Bastien

    Super article, merci. Cependant un filtre trop ‘fin’ au niveau des maxretry entrainera le dysfonctionnement de certains plugins qui utilisent XMLRPC comme Jetpack. maxretry = 3 est plus judicieux à mon sens.

  8. Charlie Echo

    J’ai suivi ce tuto et 10 autres sur Internet ; j’ai eu un mal FOU à arrêter les attaques, car j’avais l’impression que fail2ban ne fonctionnait pas, sans que j’arrive à comprendre pourquoi.

    Ce qui a marché, c’était de :
    – arrêter apache et « rotater » les logs deux fois pour avoir un échantillon de logs utilisables :
    -sudo service apache2 stop ; sudo mv access.log access.log2 ; sudo service apache2 start
    – attendre 2 minutes
    -sudo service apache2 stop ; sudo mv access.log access.log3 ; sudo service apache2 start

    – travailler sur le fichier access.log3 pour vérifier la syntaxe du filtre :
    – fail2ban-regex access.log3 /etc/fail2ban/filter.d/xmlrpc.conf
    (syntaxe qui était bonne au passage…)

    – relancer fail2ban :
    – sudo service fail2ban restart

    Peut-être que fail2ban essaye de « remonter la pente » en scrutant un fichier access.log déjà énorme, et qu’il n’y arrive pas. En tous cas, pour moi, j’ai dû en passer par là…

Laisser un commentaire