The Burton Tech Journal

Fix for Incorrect IP Addresses in WordPress Comments

by on Nov.30, 2008, under PHP, Security, Spam, Wordpress

Due to a web server’s proxy or the server is clustered (particularly with “cloud” based hosting), the server variable WordPress uses does not reflect the IP address of the posting user. Instead the IP address is the internal private LAN address of the web server’s network. This causes problems when trying to blacklist spammers or use a plugin like Akismet.

To workaround this IP address issue, you will need to modify the $_SERVER[“REMOTE_ADDR”] variable by editing the “wp-config.php” in your WordPress root directory:

  1. Download and backup your wp-config.php configuration file.
  2. Open your WordPress configuration file and add the following code after the named constant definitions:

/* By Grant Burton @ BURTONTECH.COM (11-30-2008): IP-Proxy-Cluster Fix */
/* Updated on 7/30/2015 to reflect current IANA addresses */
function checkIP($ip) {
if (!empty($ip) && ip2long($ip)!=-1 && ip2long($ip)!=false) {
$private_ips = array (array('10.0.0.0','10.255.255.255'),
array('127.0.0.0','127.255.255.255'),
array('169.254.0.0','169.254.255.255'),
array('172.16.0.0','172.31.255.255'),
array('192.168.0.0','192.168.255.255'),
array('255.255.255.0','255.255.255.255')
);

</p><p>foreach ($private_ips as $r) {
$min = ip2long($r[0]);
$max = ip2long($r[1]);
if ((ip2long($ip) >= $min) && (ip2long($ip) < = $max)) return false; } return true; } else { return false; } } function determineIP() { if (checkIP($_SERVER["HTTP_CLIENT_IP"])) { return $_SERVER["HTTP_CLIENT_IP"]; } foreach (explode(",",$_SERVER["HTTP_X_FORWARDED_FOR"]) as $ip) { if (checkIP(trim($ip))) { return $ip; } } if (checkIP($_SERVER["HTTP_X_FORWARDED"])) { return $_SERVER["HTTP_X_FORWARDED"]; } elseif (checkIP($_SERVER["HTTP_X_CLUSTER_CLIENT_IP"])) { return $_SERVER["HTTP_X_CLUSTER_CLIENT_IP"]; } elseif (checkIP($_SERVER["HTTP_FORWARDED_FOR"])) { return $_SERVER["HTTP_FORWARDED_FOR"]; } elseif (checkIP($_SERVER["HTTP_FORWARDED"])) { return $_SERVER["HTTP_FORWARDED"]; } else { return $_SERVER["REMOTE_ADDR"]; } } //Override server variable for WordPress comments $_SERVER["REMOTE_ADDR"] = determineIP(); 

Caution should be used since many of these variables can be spoofed by a client, so don’t use them for authentication or access control. The functions could be easily adapted for other web applications though.

 

:, , , , , , , , , , , , , , ,

3 Comments for this entry

  • Gabor 'Morc' Kormos

    Great work Grant, but the 2.0.0.0/8 range is not private any more. I just saw a legit IP like today. You should update the code and remove that line altogether, or narrow it down to 0.0.0.0/8 as according to IANA only 0.0.0.0/8 is local.

  • Patrick Pollet

    Hello

    Please find below a slightly revised version of your functions that do not trigger PHP notice when in full debug mode and remove extraneous spaces in the case of comma separated multiple IPS

    Cheers

    /* By Grant Burton @ BURTONTECH.COM (11-30-2008): IP-Proxy-Cluster Fix */
    function checkIP($ip) {
    if (!empty($ip) && ip2long($ip)!=-1 && ip2long($ip)!=false) {
    $private_ips = array (
    array(‘0.0.0.0′,’2.255.255.255’),
    array(‘10.0.0.0′,’10.255.255.255’),
    array(‘127.0.0.0′,’127.255.255.255’),
    array(‘169.254.0.0′,’169.254.255.255’),
    array(‘172.16.0.0′,’172.31.255.255’),
    array(‘192.0.2.0′,’192.0.2.255’),
    array(‘192.168.0.0′,’192.168.255.255’),
    array(‘255.255.255.0′,’255.255.255.255’)
    );

    foreach ($private_ips as $r) {
    $min = ip2long($r[0]);
    $max = ip2long($r[1]);
    if ((ip2long($ip) >= $min) && (ip2long($ip) <= $max)) return false;
    }
    return true;
    } else {
    return false;
    }
    }

    function determineIP() {
    if (!empty($_SERVER['HTTP_CLIENT_IP']) && checkIP($_SERVER["HTTP_CLIENT_IP"])) {
    return $_SERVER["HTTP_CLIENT_IP"];
    }

    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    foreach (explode(",",$_SERVER["HTTP_X_FORWARDED_FOR"]) as $ip) {
    //attention aux espaces (null), 134.214.152.108 !!!!!!
    if (checkIP(trim($ip))) {
    return trim($ip);
    }
    }
    }
    if (!empty($_SERVER['HTTP_X_FORWARDED'])&& checkIP($_SERVER["HTTP_X_FORWARDED"])) {
    return $_SERVER["HTTP_X_FORWARDED"];
    } elseif (!empty($_SERVER["HTTP_X_CLUSTER_CLIENT_IP"]) && checkIP($_SERVER["HTTP_X_CLUSTER_CLIENT_IP"])) {
    return $_SERVER["HTTP_X_CLUSTER_CLIENT_IP"];
    } elseif (!empty($_SERVER["HTTP_FORWARDED_FOR"]) && checkIP($_SERVER["HTTP_FORWARDED_FOR"])) {
    return $_SERVER["HTTP_FORWARDED_FOR"];
    } elseif (!empty($_SERVER["HTTP_FORWARDED"]) && checkIP($_SERVER["HTTP_FORWARDED"])) {
    return $_SERVER["HTTP_FORWARDED"];
    } elseif(!empty($_SERVER["REMOTE_ADDR"]) && checkIP($_SERVER["REMOTE_ADDR"])) {
    return $_SERVER["REMOTE_ADDR"];
    } else {
    return '';
    }
    }

  • Luis

    Warning, the first range is wrong: array(‘0.0.0.0′,’2.255.255.255’)
    the right one is:
    array(‘0.0.0.0′,’0.255.255.255’)

    Example: 2.227.250.202 is a valid public IP (from Italian Fastweb Company) !!!

1 Trackback or Pingback for this entry

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Blogroll

A few highly recommended websites...