Для защиты сайтов на WordPress от грубого переборы паролей существует множество плагинов, но все они банят злоумышленников на уровне самого WordPress. А это совсем не здорово. Хотелось бы банить их на уровне iptables.
Сразу же на ум приходит замечательная программа fail2ban, но сразу же возникает вопрос — как отловить ошибку авторизации. WordPress ее никак не отлавливает и тупо возвращает код 200. Пока идут дискуссии по поводу ошибки авторизации WordPress, в дебрях интернета был найден прекрасный плагин, выдающий в указанный log сообщение об ошибке авторизации и прикрутить fail2ban оказалось достаточно просто. Вот сам плагин:
<?php /* Plugin Name: Lumpy Login Protect Description: Protect the WordPress login screen by blocking common usernames and writing failed attempts to the error log (for use by fail2ban) Version: 0.2 License: GPL version 2 or any later version Author: Simon Blackbourn Author URI: http://lumpylemon.uk https://twitter.com/lumpysimon */ defined( 'ABSPATH' ) or die(); $ll_login_protect = new ll_login_protect; class ll_login_protect { function __construct() { add_action( 'muplugins_loaded', array( $this, 'maybe_block' ) ); add_action( 'wp_login_failed', array( $this, 'log_failure' ) ); } function maybe_block() { $blocked = array( 'admin', 'administrator' ); if ( isset( $_POST[ 'log' ] ) and isset( $_POST[ 'pwd' ] ) and in_array( trim( $_POST[ 'log' ] ), $blocked ) ) { error_log( 'WordPress login fail: ' . $_POST[ 'log' ] ); die(); } } function log_failure( $username ) { error_log( 'WordPress login fail: ' . $username ); } } // class
Создаем файл с именем login-protect.php с указанным выше содержимым и кидаем его в директорию wp-content/plugins или wp-content/mu-plugins. Заходим в «плагины» в панели управления и активируем плагин Lumpy Login Protect.
В файл ошибок htth сервера теперь при любой ошибочной авторизации будет выдаваться сообщение
WordPress login fail: <имя_пользователя>
и ip адрес клиента.
Далее настраиваем fail2ban. Здесь приведены настройка для nginx+php-fpm. Для apache — нечто подобное, только другой файл логов и иная структура сообщения об ошибке в фильтре.
В конец файла /etc/fail2ban/jail.conf добавляем что-то типа:
[wordpress] enabled = true port = http,https filter = wordpress-auth logpath = /var/log/nginx/error.log maxretry = 3 bantime = 1200 findtime = 600
Создаем новый файл фильтра /etc/fail2ban/filter.d/wordpress-auth.conf:
[Definition] #По моему для apache будет так #failregex = [[]client <HOST>[]] WordPress login fail.* #Для nginx+php-fpm failregex = .*WordPress login fail.*client: <HOST>.* ignoreregex =
Перегружаем сервис fail2ban и всё должно работать.