Hello,
After upgrading to v5.0 I noticed that failed login attempts were no longer generating a Cloudflare blocked rule. I have other Wordpress sites hosted on the same server running v4.4.0.4 and they are working correctly.
I believe I have everything configured correctly both in my wp-config.php:
/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');
/**
* WP Fail2ban Plugin
* Cloudflare IP Ranges
*/
define('WP_FAIL2BAN_PROXIES', [
'103.21.244.0/22',
'103.22.200.0/22',
'103.31.4.0/22',
'104.16.0.0/13',
'104.24.0.0/14',
'108.162.192.0/18',
'131.0.72.0/22',
'141.101.64.0/18',
'162.158.0.0/15',
'172.64.0.0/13',
'173.245.48.0/20',
'188.114.96.0/20',
'190.93.240.0/20',
'197.234.240.0/22',
'198.41.128.0/17',
'2400:cb00::/32',
'2606:4700::/32',
'2803:f800::/32',
'2405:b500::/32',
'2405:8100::/32',
'2a06:98c0::/29',
'2c0f:f248::/32'
& in my nginx.conf
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP;
So after digging around the code I found the function that was causing an incorrect login attempt to show a “Forbidden” message and failing to create a Cloudflare IP block rule.
function _remote_addr(): ?IP
{
try {
// Typical path first
if (!defined('WP_FAIL2BAN_REMOTE_ADDR')) {
$ip = new IP($_SERVER['REMOTE_ADDR'], true, 'REMOTE_ADDR');
if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
/**
* User-defined proxies, typically upstream nginx
*/
$proxies = array_filter(Config::get('WP_FAIL2BAN_PROXIES'));
if (empty($proxies)) {
// No proxies set; don't care about the header
return $ip;
} elseif ($ip->inRanges($proxies, 'WP_FAIL2BAN_PROXIES')) {
// From a known proxy
$xIPs = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2);
return new IP($xIPs[0], true, 'HTTP_X_FORWARDED_FOR');
} else {
// Not a known proxy: hard fail and bail out
Syslog::single(LOG_NOTICE, "Unknown Proxy with X-Forwarded-For", 'WP_FAIL2BAN_AUTH_LOG', (string)$ip);
do_action(__FUNCTION__.'.unknown_proxy', $ip);
bail();
}
Specifically this part:
} else {
// Not a known proxy: hard fail and bail out
Syslog::single(LOG_NOTICE, "Unknown Proxy with X-Forwarded-For", 'WP_FAIL2BAN_AUTH_LOG', (string)$ip);
do_action(__FUNCTION__.'.unknown_proxy', $ip);
bail();
}
I ended up modifying this else statement to return the IP that was correctly set.
} else {
// Not a known proxy: hard fail and bail out
//BV Workaround
$xIPs = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2);
return new IP($xIPs[0], true, 'HTTP_X_FORWARDED_FOR');
// Syslog::single(LOG_NOTICE, "Unknown Proxy with X-Forwarded-For", 'WP_FAIL2BAN_AUTH_LOG', (string)$ip);
//
// do_action(__FUNCTION__.'.unknown_proxy', $ip);
//
// bail();
}
My website is being correctly proxied through Cloudflare, headers indicate HIT for my resources.
My question at this point is: Is this a known bug or is this the correct behavior?