Alright, I have an small authentication issue. My web service allows to connect to my API over HTTP with a username and password, but this connection can also be restricted to a specific IP address.
This means that the $_SERVER['REMOTE_ADDR']
can be incorrect. I already know that any IP information can never truly be relied upon - I have the restriction only in an attempt to add another layer of security.
If this is the general overview of a request to my web server:
clientSERVER => clientPROXY => myPROXY => mySERVER
Then this means that mySERVER shows REMOTE_ADDR
of myPROXY instead of that of the client and sends the actual IP of the client as HTTP_X_FORWARDED_FOR
.
To overcome this, my web service has a list of 'trusted proxy' IP addresses and if REMOTE_ADDR
is from one of those trusted IP addresses, then it tells my web service that the actual IP address is the value of HTTP_X_FORWARDED_FOR
.
Now the problem is with clientPROXY. This means that (quite often) mySERVER gets HTTP_X_FORWARDED_FOR
value that has multiple IP addresses. According to HTTP_X_FORWARDED_FOR
documentation, the value is a comma-separated list of IP addresses where the first IP is that of the actual true client and every other IP address is that of a proxy.
So, if HTTP_X_FORWARDED_FOR
has multiple values and my service is IP restricted, do I have to check the 'last' value of HTTP_X_FORWARDED_FOR
against my allowed IP list and just ignore the actual client IP?
I assume that in a system, where I have to set the list of allowed IP addresses, the whitelisted IP address should be that of a proxy and not an IP that is behind the proxy (since that could be some localhost IP and change frequently).
And what of HTTP_CLIENT_IP
?
You can use this function to get proper client IP:
public function getClientIP(){
if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)){
return $_SERVER["HTTP_X_FORWARDED_FOR"];
}else if (array_key_exists('REMOTE_ADDR', $_SERVER)) {
return $_SERVER["REMOTE_ADDR"];
}else if (array_key_exists('HTTP_CLIENT_IP', $_SERVER)) {
return $_SERVER["HTTP_CLIENT_IP"];
}
return '';
}