Oli Warner About Contact Oli on Twitter Subscribe

Getting The Real IP Of Your Users

Monday, 22 May 2006 asp csharp coldfusion ip java jsp perl php programming vb.net webdev

There are a lot of sites around the internet that try and get your IP address. Most of their reasons are legitimate. For example Google Adsense will log your IP to see where the user clicking the advert is from (and kick you off if its the same IP you logged into that account with).

However, there are some sites that try to look at your IP for various reasons but do it wrong. Rapidshare is a beatifully painful example of this. If you’re on an ISP that uses a transparent proxy, RapidShare will log the proxy address instead of the actual account IP. As they limit the downloading on a per-IP basis, that means everyone using that ISP, going through that proxy, has the same IP to Rapidshare, meaning the limit to how much you download is split among those users.

What I’m saying here is, if you’re going to do your own IP lookups for whatever reason, do them correctly. My initial code here was in VB.net but since I have translated what its doing to the most popular server-side languages. As its based on the server variables, rather than the code’s process, its quite easy to port to something else if you need to.

The lookup that these “incorrect” sites are doing is something like this:

Request.ServerVariables("REMOTE_ADDR")

What then need to be doing is comparing the HTTP_X_FORWARDED_FOR variable against it, to check that there isn’t a non-transparent proxy in the way. Like so:

' Look for a proxy address first
Dim _ip As String = Request.ServerVariables("HTTP_X_FORWARDED_FOR")

' If there is no proxy, get the standard remote address
If (_ip = "" Or _ip.ToLower = "unknown") Then _
_ip = Request.ServerVariables("REMOTE_ADDR")

This doesnt help people that are limited to (or otherwise) on anonymous proxies. They will hide the forwarding address (like they’re supposed to) and therefore the lookup will ONLY get the proxy’s address. Some ISPs do this by default to “protect” their users… Its just retarded. If you ISP does this, and you’ve been wondering why RS or other sites don’t work… Now you know.

If you want to check against an existing “wrong site”, try IP Chicken. It will return an incorrect value (eg the proxy). WhatsMyIP.org is one that will look through the proxy and should give you the correct IP.

Here are some more examples in other languages:

C#

// Look for a proxy address first
String _ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

// If there is no proxy, get the standard remote address
If (_ip == "" || _ip.ToLower == "unknown")
_ip = Request.ServerVariables["REMOTE_ADDR"];

PHP

Based on code from OxyScripts.

function GetUserIP() {

if (isset($_SERVER)) {

if (isset($_SERVER["HTTP_X_FORWARDED_FOR"]))
return $_SERVER["HTTP_X_FORWARDED_FOR"];

if (isset($_SERVER["HTTP_CLIENT_IP"]))
return $_SERVER["HTTP_CLIENT_IP"];

return $_SERVER["REMOTE_ADDR"];
}

if (getenv('HTTP_X_FORWARDED_FOR'))
return getenv('HTTP_X_FORWARDED_FOR');

if (getenv('HTTP_CLIENT_IP'))
return getenv('HTTP_CLIENT_IP');

return getenv('REMOTE_ADDR');
}

Java and JSP

String ipaddress = request.getHeader("HTTP_X_FORWARDED_FOR");

if (ipaddress == null)
ipaddress = request.getRemoteAddr();

ASP/VBScript

ipaddress = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
if ipaddress = "" then
	ipaddress = Request.ServerVariables("REMOTE_ADDR")
end if

ColdFusion

<CFCOMPONENT>
	<CFIF #CGI.HTTP_X_Forwarded_For# EQ "">
		<CFSET ipaddress="#CGI.Remote_Addr#">
	<CFELSE>
		<CFSET ipaddress="#CGI.HTTP_X_Forwarded_For#">
	</CFIF>
</CFCOMPONENT>

Perl

$ip = $req->header('Client-IP') || $req->header('Remote-Addr');
if ($req->header('X-Forwarded-For')) {
$proxy = $ip;
$ip = $req->header('X-Forwarded-For');
}

If you know anymore, just ping them in my general direction and they can be added.