Version Description
- Add experimental support for X-Forwarded-For header; see
WP_FAIL2BAN_PROXIES
- Add experimental support for regex-based login blocking; see
WP_FAIL2BAN_BLOCKED_USERS
Download this release
Release Info
Developer | invisnet |
Plugin | WP fail2ban |
Version | 2.0.0 |
Comparing to | |
See all releases |
Code changes from version 1.2.1 to 2.0.0
- readme.txt +44 -8
- wordpress.conf +1 -0
- wp-fail2ban.php +53 -5
readme.txt
CHANGED
@@ -4,8 +4,8 @@ Author URI: https://charles.lecklider.org/
|
|
4 |
Plugin URI: https://charles.lecklider.org/wordpress/wp-fail2ban/
|
5 |
Tags: fail2ban, security, syslog, login
|
6 |
Requires at least: 3.4.0
|
7 |
-
Tested up to: 3.
|
8 |
-
Stable tag:
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -38,29 +38,65 @@ Requires PHP 5.3 or later.
|
|
38 |
|
39 |
1. Reload or restart `fail2ban`
|
40 |
|
41 |
-
|
42 |
|
43 |
== Frequently Asked Questions ==
|
44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
= Why is fail2ban complaining on my flavour of Linux? =
|
46 |
|
47 |
Depending on your `fail2ban` configuration, you may need to add a line like:
|
48 |
|
49 |
-
|
50 |
|
51 |
to the `[wordpress]` section in `jail.local`.
|
52 |
|
53 |
== Changelog ==
|
54 |
|
|
|
|
|
|
|
|
|
55 |
= 1.2.1 =
|
56 |
-
Update FAQ.
|
57 |
|
58 |
= 1.2 =
|
59 |
-
Fix harmless warning.
|
60 |
|
61 |
= 1.1 =
|
62 |
-
Minor cosmetic updates.
|
63 |
|
64 |
= 1.0 =
|
65 |
-
Initial release.
|
|
|
|
|
66 |
|
|
|
|
4 |
Plugin URI: https://charles.lecklider.org/wordpress/wp-fail2ban/
|
5 |
Tags: fail2ban, security, syslog, login
|
6 |
Requires at least: 3.4.0
|
7 |
+
Tested up to: 3.6
|
8 |
+
Stable tag: 2.0.0
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
38 |
|
39 |
1. Reload or restart `fail2ban`
|
40 |
|
41 |
+
You may want to set WP_FAIL2BAN_PROXIES and/or WP_FAIL2BAN_BLOCKED_USERS; see the FAQ for details.
|
42 |
|
43 |
== Frequently Asked Questions ==
|
44 |
|
45 |
+
= WP_FAIL2BAN_PROXIES - what's it all about? =
|
46 |
+
|
47 |
+
The idea here is to list the IP addresses of the trusted proxies that will appear as the remote IP for the request. When defined:
|
48 |
+
|
49 |
+
* If the remote address appears in the `WP_FAIL2BAN_PROXIES` list, *WPf2b* will log the IP address from the `X-Forwarded-For` header
|
50 |
+
* If the remote address does not appear in the `WP_FAIL2BAN_PROXIES` list, *WPf2b* will return a 403 error
|
51 |
+
* If there's no X-Forwarded-For header, *WPf2b* will behave as if `WP_FAIL2BAN_PROXIES` isn't defined
|
52 |
+
|
53 |
+
To set `WP_FAIL2BAN_PROXIES`, add something like the following to `wp-config.php`:
|
54 |
+
|
55 |
+
define('WP_FAIL2BAN_PROXIES','192.168.0.42,192.168.0.43');
|
56 |
+
|
57 |
+
*WPf2b* doesn't do anything clever with the list so don't add whitespace or CIDR notations.
|
58 |
+
|
59 |
+
= WP_FAIL2BAN_BLOCKED_USERS - what's it all about? =
|
60 |
+
|
61 |
+
The bots that try to brute-force WordPress logins aren't that clever (no doubt that will change), but they may only make one request per IP every few hours in an attempt to avoid things like `fail2ban`. With large botnets this can still create significant load.
|
62 |
+
|
63 |
+
Based on a suggestion from *jmadea*, *WPf2b* now allows you to specify a regex that will shortcut the login process if the requested username matches.
|
64 |
+
|
65 |
+
For example, putting the following in `wp-config.php`:
|
66 |
+
|
67 |
+
define('WP_FAIL2BAN_BLOCKED_USERS','^admin$');
|
68 |
+
|
69 |
+
will block any attempt to log in as `admin` before most of the core WordPress code is run. Unless you go crazy with it, a regex is usually cheaper than a call to the database so this should help keep things running during an attack.
|
70 |
+
|
71 |
+
*WPf2b* doesn't do anything to the regex other than make it case-insensitive.
|
72 |
+
|
73 |
= Why is fail2ban complaining on my flavour of Linux? =
|
74 |
|
75 |
Depending on your `fail2ban` configuration, you may need to add a line like:
|
76 |
|
77 |
+
port = http,https
|
78 |
|
79 |
to the `[wordpress]` section in `jail.local`.
|
80 |
|
81 |
== Changelog ==
|
82 |
|
83 |
+
= 2.0.0 =
|
84 |
+
* Add *experimental* support for X-Forwarded-For header; see `WP_FAIL2BAN_PROXIES`
|
85 |
+
* Add *experimental* support for regex-based login blocking; see `WP_FAIL2BAN_BLOCKED_USERS`
|
86 |
+
|
87 |
= 1.2.1 =
|
88 |
+
* Update FAQ.
|
89 |
|
90 |
= 1.2 =
|
91 |
+
* Fix harmless warning.
|
92 |
|
93 |
= 1.1 =
|
94 |
+
* Minor cosmetic updates.
|
95 |
|
96 |
= 1.0 =
|
97 |
+
* Initial release.
|
98 |
+
|
99 |
+
== Upgrade Notice ==
|
100 |
|
101 |
+
= 2.0.0 =
|
102 |
+
This is an experimental release. If your current version is working and you're not interested in the new features, skip this version - wait for 2.1.0. For those that do want to test this release, note that `wordpress.conf` has changed - you'll need to copy it to `fail2ban/filters.d` again.
|
wordpress.conf
CHANGED
@@ -22,6 +22,7 @@ _daemon = wordpress
|
|
22 |
# Values: TEXT
|
23 |
#
|
24 |
failregex = ^%(__prefix_line)sAuthentication failure for .* from <HOST>$
|
|
|
25 |
|
26 |
# Option: ignoreregex
|
27 |
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
22 |
# Values: TEXT
|
23 |
#
|
24 |
failregex = ^%(__prefix_line)sAuthentication failure for .* from <HOST>$
|
25 |
+
^%(__prefix_line)sBlocked authentication attempt for .* from <HOST>$
|
26 |
|
27 |
# Option: ignoreregex
|
28 |
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
wp-fail2ban.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: WP fail2ban
|
4 |
Plugin URI: https://charles.lecklider.org/wordpress/wp-fail2ban/
|
5 |
Description: Write all login attempts to syslog for integration with fail2ban.
|
6 |
-
Version:
|
7 |
Author: Charles Lecklider
|
8 |
Author URI: https://charles.lecklider.org/
|
9 |
License: GPL2
|
@@ -25,17 +25,65 @@ License: GPL2
|
|
25 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
26 |
*/
|
27 |
|
|
|
28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
add_action( 'wp_login',
|
30 |
function($user_login, $user)
|
31 |
{
|
32 |
-
openlog(
|
33 |
-
syslog(LOG_INFO,"Accepted password for $user_login from
|
34 |
},10,2);
|
35 |
add_action( 'wp_login_failed',
|
36 |
function($username)
|
37 |
{
|
38 |
-
openlog(
|
39 |
-
syslog(LOG_NOTICE,"Authentication failure for $username from
|
40 |
});
|
41 |
|
3 |
Plugin Name: WP fail2ban
|
4 |
Plugin URI: https://charles.lecklider.org/wordpress/wp-fail2ban/
|
5 |
Description: Write all login attempts to syslog for integration with fail2ban.
|
6 |
+
Version: 2.0.0
|
7 |
Author: Charles Lecklider
|
8 |
Author URI: https://charles.lecklider.org/
|
9 |
License: GPL2
|
25 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
26 |
*/
|
27 |
|
28 |
+
namespace org\lecklider\charles\wp_fail2ban;
|
29 |
|
30 |
+
function openlog()
|
31 |
+
{
|
32 |
+
\openlog('wordpress('.$_SERVER['HTTP_HOST'].')',
|
33 |
+
LOG_NDELAY|LOG_PID,
|
34 |
+
defined(WP_FAIL2BAN_LOG) ? WP_FAIL2BAN_LOG : LOG_AUTH);
|
35 |
+
}
|
36 |
+
|
37 |
+
function bail()
|
38 |
+
{
|
39 |
+
ob_end_clean();
|
40 |
+
header('HTTP/1.0 403 Forbidden');
|
41 |
+
header('Content-Type: text/plain');
|
42 |
+
exit('Forbidden');
|
43 |
+
}
|
44 |
+
|
45 |
+
function remote_addr()
|
46 |
+
{
|
47 |
+
$ip = $_SERVER['REMOTE_ADDR'];
|
48 |
+
|
49 |
+
if (defined('WP_FAIL2BAN_PROXIES')) {
|
50 |
+
if (array_key_exists($_SERVER,'HTTP_X_FORWARDED_FOR')) {
|
51 |
+
if (in_array($ip, explode(',',WP_FAIL2BAN_PROXIES) )) {
|
52 |
+
$ip = (false===($len = strpos($_SERVER['HTTP_X_FORWARDED_FOR'],',')))
|
53 |
+
? $_SERVER['HTTP_X_FORWARDED_FOR']
|
54 |
+
: substr($_SERVER['HTTP_X_FORWARDED_FOR'],0,$len);
|
55 |
+
} else {
|
56 |
+
bail();
|
57 |
+
}
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
return $ip;
|
62 |
+
}
|
63 |
+
|
64 |
+
if (defined('WP_FAIL2BAN_BLOCKED_USERS')) {
|
65 |
+
add_action( 'authenticate',
|
66 |
+
function($user, $username, $password)
|
67 |
+
{
|
68 |
+
if (!empty($username) && preg_match('/'.WP_FAIL2BAN_BLOCKED_USERS.'/i', $username)) {
|
69 |
+
openlog();
|
70 |
+
\syslog(LOG_NOTICE,"Blocked authentication attempt for $username from ".remote_addr());
|
71 |
+
bail();
|
72 |
+
}
|
73 |
+
|
74 |
+
return $user;
|
75 |
+
},1,3);
|
76 |
+
}
|
77 |
add_action( 'wp_login',
|
78 |
function($user_login, $user)
|
79 |
{
|
80 |
+
openlog();
|
81 |
+
\syslog(LOG_INFO,"Accepted password for $user_login from ".remote_addr());
|
82 |
},10,2);
|
83 |
add_action( 'wp_login_failed',
|
84 |
function($username)
|
85 |
{
|
86 |
+
openlog();
|
87 |
+
\syslog(LOG_NOTICE,"Authentication failure for $username from ".remote_addr());
|
88 |
});
|
89 |
|