REMOTE_ADDR

2009-11-21

It's usually rather important to get the IP of the client who connected to your server through PHP. Still, there seems to be no clarity regarding the variables that cover these details.

I've investigated this a while ago and only found some reference about $_SERVER['REMOTE_ADDR'] in some cases being a comma delimited list. Where PHP would put in the IP's in order of relevance.

The reason I had to dig this up again is that I've encountered an unexpected value to the IP. It appears that some proxyservers mask the original IP by sending "unknown", rather than the IP. A proxy sometimes sends this just to make clear that, yes there's an original sender but no, he's not telling you who.

PHP not offering a sanatized way of getting the "requesting IP", even if it's just all PHP knows, is very bad in my oppinion.

I don't even know what the $_SERVER['REMOTE_ADDR'] will return with an IPv6 address at this point. Search engines are so cluttered it's impossible to decently find this information.

So, here are my findings:

$_SERVER['REMOTE_ADDR'] will contain the IP that executed the current request. In the case of proxy, this can sometimes be an comma delimited list, with the most important/likely hit up front. Usually, this is just a regular IPv4 IP though. I don't know what IPv6 will do, but I expect an unsanitized IPv6 notation will emerge from it.

$_SERVER['HTTP_X_FORWARDED_FOR'] can be the address the connected proxy server is making the request for. HOWEVER, this is a HTTP header and the address can easily be spoofed. That's what it's there for, to be external input. You can basically never trust it. But this is it's intended meaning. When supplied, the value can be a comma delimited list, listing several IP's if the request went through several proxies. Can contain 'unknown'.

$_SERVER['HTTP_CLIENT_IP'] is pretty much like 'HTTP_X_FORWARDED_FOR, except it should just contain the original IP. Can contain 'unknown', for example when one proxy in the chain is anonymous and wants to make this clear.

In my oppinion, the best way to get the connected client IP, even if it's the proxy, is to check the REMOTE_ADDR. See the following:

Code: (PHP)
$ip = $_SERVER['REMOTE_ADDR'];
if (strstr($ip, ', ')) {
$ips = explode(', ', $ip);
$ip = $ips[0];
}

Now I'm not certain whether REMOTE_ADDR can actually contain "unknown", right now I'm guessing not.

For security, always use the remote_addr. You can't trust the HTTP headers. For other logging purposes which aren't very security sensitive, try to validate an IP from the headers and use that, if one is found.

Hope it helps ya...