Wordpress et les attaques brute force

Dans le cadre de l’hébergement de wordpress, on voit régulièrement des tentatives d’attaques brutes forces sur la page de connexion de ces plate-formes.

Profitons de notre avantage d’hébergeur pour exploiter les capacités de fail2ban

Prérequis

Je considére que nous avons sous la main un serveur apache, au moins un site utilisant wordpress et fail2ban.
Les chemins indiqués dans les exemples supposeront un environnement Debian

Analyser les logs apache

Pour se protéger des attaques brutes forces, il faut savoir les identifier voici ce que cela peut donner pour le site www.monsitewp.net :

On peut constater que, selon l’extrait présenté :

  • 199.30.16.38 est légitime en tant que bot msn,
  • 192.168.0.1 est légitime en tant que cron pour le site concerné,
  • 269.31.103.204 est certainement malveillant, plusieurs connexions simultanées à la page d’authentification,
  • 177.256.80.95 potentiellement légitime au vu de l’extrait présenté
  • 2.237.259.171 est probablement malveillant, au vu des connexions très rapprochées.

On peut définir comme postulat de départ :

  • un utilisateur légitime tentera moins de 3 connexions rapprochées,
  • l’information de connexion est stockée dans le fichier access.log d’apache,
  • la page à protéger est wp_login.php en mode POST.

Définir la règle de filtrage

Pour commencer on définit l’expression régulière à utiliser dans le fichier /etc/fail2ban/filter.d/apache-wp.conf

On notera une petite astuce, l’utilisation d’une variable nommée file_preserved. Cela permet de faire évoluer la règle de filtrage facilement. On peut imaginer la protection des pages de commentaires ou d’un plugin.

Appliquer le filtrage

Dans le fichier /etc/fail2ban/jail.local , [EDIT via kayasax, on évite jail.conf pour ne pas perdre ses modifications lors d’une mise à jour] on applique le filtre en ajoutant les lignes suivantes :

La règle se nomme apache-wp et exploite le filtre apache-wp. Elle s’applique sur tous fichiers de suffixe access.log présents dans les répertoire /var/log/apache et /var/log/apache2.

On banni toute IP ayant accédée à wp_login.php au moins 3 fois dans un intervalle de 600 secondes et ceci pour une durée de 600 secondes.
On peut modifier findtime et bantime pour élargir la fenêtre de détection ou la durée de bannissement.

Contrôler la validité de la règle

Avant de relancer fail2ban, vérifions si notre nouvelle règle fonctionne. On exécute la commande suivante :

fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/apache-wp.conf

Le résultat obtenu ressemblera à :

Relancer et contrôler l’activité de Fail2ban

Nous chargeons la nouvelle configuration via /etc/init.d/fail2ban reload ou service fail2ban reload

Pour contrôler dans le temps l’application de la règle, nous pouvons faire :
watch fail2ban-client status apache-wp

Le résultat sera rafraîchi par défaut toutes 2 secondes.

Conclusion

Votre serveur se portera sûrement mieux avec ce petit paramétrage maison :)

Messages

  • Ha ben ça faisait un moment que t’avais pas posté mignon ! Cool de revoir ton flux RSS dans mon lecteur :)

    ps : tu as du mal fermer une balise de gras dans la conclusion de ton article.

  • Bonjour,

    Tout d’abord merci pour cette documentation. Je suis d’abord passé sur le billet de merceau.info, et j’ai vu ton commentaire, ce qui fait que je suis passé ici. J’ai essayé de mettre en place ce filtre, mais fail2ban échoue au rédémarrage (idem avec la solution de merceau.info).

    J’ai cherché à comprendre pourquoi en comparant avec les deux autres filtres que j’utilise, mais je ne vois vraiment pas. Quand je teste avec ta commande fail2ban -regex, j’ai un résultat qui correspond à bien à ce qui devrait être, je crois. La seule modif que j’ai faite, c’est le chemin vers le fichier de log, vu la configuration de mon apache.

    Il suffit que je passe le enabled à false pour pouvoir démarrer fail2ban. Est-ce que tu pourrais m’indiquer une piste de recherche, ça serait bien cool. Parce qu’en ce moment j’ai des addresses IP qui passent tout droit à travers le plugin limit-login-attempts que j’ai mis en place sur mon serveur.

    • Bonjour

      J’opterai pour un problème de droit. Est ce que Fail2ban arrive à lire les fichiers de logs ?

      • Si non, alors la solution est trouvée. Le client fail2ban ne s’execute pas necessairement avec le compte root.
      • Si oui, j’opterai pour un problème dans la rédaction du jail.conf. Nettoie autant que possible et rajoute les directives au fur et à mesure.

      Bon courage

  • Salut !
    Je plussoie b_b ca faisait un bail :)

    <troll>Alors comme ça tu blogues sur "ceux d’en face" maintenant ? :P</troll>

    Blague à part, en appoint d’une conf’ sensiblement proche de la tienne, on va aussi jusqu’à systématiser l’install de 2 plugins pour calmer un peu le jeu en premier niveau, c’est

    Login Lock Down
    http://wordpress.org/plugins/login-lockdown/

    Lui, en gros, il fait la même chose que f2b mais au niveau du CMS
    Peut être pas ultime ultime mais ca fait une première barrière avant le niveau "serveur"

    SF Author Url Control
    http://wordpress.org/plugins/sf-author-url-control/

    Lui, il permet de sécuriser un poil le compte admin en remplaçant les footprint habituelle et surtout les ID auteurs Wordpress qu’on retrouve dans l’url des pages auteurs : par exemple /admin/ — premier compte testé par un script kiddie quand il veut jouer avec un wp — automatiquement remplacé par /user-123456/ ou encore par /ce-que-tu-decides-ds-le-backoffice/

    • Ciao

      Merci pour ces compléments d’informations, c’est toujours bon à prendre.
      Pour le premier plugin, il me semble inutile, car comme tu le dis il travaille au niveau du CMS. De ce fait apache/nginx/fastcgit/... sera toujours sollicité pour faire le traitement php. Avec fail2ban on passe au niveau inférieur, vers la couche IP, de ce fait le serveur web peut conserver ses ressources pour des choses plus utiles.

      Pour le second plugin, pourquoi pas ça ne peut pas faire de mal pour se prémunir des scripts kiddies. À noter que je ne suis pas fan de l’obfuscation ou assimilé, dans la mesure du possible je préfère rester standard et bien paramétrer le tout. Une histoire de goût :)

      Merci

  • Salut,

    J’ai une question sans doute très noob (désolé...)

    Comment modifier l’expression :
    failregex = ^ -.*POST /%(file_preserved)s HTTP.*
    Pour qu’elle inclue les WP situés dans des sous répertoires ?

    J’ai bien essayer de jouer avec la wildcard, exemple :
    failregex = ^ -.*POST */%(file_preserved)s HTTP.*
    Mais cela ne semble pas fonctionner...

    Alors que si je définit un chemin bien précis, pas de souci, exemple :
    failregex = ^ -.*POST /blog/%(file_preserved)s HTTP.*
    Mais bon, on ne bloque alors les attaques QUE sur le site qui utilise cettte structure...

    Une idée ?

    • Bonjour

      Je dirais à vu de nez :
      failregex = ^ -.*POST /.*%(file_preserved)s HTTP.*

      Le / est en début de la requête.
      Je ne me rappelle plus si les expression régulières sont gourmandes ou pas. Du coup il est possible que le .* prenne tout, y compris le fichier à protéger.
      Dans cas cas, on peut s’en sortir soit en précisant la nature de .* selon les types de répertoires ou bien en exploitant en nouveau les variables.

      failregex = ^ -.*POST /%(mes_repertoires)s/%(file_preserved)s HTTP.*

  • YES ! :-)
    L’expression qui fonctionne est :
    failregex = ^ -.*POST /.*%(file_preserved)s HTTP.*

    Elle intercepte toutes les attaques, exemples :
    77.72.145.32 - - [26/Feb/2014:09:45:44 +0100] "POST /photo/wp-login.php HTTP/1.0" 200 10851 "-" "-"
    62.129.7.85 - - [26/Feb/2014:09:49:00 +0100] "POST /wp-login.php HTTP/1.0" 200 4348 "-" "-"

    Je pense que tu peux la recommander comme expression standard dans le filtre, histoire de couvrir toutes les bases.

    Un très grand merci !

  • Merci pour ces infos, juste une petite coquille je pense : le fichier de conf à modifier devrait être jail.local et non pas jail.conf pour éviter qu’il ne soit écrasé en cas de mise à jour ;)

    peace.

  • Cela fonctionne impec !
    Petite amélioration, au lieu de faire un fichier jail.local il est préférable de faire un fichier apache-wp.conf dans le dossier /etc/fail2ban/jail.d/

  • Bonjour,

    Votre méthode est élégante mais il faut mettre entre parenthèses l’expression de files_preserved car sinon l’opérateur OU ne fonctionne pas et seule la première occurence (wp-login.php) matche sans la seconde occurrence (xmlrpc.php).

    En l’état j’obtiens un miss sur xmlrpc.php avec une erreur ERROR No ’host’ found in ’...’ using ’re.compile(...)’

    Chez moi :
    file_preserved = (xmlrpc\.php|wp-login\.php)
    failregex = ^ -.*"(POST|GET) /+%(file_preserved)s HTTP.*" 200 .*$

    Bonne continuation

Un message, un commentaire ?

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.