7

我的应用程序会跟踪登录该站点的用户的 IP 地址。跟踪在常规 Web 服务器上运行良好(我们在 hostgator 上),但是当我们切换到 PaaS 平台(pagodabox)时,似乎开始跟踪奇怪的 IP 地址。在与 pagodabox 支持人员交谈后,他们告诉我 IPs codeigniter 正在接收pagodabox 的负载均衡器/路由器的 IP 并获取用户的实际 IP 地址,我必须使用HTTP_X_FORWARDED_FOR

我正在使用 codeigniter 的输入类函数$this->input->ip_address()来检索用户的 IP。我查看了该功能,发现它们具有某种功能来检索 HTTP_X_FORWARDED_FORIP 值,但我不知道如何使用它。我必须在配置中更改/添加一些东西吗?

编辑:在一些用户指出我应该在负载均衡器的 IP 地址列表中添加的位置之后,出现了一个新问题:如果 IP 列表经常更改,我该怎么办?(即没有静态IP,全是动态的)

4

7 回答 7

12

我确定您现在已经解决了这个问题,但我想我会发布正确的答案以供将来参考。我遇到了同样的问题(在 AWS 上使用负载均衡器和 CodeIgniter 应用程序。)正如您所指出的,使用 HTTP_X_FORWARDED_FOR 标头在负载均衡器或其他分布式环境后面获取正确的 IP 很容易。问题是我们如何在 CodeIgniter 中正确实现这个解决方案?正如前面的答案所指出的:编写自己的 IP 函数。问题在于,如果在整个应用程序中调用 ip_address() 会怎样?重写该函数不是更好吗(使用查看正确标题的函数)?CodeIgniter 有一个方便的机制,很方便:

解决方案是扩展 CodeIgniter Input 类,方法是在 /application/core 中创建一个名为 MY_Input.php 的新类文件(MY_ 是扩展的可配置前缀,您可以在配置文件中更改它)。使用扩展,您可以创建与原始类方法同名的函数,而无需破坏任何内容,也无需编辑核心文件。CodeIgniter 将只使用您的新方法。您的扩展输入类将如下所示:

class MY_Input extends CI_Input {

    function __construct()
    {
        parent::__construct();
    }
    //Overide ip_address() with your own function
    function ip_address() 
    {
        //Obtain the IP address however you'd like, you may want to do additional validation, etc..
        $correct_ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];  
        return $correct_ip_address;
    }
}

通过这种方式,我们在不破坏框架的情况下更改了核心行为,并且整个应用程序中对 ip_address() 的现有调用现在将使用您的方法。

关于处理链中的其他 IP,如果您只对客户端 IP 感兴趣,那应该没关系。至少使用 AWS 负载均衡器,HTTP_X_FORWARDED_FOR 标头似乎总是包含正确的客户端 IP。

于 2013-04-28T16:28:03.367 回答
9

Oliver 的解决方案有效,但在某些情况下,如果您知道正在使用的代理 IP 地址,则最好使用以下内容。编辑您的 application/config/config.php 文件以包含以下内容:

$config['proxy_ips'] = '1.2.3.4, 2.3.4.5';

另请注意,标头信息通常不可靠,不应用于安全敏感目的。例如,限制管理员用户仅使用某些白名单 IP 地址的情况并不少见。

于 2013-12-19T10:00:58.823 回答
3
<?php 
function getIPfromXForwarded() 
{ 
    $ipString = @getenv("HTTP_X_FORWARDED_FOR"); 
    $addr     = explode(",",$ipString); 

    return $addr[sizeof($addr)-1]; 
} 
?> 

尝试类似的东西。看看它是否有效。用法:

<? echo getIPfromXForwarded(); ?>
于 2013-01-23T23:08:25.770 回答
3

在您的情况下,您可以将指定的负载平衡器 IP 添加到$config['proxy_ips']( application/config/config.php) 中,例如:

$config['proxy_ips'] = ['192.168.1.2'];

动态代理IP:

根据您的动态 IP 问题,您可以屏蔽 Load-Balancer 网络的 IP 范围,例如:

 $config['proxy_ips'] = '192.168.1.0/24';

掩码功能可以在 Codeigniter 3 中使用


获取IP方法:

$this->input->ip_address();

While$this指的是 CI 实例。

此方法会考虑 $config['proxy_ips'] 设置,并将返回报告的 HTTP_X_FORWARDED_FOR、HTTP_CLIENT_IP、HTTP_X_CLIENT_IP 或 HTTP_X_CLUSTER_CLIENT_IP 地址以获得允许的 IP 地址。

于 2017-07-07T15:07:08.130 回答
2

我知道有一个很好的答案与您的问题相关并且被您接受,但对于未来的用户,我正在分享一个在所有情况下都对我完美运行的功能。

 public function ip()
    {
        $ipaddress = '';
        if ($_SERVER['HTTP_CLIENT_IP'])
            $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
        else if($_SERVER['HTTP_X_FORWARDED_FOR'])
            $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
        else if($_SERVER['HTTP_X_FORWARDED'])
            $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
        else if($_SERVER['HTTP_FORWARDED_FOR'])
            $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
        else if($_SERVER['HTTP_FORWARDED'])
            $ipaddress = $_SERVER['HTTP_FORWARDED'];
        else if($_SERVER['REMOTE_ADDR'])
            $ipaddress = $_SERVER['REMOTE_ADDR'];
        else
            $ipaddress = 'UNKNOWN';
        echo $ipaddress ;
     }
于 2015-05-04T09:53:43.643 回答
2

我遇到了 Thava 解决方案的一个版本,该版本非常适用于负载均衡器 IP 可以更改(例如 AWS)并且仍然在本机利用 CI 配置文件的情况。当您知道您在 LB 后面运行时,您可以将 config.php 修改为:

$config['proxy_ips'] = isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : '';

知道 REMOTE_ADDR 将永远是当前的 LB。

感谢 Eric Brown 在这里https://expressionengine.com/forums/archive/topic/185751/amazon-load-balancing-and-codeigniter-configproxy_ips#925678

于 2017-06-21T14:42:21.500 回答
1

我在工作中遇到了同样的情况,除了 IP 并不是真正的“动态”,而是管理代理和负载平衡器的“基础设施人员”出于未公开的原因经常更改它们。所以我们不得不协商,我们想出了一个解决方案,在他们的配置/配置管理工具中设置一个钩子,以便在某个地方(在运行我们的 Apache/PHP 的用户可以访问的文件夹中)写入一个配置文件。

因此,我使用 CI 挂钩在系统引导程序上读取该文件,以更改我的应用程序配置,更新代理 IP 列表、缓存路径、cookie 域等值。

于 2014-11-06T18:53:19.847 回答