【问题标题】:How can I get the user's IP while using both CloudFlare and MaxMind's GeoIP with mod_geoip?如何在使用 CloudFlare 和 MaxMind 的 GeoIP 和 mod_geoip 时获取用户的 IP?
【发布时间】:2011-09-22 04:34:24
【问题描述】:

CloudFlare 从原始 IP 提供用户所在的国家/地区,但我需要城市级别的位置,因此我使用 mod_geoip Apache 脚本添加了 MaxMind 的 GeoCityLite。

现在的问题是在 php 变量中获取 IP,我正在使用类似的东西

$country = apache_note("GEOIP_COUNTRY_CODE");

这很好,但是 mod_geoip 使用的 IP 是 CloudFlare DNS,而不是最终用户。 CloudFlare 提供服务器变量 HTTP_CF_CONNECTING_IP 以使用最终用户 IP,但我如何在 mod_geoip 中使用该变量/IP?

这可以用htaccess中的几行来完成吗?

编辑:我有一个使用 php API for geoip 的解决方法,这很简单,但是使用 php api 的 apache 查找的基准要好得多,所以我宁愿找到这个解决方案。

【问题讨论】:

    标签: apache .htaccess geolocation geoip cloudflare


    【解决方案1】:

    在调用 geoip 之前执行此操作:

    $_SERVER['REMOTE_ADDR'] = isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : $_SERVER['REMOTE_ADDR'];
    

    【讨论】:

    • 谢谢!这很有帮助!
    • 工作得非常完美,我正忙着想弄清楚为什么用户在设置 cloudflare 后无法登录。谢谢!
    【解决方案2】:

    我在尝试让 Larvel TrustedProxy 与 CloudFlare 和 AWS 的 EC2 弹性负载均衡器一起工作时遇到了困难。它假设您只使用 1 个代理,而不是 2 个并且不能正常工作。我最终只是跳过了所有受信任的代理内容并制作了一个简单的中间件,如果使用 CloudFlare,无论您前面是否有另一个负载均衡器,它都会设置正确的 IP 地址和协议。

    CloudFlare 通过 HTTP 标头传递有关客户端的信息:https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-CloudFlare-handle-HTTP-Request-headers-

    我们同时采用客户端 IP 和客户端 HTTP/HTTPS 协议,并将其设置到 $request->server 属性中。

    ======

    app/Http/Middleware/UseCloudFlareHeaders.php

    <?php namespace App\Http\Middleware;
    
    use Closure;
    
    class UseCloudFlareHeaders
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request $request
         * @param  \Closure $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
            //if CloudFlare request, set correct protocol and proper client ip address
            $HTTP_CF_VISITOR = $request->server->get('HTTP_CF_VISITOR');
            $HTTP_CF_CONNECTING_IP = $request->server->get('HTTP_CF_CONNECTING_IP');
    
            if ($HTTP_CF_VISITOR and json_decode($HTTP_CF_VISITOR)->scheme == 'https') {
                $request->server->set('HTTPS', 'on');
            }
    
            if ($HTTP_CF_CONNECTING_IP) {
                $request->server->set('REMOTE_ADDR', $HTTP_CF_CONNECTING_IP);
            }
    
            return $next($request);
        }
    }
    

    app/Http/Kernal.php

    protected $middleware = [
        //add this to your middleware...
        \App\Http\Middleware\UseCloudFlareHeaders::class
    ];
    

    如果有人知道更好的方法,请告诉我们。

    【讨论】:

    • 这让它变得简单,不需要 TrustedProxy。谢谢。
    【解决方案3】:

    Cloudflare 有一个 Apache 扩展 mod_cloudflare (https://github.com/cloudflare/CloudFlare-Tools),我相信它会用正确的 IP 替换 Cloudflare IP。

    如果它在 mod_geoip 之前加载,它可能会根据 mod_geoip 的工作方式工作。

    不过,您需要 root 访问权限才能安装 mod_cloudflare。

    【讨论】:

      【解决方案4】:

      要获取存储在 $ip 等变量中的用户 IP 地址,您可以通过以下几种方式进行:

      $ip = $_SERVER['REMOTE_ADDR'];
      

      $ip = getenv('REMOTE_ADDR');
      

      【讨论】:

      • 不,这必须在 apache conf 文件或 htaccess 中设置。以某种方式使 mod_geoip.c 使用变量 HTTP_CF_CONNECTING_IP 而不是 REMOTE_ADDR(REMOTE_ADDR 目前读取 DNS 代理服务器,HTTP_CF_CONNECTING_IP 是解决方法)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 2012-01-09
      • 2019-02-10
      • 2014-06-29
      • 1970-01-01
      相关资源
      最近更新 更多