Problem getting real IP in php
I am using this to get real IP but I take empty from $_SERVER['HTTP_CLIENT_IP']
, I take not empty only from $_SERVER['REMOTE_ADDR']
.But I dont need the IP of proxy, I need the real ip of computers using some intranet. Can I get it? When $_SERVER['HTTP_CLIENT_IP']
does not return empty?
function getRealIpAddr()
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) //check ip from share internet
{
$ip=$_SERVER['HTTP_CLI开发者_开发知识库ENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) //to check ip is pass from proxy
{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}
The functions on this page are not reliable.
The only reliable IP from $ip = $_SERVER["REMOTE_ADDR"];
Otherwise anyone could fake his IP address by sending the CLIENT_IP header for example.
This Firefox Addon can help you send custom headers. Sending the CLIENT_IP=x.x.x.x header to a server running any of the functions on this page, would mean that clients can choose any IP they want...
HTTP_CLIENT_IP is not specified in the $_SERVER
documentation... It may be available as an environmental variable (under $_ENV
), but it's not in $_SERVER
. The method you're using (going to HTTP_X_FORWARDED_FOR
, then falling back on REMOTE_ADDR
) is about the best you can do...
What you are doing is about all that you can do to get this information. I'm not 100% sure what you are saying, but try the 2 methods below to see if they give you different/better info.
Try:
$headers = apache_request_headers();
echo $headers['X-Forwarded-For'];
Or:
$ip_list = getenv('HTTP_X_FORWARDED_FOR');
echo $ip_list;
It's not possible to resolve this 100% of the time, but this would get you about as close as possible:
if($_SERVER["HTTP_X_FORWARDED_FOR"]) {
if($_SERVER["HTTP_CLIENT_IP"]) {
$proxy = $_SERVER["HTTP_CLIENT_IP"];
} else {
$proxy = $_SERVER["REMOTE_ADDR"];
}
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
} else {
if($_SERVER["HTTP_CLIENT_IP"]) {
$ip = $_SERVER["HTTP_CLIENT_IP"];
} else {
$ip = $_SERVER["REMOTE_ADDR"];
}
}
echo "IP resolved to: ".$ip." (could still be a proxy IP though)<br>";
if($proxy) echo "Proxied through: ".$proxy;
I think that this is one of the best ways to get the real ip
by: oliver leuyim angel
function getRealIP(){
if( $_SERVER['HTTP_X_FORWARDED_FOR'] != '' ) {
$client_ip = ( !empty($_SERVER['REMOTE_ADDR']) ) ? $_SERVER['REMOTE_ADDR'] :(( !empty($_ENV['REMOTE_ADDR']) ) ? $_ENV['REMOTE_ADDR'] : "unknown" );
// los proxys van añadiendo al final de esta cabecera
// las direcciones ip que van "ocultando". Para localizar la ip real
// del usuario se comienza a mirar por el principio hasta encontrar
// una dirección ip que no sea del rango privado. En caso de no
// encontrarse ninguna se toma como valor el REMOTE_ADDR
$entries = split('[, ]', $_SERVER['HTTP_X_FORWARDED_FOR']);
reset($entries);
while (list(, $entry) = each($entries)){
$entry = trim($entry);
if ( preg_match("/^([0-9]+.[0-9]+.[0-9]+.[0-9]+)/", $entry, $ip_list) ){
// http://www.faqs.org/rfcs/rfc1918.html
$private_ip = array(
'/^0./',
'/^127.0.0.1/',
'/^192.168..*/',
'/^172.((1[6-9])|(2[0-9])|(3[0-1]))..*/',
'/^10..*/');
$found_ip = preg_replace($private_ip, $client_ip, $ip_list[1]);
if ($client_ip != $found_ip){
$client_ip = $found_ip;
break;
}
}
}
} else {
$client_ip = ( !empty($_SERVER['REMOTE_ADDR']) ) ? $_SERVER['REMOTE_ADDR'] : ( ( !empty($_ENV['REMOTE_ADDR']) ) ? $_ENV['REMOTE_ADDR'] : "unknown" );
if ($client_ip == 'unknown') {
if (!empty($_SERVER['HTTP_CLIENT_IP'])) //check ip from share internet
{
$ip=$_SERVER['HTTP_CLIENT_IP'];}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) //to check ip is pass from proxy
{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else {
$ip=$_SERVER['REMOTE_ADDR'];
}
$client_ip = $ip;
}
}
return $client_ip;
}
Anonymizing proxies will not populate HTTP_X_FORWARDED_FOR or REMOTE_ADDR, or will populate them using their own IP addresses, not the client IP address.
If you are working on something where you absolutely must identify the ip address of the gateway the client computer is using and are having to deal with situations where anonymizing proxies are being used, then you will have to come up with something else. I have in the past, used flash to make a socket connection to the server and send a unique key provided to the flash via params.
Be aware though that this is not a perfect solution. But in the case I was using it, to prevent cheating on a voting app, it worked fine. No flash, no vote. Similar things could be done with Java applets, silverlight, etc. Any client tech where you can specify the port that you talk to the server with. You would not want to use 80, 8080, etc, any of the common proxy ports.
精彩评论