如何在使用CloudFlare和MaxMind的GeoIP和mod_geoip时获取用户的IP?

时间:2011-06-24 16:35:38

标签: apache .htaccess geolocation geoip cloudflare

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

现在的问题是在php变量中获取IP,我正在使用像

这样的东西
$country = apache_note("GEOIP_COUNTRY_CODE");

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

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

编辑:我有一个使用php API进行geoip的解决方法,这很容易,但使用php api的apache查找的基准测试要好得多,所以我宁愿找到这个解决方案。

4 个答案:

答案 0 :(得分:17)

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

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

答案 1 :(得分:4)

我很难让Larvel TrustedProxy同时使用CloudFlare和AWS' EC2弹性负载平衡器在一起。它假设您只使用1个代理,而不是2,并且不能正常工作。我最后只是将可信代理内容全部一起跳过并制作了一个简单的MiddleWare,如果使用CloudFlare,无论你前面有另一个Load Balancer,它都只需设置正确的IP地址和协议。

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

我们同时接受客户端IP和客户端HTTP / HTTPS协议,并将其设置为$ request->服务器属性。

==

应用程序/ HTTP /中间件/ 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);
    }
}

应用程序/ HTTP / Kernal.php

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

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

答案 2 :(得分:0)

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

如果在mod_geoip之前加载它可能会起作用,具体取决于mod_geoip的工作方式。

您需要root权限才能安装mod_cloudflare。

答案 3 :(得分:-3)

要将用户的IP地址存储在$ip之类的变量中,您可以通过以下几种方式完成此操作:

$ip = $_SERVER['REMOTE_ADDR'];

$ip = getenv('REMOTE_ADDR');