Vanilla 1 is no longer supported or maintained. If you need a copy, you can get it here.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Check IP addresses behind proxies-It's working :)

edited September 2005 in Vanilla 1.0 Help
I'm using Vanilla on o hosting server that seen to be behind a proxy or somethig because i see only 1 IP for all the users. I'd like if somewone knows php to tell me what do i need to change in order to make the forum ip function work correctly.

For my Wordpress site hosted on the same hosting service i've got a plugin Check IP addresses behind proxies that resolve the problem:
<?php
/*
Plugin Name: Check IP Behind Proxy
Plugin URI: http://mnm.uib.es/gallir/posts/2005/02/21/145/
Description: Check for client public IP sent by proxies in HTTP headers
Author: Ricardo Galli
Version: 1.1
Author URI: http://mnm.uib.es/gallir/
License: GPL
*/ 

function isIPIn($ip,$net,$mask) {
        $lnet=ip2long($net);
        $lip=ip2long($ip);
        $binnet=str_pad( decbin($lnet),32,"0","STR_PAD_LEFT" );
        $firstpart=substr($binnet,0,$mask);
        $binip=str_pad( decbin($lip),32,"0","STR_PAD_LEFT" );
        $firstip=substr($binip,0,$mask);
        return(strcmp($firstpart,$firstip)==0);
}


function isPrivateIP($ip) {
        $privates = array ("127.0.0.0/24", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16");
        foreach ( $privates as $k ) {
                list($net,$mask)=split("/",$k);
                if (isIPIn($ip,$net,$mask)) {
                        return true;
                }
        }
        return false;
}

function check_ip_behind_proxy($user_ip) {
	//$user_ip = $_SERVER["REMOTE_ADDR"];
	if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
		$user_ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
	} else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
		$user_ip = $_SERVER["HTTP_CLIENT_IP"];
	} else {
		return $user_ip;
	}
	$ips = preg_split('/[, ]/', $user_ip);
	foreach ($ips as $ip) {
		if (preg_match('/^(\d{1,3}\.){3}\d{1,3}$/s', $ip)
			&& !isPrivateIP($ip) ) {
			$user_ip = $ip;
		}
	}
	return $user_ip;
}


add_filter('pre_comment_user_ip','check_ip_behind_proxy');

?>

Because I don't have any PHP skills :( i need your help in resolving this problem.

Thanks.

Comments

  • edited September 2005
    //nevermind
  • MarkMark Vanilla Staff
    Hmmm. That is an interesting one.

    Luckily, I use one function to retrieve remote ip addresses. If you open up library/utility.functions.php, you can find my ip address function on line 392:

    So, I guess the thing to do here is mix his function and my function together somehow. I guess it would go kind of like this:
    function GetRemoteIp($FormatIpForDatabaseInput = "0") {
    	$FormatIpForDatabaseInput = ForceBool($FormatIpForDatabaseInput, 0);
    	$sReturn = ForceString(@$_SERVER['REMOTE_ADDR'], "");
    	if (strlen($sReturn) > 20) $sReturn = substr($sReturn, 0, 19);
    	if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
    		$sReturn = $_SERVER["HTTP_X_FORWARDED_FOR"];
    	} else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
    		$sReturn = $_SERVER["HTTP_CLIENT_IP"];
    	} else {
    		if ($FormatIpForDatabaseInput) $sReturn = FormatStringForDatabaseInput($sReturn, 1);
    		return $sReturn;
    	}
    	$ips = preg_split('/[, ]/', $sReturn);
    	foreach ($ips as $ip) {
    		if (preg_match('/^(\d{1,3}\.){3}\d{1,3}$/s', $ip)
    			&& !isPrivateIP($ip) ) {
    			$sReturn = $ip;
    		}
    	}
    	if ($FormatIpForDatabaseInput) $sReturn = FormatStringForDatabaseInput($sReturn, 1);
    	return $sReturn;
    }
    function isPrivateIP($ip) {
            $privates = array ("127.0.0.0/24", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16");
            foreach ( $privates as $k ) {
                    list($net,$mask)=split("/",$k);
                    if (isIPIn($ip,$net,$mask)) {
                            return true;
                    }
            }
            return false;
    }

    I make no promises on this code working. I have not tested it, and so it may not work. But that's basically what you need to do if this other guy's functions work properly.
  • Several of my forum member's come in through the same IP as well. Does that suggest that your built-in IP function doesn't quite work either?
  • MarkMark Vanilla Staff
    Well, it's all about proxies and networking. On a past forum I ran, I had four or five guys who all came in on the same IP address. I later found out it was because they were all working from the same office, and going out to the net on the same ip. There's nothing wrong with my function, it just hands you the net-accessable ip address of a user. In the case of these five guys, using that proxy function above wouldn't make a difference, because they weren't going through a proxy.
  • Hmm, well i know all of these are accessing from seperate places. One of them's me and I know nobody else is using my connection as well.
  • edited September 2005
    It's WORKING :))


    Thank you :))function isIPIn($ip,$net,$mask) { $lnet=ip2long($net); $lip=ip2long($ip); $binnet=str_pad( decbin($lnet),32,"0","STR_PAD_LEFT" ); $firstpart=substr($binnet,0,$mask); $binip=str_pad( decbin($lip),32,"0","STR_PAD_LEFT" ); $firstip=substr($binip,0,$mask); return(strcmp($firstpart,$firstip)==0); } function GetRemoteIp($FormatIpForDatabaseInput = "0") { $FormatIpForDatabaseInput = ForceBool($FormatIpForDatabaseInput, 0); $sReturn = ForceString(@$_SERVER['REMOTE_ADDR'], ""); if (strlen($sReturn) > 20) $sReturn = substr($sReturn, 0, 19); if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) { $sReturn = $_SERVER["HTTP_X_FORWARDED_FOR"]; } else if (isset($_SERVER["HTTP_CLIENT_IP"])) { $sReturn = $_SERVER["HTTP_CLIENT_IP"]; } else { if ($FormatIpForDatabaseInput) $sReturn = FormatStringForDatabaseInput($sReturn, 1); return $sReturn; } $ips = preg_split('/[, ]/', $sReturn); foreach ($ips as $ip) { if (preg_match('/^(\d{1,3}\.){3}\d{1,3}$/s', $ip) && !isPrivateIP($ip) ) { $sReturn = $ip; } } if ($FormatIpForDatabaseInput) $sReturn = FormatStringForDatabaseInput($sReturn, 1); return $sReturn; } function isPrivateIP($ip) { $privates = array ("127.0.0.0/24", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"); foreach ( $privates as $k ) { list($net,$mask)=split("/",$k); if (isIPIn($ip,$net,$mask)) { return true; } } return false; }</pre>
  • You'd need to dig through the code from where you found the first function and find that one too. It doesnt look standard. Btw ben, are the other people on the same ip? I know me and chrissy (par exemple) are on the same isp cache and therefore use the same 'ip' besides being 2 miles away from each other.
  • I'm afraid I have no idea mini.
  • Well it seems like a more common possibility than your server itself being behind a proxy - i cant quite see why this would be the case unless it's some sort of firewalling system. You could try using www.whatismyip.com (i think..google it) and requesting your users do the same and see what it comes up with.
  • MarkMark Vanilla Staff
    cheers @ arthos :)
  • Yep, all of my users are being logged as the proxy most of the time, instead of their actual IP address.
This discussion has been closed.