fail2ban & nginx & wordpress bruteforce protection

Auf der suche nach fail2ban rules um bruteforce loginversuche auf wordpress zu verhindern stieß ich auf diesen Blogpost:

http://blog.somsip.com/2012/02/using-fail2ban-to-protect-wordpress/

der Artikel bezieht sich allerdings auf Apache.
Unter nginx…
(debian mit nginx und php-fpm von http://dotdeb.org)
… sehen die Logs aber etwas anders aus und brauchen deshalb eine etwas andere regex im fail2ban Filter.

Beispiel-Log mit nginx & php-fpm:


2013/04/14 02:24:10 [error] 27884#0: *204 FastCGI sent in stderr: "PHP message: WP login failed for username: xyz" while reading response header from upstream, client: 192.168.0.23, server: example.com, request: "POST /wp-login.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9015", host: "www.example.com", referrer: "http://www.example.com/wp-login.php"

Als erstes, um WordPress dazu zu bringen überhaupt fehlgeschlagene logins ins error.log vom Webserver zu schreiben benötigen wir folgenden Eintrag in der functions.php des jeweils benutzen Themes von wordpress:


// Log login errors to Apache/nginx error log
add_action('wp_login_failed', 'log_wp_login_fail'); // hook failed login
function log_wp_login_fail($username) {
error_log("WP login failed for username: $username");
}

Dadurch bekommen wir, bei fehlgeschlagenen logins, Einträge in unser error.log wie oben im Beispiel.

Danach legen wir in unserer fail2ban Installation folgende Datei an:


/etc/fail2ban/filters.d/nginx-wp-login.conf

In diese Datei kommt die regex die auf den Logeintrag passt:


[Definition]
failregex = WP login failed.*client: <HOST>
ignoreregex =

Tipp: um euch “regular expressions” für andere Anwendungen zu bauen empfehle ich: http://gskinner.com/RegExr/ für alle die keine Zeit Haben ein Studium zu beginnen 😉

Jetzt brauchen wir nur noch einen Eintrag in unserer jail.local:


[apache-wp-login]
enabled = true
port = http,https
filter = nginx-wp-login
logpath = /var/log/nginx*/*error.log
maxretry = 3
findtime = 120

danach fail2ban neu starten:


/etc/init.d/fail2ban restart

Fertsch!