获取用户IP - 负载平衡器后面的Drupal网站

时间:2013-05-17 21:52:06

标签: php drupal drupal-7 load-balancing

如果Drupal(7.17)网站落后于负载均衡器,是否有任何解决方法可以获得实际的用户IP ? 它总是返回负载均衡器的IP地址。

3 个答案:

答案 0 :(得分:2)

Drupal有函数ip_address()

function ip_address() {
 $ip_address = &drupal_static(__FUNCTION__);

 if (!isset($ip_address)) {
   $ip_address = $_SERVER['REMOTE_ADDR'];

     if (variable_get('reverse_proxy', 0)) {
       $reverse_proxy_header = variable_get('reverse_proxy_header', 'HTTP_X_FORWARDED_FOR');

       if (!empty($_SERVER[$reverse_proxy_header])) {
         // If an array of known reverse proxy IPs is provided, then trust
         // the XFF header if request really comes from one of them.
         $reverse_proxy_addresses = variable_get('reverse_proxy_addresses', array());

         // Turn XFF header into an array.
         $forwarded = explode(',', $_SERVER[$reverse_proxy_header]);

         // Trim the forwarded IPs; they may have been delimited by commas and spaces.
         $forwarded = array_map('trim', $forwarded);

         // Tack direct client IP onto end of forwarded array.
         $forwarded[] = $ip_address;

         // Eliminate all trusted IPs.
         $untrusted = array_diff($forwarded, $reverse_proxy_addresses);

         // The right-most IP is the most specific we can trust.
         $ip_address = array_pop($untrusted);
       }
     }
   }

 return $ip_address;
}

答案 1 :(得分:1)

您是否尝试使用PHP获取IP,如下所示:

if ($_SERVER["HTTP_X_FORWARDED_FOR"]) {
    $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
}
else {
    $ip = $_SERVER["REMOTE_ADDR"];
}

答案 2 :(得分:1)

你确实需要X-Forwarded-For标题,但天真的方法是错误的,因为X-Forwarded-For can contain multiple IP addresses代表途中的代理。

这是你真正想要的(Ideone):

<?php
// Don't use this function directly to parse arbitrary headers, since it
// assumes that the headers you're passing in are associated with the
// current $_SERVER variable.
function get_client($headers) {
    if (isset($headers['HTTP_X_FORWARDED_FOR'])) {
        return explode(', ', $headers['HTTP_X_FORWARDED_FOR'])[0];
    }
    else {
        return $_SERVER['REMOTE_ADDR'];
    }
}

// You'd want to do this on a server, but not on ideone:
// $headers = getallheaders();
$headers = array('HTTP_X_FORWARDED_FOR' => 'client, proxy1, proxy2');
echo "Client 1: " . get_client($headers) . "\n";

$headers = array('HTTP_X_FORWARDED_FOR' => 'client');
echo "Client 2: " . get_client($headers) . "\n";

// $_SERVER['REMOTE_ADDR'] is blank on ideone but works on servers:
$headers = array();
echo "Client 3: " . get_client($headers) . "\n";
?>

另请注意,X-Forwarded-For可能很容易被欺骗,因此您不应仅在安全上下文中依赖它。正确的方法,例如,禁令清单还需要了解$_SERVER['REMOTE_ADDR'];