I do get track the "real" IP of an user, if he has an proxy wich sends the header of the real IP... does any of have a better solution, or even more headers?
Since this function is used very often in the script, it has to be very fast, and it does not seem in that constellation :/
A few suggestions I came up with, but could not realise:
===
function get_real_ip()
{
$proxy_headers = array(
'CLIENT_IP',
'FORWARDED',
'FORWARDED_FOR',
'FORWARDED_FOR_IP',
'HTTP_CLIENT_IP',
'HTTP_FORWARDED',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED_FOR_IP',
'HTTP_PC_REMOTE_ADDR',
'HTTP_PROXY_CONNECTION',
'HTTP_VIA',
'HTTP_X_FORWARDED',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED_FOR_IP',
'HTTP_X_IMFORWARDS',
'HTTP_XROXY_CONNECTION',
'VIA',
'X_FORWARDED',
'X_FORWARDED_FOR'
);
foreach($proxy_headers as $proxy_header)
{
if(isset($_SERVER[$proxy_header]) && preg_match("/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/", $_SERVER[$proxy_header])) /* HEADER ist gesetzt und dies ist eine gültige IP */
{
return $_SERVER[$proxy_header];
}
else if(stristr(',', $_SERVER[$proxy_header]) !== FALSE) /* Behandle mehrere IPs in einer Anfrage(z.B.: X-Forwarded-For: client1, proxy1, proxy2) */
{
$proxy_header_temp = trim(array_shift(explode(',', $_SERVER[$proxy_header]))); /* Teile in einzelne IPs, gib die letzte zurück und entferne Leerzeichen */
if(($pos_temp = stripos($proxy_header_temp, ':')) !== FALSE) $proxy_header_temp = substr($proxy_header_temp, 0, $pos_temp); /* Entferne den Port */
if(preg_match("/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/", $proxy_header_temp) return $proxy_header_temp;
}
}
return $_SERVER['REMOTE_ADDR'];
}
Generally HTTP proxy servers, upon receiving a request from a client/user, append a new field (X-Forwarded-For) in the HTTP header and subsequently forward the request to the web-server. This X-Forwarded-For field has the client's IP address. Hence, by analyzing this field, a website can figure out the real IP address.
$_SERVER['REMOTE_ADDR'] Returns the IP address from where the user is viewing the current page. $_SERVER['REMOTE_HOST'] Returns the Host name from where the user is viewing the current page.
If the proxy sends a header then you can fetch the original IP of the client. If the proxy doesn't, then you can't. Unfortunately (Or maybe fortunately depending on your perspective) it's as simple as that.
What I did at our intranet, is redirect "intranet.mydomain.com" to "intranet" on the webserver, the latter doesn't use the proxy due to out internal network/DNS configuration ... Don't know what you want to do, but this may be useful.
You can also set an exclude list in the browser...
the regex validation would fail for ipv6 addresses; so I would rather remove that (or try to find a better RegEX).
also stripos($proxy_header_temp, ':')
would lead to a not expected behaivour for example for "::1" (localhost, ipv6).
my suggestion with mentioned modifications:
function getIp()
{
$proxy_headers = array(
'CLIENT_IP',
'FORWARDED',
'FORWARDED_FOR',
'FORWARDED_FOR_IP',
'HTTP_CLIENT_IP',
'HTTP_FORWARDED',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED_FOR_IP',
'HTTP_PC_REMOTE_ADDR',
'HTTP_PROXY_CONNECTION',
'HTTP_VIA',
'HTTP_X_FORWARDED',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED_FOR_IP',
'HTTP_X_IMFORWARDS',
'HTTP_XROXY_CONNECTION',
'VIA',
'X_FORWARDED',
'X_FORWARDED_FOR'
);
$regEx = "/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/";
foreach ($proxy_headers as $proxy_header) {
if (isset($_SERVER[$proxy_header])) {
/* HEADER ist gesetzt und dies ist eine gültige IP */
return $_SERVER[$proxy_header];
} else if (stristr(',', $_SERVER[$proxy_header]) !== false) {
// Behandle mehrere IPs in einer Anfrage
//(z.B.: X-Forwarded-For: client1, proxy1, proxy2)
$proxy_header_temp = trim(
array_shift(explode(',', $_SERVER[$proxy_header]))
); /* Teile in einzelne IPs, gib die letzte zurück und entferne Leerzeichen */
// if IPv4 address remove port if exists
if (preg_match($regEx, $proxy_header_temp)
&& ($pos_temp = stripos($proxy_header_temp, ':')) !== false
) {
$proxy_header_temp = substr($proxy_header_temp, 0, $pos_temp);
}
return $proxy_header_temp;
}
}
return $_SERVER['REMOTE_ADDR'];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With