[php] $_SERVER["REMOTE_ADDR"] gives server IP rather than visitor IP

I'm trying to track IP addresses of visitors. When using $_SERVER["REMOTE_ADDR"], I get the server's IP address rather than the visitor's. I tried this on multiple machines at multiple locations and they all resulted in the exact same IP. Is there some PHP/server settings that could be affecting this?

This question is related to php

The answer is


Look no more for IP addresses not being set in the expected header. Just do the following to inspect the whole server variables and figure out which one is suitable for your case:

print_r($_SERVER);

With PHP 7.4 I do it like this:

$ipaddress = '';
if (isset($_SERVER['REMOTE_ADDR']))
    $ipaddress = $_SERVER['REMOTE_ADDR'];
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
    $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_X_FORWARDED']))
    $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
    $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_FORWARDED']))
    $ipaddress = $_SERVER['HTTP_FORWARDED'];
else if(isset($_SERVER['HTTP_CLIENT_IP']))
    $ipaddress = $_SERVER['HTTP_CLIENT_IP'];

But keep in mind that REMOTE_ADDR is the only reliable IP address that you can get. All other values can easily be manipulated. This is theoretically also possible for REMOTE_ADDRESS, but that would require to spoof the IP address.


When using $_SERVER["REMOTE_ADDR"], I get the server's IP address rather than the visitor's.

Then something is wrong, or odd, with your configuration.

  • Are you using some sort of reverse proxy? In that case, @simshaun's suggestion may work.

  • Do you have anything else out of the ordinary in your web server config?

  • Can you show the PHP code you are using?

  • Can you show what the address looks like. Is it a local one, or a Internet address?


Replacing:

$_SERVER["REMOTE_ADDR"];

With:

$_SERVER["HTTP_X_REAL_IP"];

Worked for me.


If you are using Cloudflare then this is always the Cloudflare IP address from the node which is serving you.

In this case you get the real IP address from the $_SERVER['HTTP_FORWARDED_FOR'] entry as described in the the other answers.


Try this

$_SERVER['HTTP_CF_CONNECTING_IP'];

instead of

$_SERVER["REMOTE_ADDR"];

PHP 7.0 $_SERVER varibales have changed. var_dump it and see how it fits your reqs.

some of them giving remote details are, REMOTE_ADDR HTTP_X_FORWARDED_FOR HTTP_CF_CONNECTING_IP HTTP_CF_IPCOUNTRY


REMOTE_ADDR can not be trusted.

Anyway, try

$ipAddress = $_SERVER['REMOTE_ADDR'];
if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
    $ipAddress = array_pop(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
}

Edit: Also, does your server's router have port forwarding enabled? It may be possible that it's messing with the packets.

Security warning: REMOTE_ADDR can be fully trusted! It comes from your own webserver and contains the IP that was used to access it. You don't even need to quote() it for SQL inserts.
But HTTP_X_FORWARDED_FOR is taken directly from the HTTP headers, it can contain the picture of a cat, malicious code, any content. Treat it like that, never trust it.


$_SERVER['REMOTE_ADDR'] gives the IP address from which the request was sent to the web server. This is typically the visitor's address, but in your case, it sounds like there is some kind of proxy sitting right before the web server that intercepts the requests, hence to the web server it appears as though the requests are originating from there.