CloudFlare并通过PHP记录访问者IP地址

时间:2013-02-20 16:56:53

标签: php logging ip-address cloudflare

我正在尝试使用PHP $_SERVER['REMOTE_ADDR']跟踪和记录访问我网站的用户/访问者。 PHP中IP地址跟踪的典型方法。

但是,我使用CloudFlare进行缓存等,并将其IP地址作为CloudFlare接收:

  

108.162.212。* - 108.162.239。*

在使用CloudFlare的同时检索实际用户/访问者IP地址的正确方法是什么?

10 个答案:

答案 0 :(得分:210)

可用于云计算的额外服务器变量是:

$_SERVER["HTTP_CF_CONNECTING_IP"]真实的访问者IP地址,这就是你想要的

$_SERVER["HTTP_CF_IPCOUNTRY"]来访者国家

$_SERVER["HTTP_CF_RAY"] see description here

$_SERVER["HTTP_CF_VISITOR"]这可以帮助您了解其http或https

你可以像这样使用它:

if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
  $_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
}

如果您这样做,并且访问IP地址的有效性很重要,您可能需要验证$_SERVER["REMOTE_ADDR"]是否包含实际有效的cloudflare IP地址,因为任何人都可以伪造标头,如果他能够直接连接到服务器IP。

答案 1 :(得分:10)

自从提出并回答了这个问题以来,CloudFlare已经为Apache发布了mod_cloudflare,它记录了&显示实际的访客IP地址而不是CloudFlare地址:

https://www.cloudflare.com/resources-downloads#mod_cloudflare

答案 2 :(得分:8)

Cloudflare向您的服务器发送一些额外的请求标头,包括CF-Connecting-IP,如果已定义,我们可以使用这个简单的单行程序存储到$user_ip

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

答案 3 :(得分:7)

我正在重写我用于另一个问题的答案" CloudFlare DNS / direct IP identifier"

Cloudflare的ips存储在公共场所,因此您可以查看它们here然后检查ip是否来自cloudflare(这将允许我们从http标头获取真实的IP {{1} })。

如果你使用它来禁用所有非cf连接,反之亦然,我建议你有一个php脚本文件,在每个其他脚本之前调用,比如common.php或pagestart.php等。

HTTP_CF_CONNECTING_IP

要使用该脚本,它非常简单:

function ip_in_range($ip, $range) {
    if (strpos($range, '/') == false)
        $range .= '/32';

    // $range is in IP/CIDR format eg 127.0.0.1/24
    list($range, $netmask) = explode('/', $range, 2);
    $range_decimal = ip2long($range);
    $ip_decimal = ip2long($ip);
    $wildcard_decimal = pow(2, (32 - $netmask)) - 1;
    $netmask_decimal = ~ $wildcard_decimal;
    return (($ip_decimal & $netmask_decimal) == ($range_decimal & $netmask_decimal));
}

function _cloudflare_CheckIP($ip) {
    $cf_ips = array(
        '199.27.128.0/21',
        '173.245.48.0/20',
        '103.21.244.0/22',
        '103.22.200.0/22',
        '103.31.4.0/22',
        '141.101.64.0/18',
        '108.162.192.0/18',
        '190.93.240.0/20',
        '188.114.96.0/20',
        '197.234.240.0/22',
        '198.41.128.0/17',
        '162.158.0.0/15',
        '104.16.0.0/12',
    );
    $is_cf_ip = false;
    foreach ($cf_ips as $cf_ip) {
        if (ip_in_range($ip, $cf_ip)) {
            $is_cf_ip = true;
            break;
        }
    } return $is_cf_ip;
}

function _cloudflare_Requests_Check() {
    $flag = true;

    if(!isset($_SERVER['HTTP_CF_CONNECTING_IP']))   $flag = false;
    if(!isset($_SERVER['HTTP_CF_IPCOUNTRY']))       $flag = false;
    if(!isset($_SERVER['HTTP_CF_RAY']))             $flag = false;
    if(!isset($_SERVER['HTTP_CF_VISITOR']))         $flag = false;
    return $flag;
}

function isCloudflare() {
    $ipCheck        = _cloudflare_CheckIP($_SERVER['REMOTE_ADDR']);
    $requestCheck   = _cloudflare_Requests_Check();
    return ($ipCheck && $requestCheck);
}

// Use when handling ip's
function getRequestIP() {
    $check = isCloudflare();

    if($check) {
        return $_SERVER['HTTP_CF_CONNECTING_IP'];
    } else {
        return $_SERVER['REMOTE_ADDR'];
    }
}

此脚本将显示真实的IP地址以及请求是否为CF!

答案 4 :(得分:2)

将HTTP_CF_CONNECTING_IP转换为REMOTE_ADDR很难。所以你可以使用apache(.htaccess)auto prepending来做到这一点。因此,您无需考虑$_SERVER['REMOTE_ADDR']在所有PHP脚本中是否具有正确的值。

.htaccess代码

php_value auto_prepend_file "/path/to/file.php"

php code(file.php)

<?php

define('CLIENT_IP', isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : $_SERVER['REMOTE_ADDR']);

了解详情here

答案 5 :(得分:1)

HTTP_CF_CONNECTING_IP仅在您使用cloudflare时有效。也许您转移您的网站或删除cloudflare您将忘记该值,因此请使用此代码。

conditionalProps

答案 6 :(得分:1)

在Laravel中,将以下行添加到AppServiceProvider

...
use Symfony\Component\HttpFoundation\Request;


...
public function boot()
{
    Request::setTrustedProxies(['REMOTE_ADDR'], Request::HEADER_X_FORWARDED_FOR);
}

现在您可以使用request()->ip()获取真实的客户端IP。

了解更多here

答案 7 :(得分:1)

Cloudflare 可以选择在域的网络管理页面的标头中使用“伪 IPv4”地址。您可以选择添加或覆盖发送到服务器的标头。

Cloudflare Dashboard | Network

来自文档:

<块引用>

什么是伪 IPv4?

作为加速采用 IPv6 的权宜之计,Cloudflare 提供了伪 IPv4,它在需要 IPv4 地址的传统应用程序中支持 IPv6 地址。目标是为每个 IPv6 地址提供一个几乎唯一的 IPv4 地址,使用 E 类 IPv4 地址空间,该地址空间被指定为实验性的,通常不会看到流量。要了解更多信息see here

选项

  • 添加标题:仅添加额外的 Cf-Pseudo-IPv4 标题
  • 覆盖标头:用伪 IPv4 地址覆盖现有的 Cf-Connecting-IPX-Forwarded-For 标头。

注意:除非您有特殊需要,否则我们建议将此设置为“关闭”。

您可以了解有关此功能的更多信息 from this article from Cloudflare,其中详细介绍了它们如何尝试在 IPv4 的 32 位空间中适应 IPv6 的 128 位地址空间。

>

如果您想知道 IPv6 地址以及伪 IPv4,Cloudflare 会在启用伪 IPv4 时添加 Cf-Connecting-IPv6 标头。这可用于衡量有多少流量来自 IPv6 网络上的设备,如果在投资更新仍受 IPv4 限制的系统之前需要一个可靠的数字来显示管理情况,这将非常有用。

答案 8 :(得分:0)

对于magento 1.x用户(我还没有尝试magento 2.0),请检查需要更改app / etc / local.xml的https://tall-paul.co.uk/2012/03/13/magento-show-remote-ip-in-cloudflare-the-right-way/并添加:            HTTP_CF_CONNECTING_IP

答案 9 :(得分:0)

当您使用CloudFlare时,您的服务器和用户之间的所有请求都将通过CloudFlare服务器进行路由。

在这种情况下,有两种方法可以获取用户的真实IP地址:

  1. 通过CloudFlare Servers添加的额外服务器标头
  2. 在您的服务器上添加CloudFlare Apache / NGINX模块。
  3. 方法1:通过额外的服务器标头获取IP

    您可以使用以下代码获取用户的IP地址:

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

    它是如何工作的?

    CloudFlare在请求中添加了一些额外的服务器变量,如下所示:

    $_SERVER["HTTP_CF_CONNECTING_IP"] - 用户的真实IP地址

    $_SERVER["HTTP_CF_IPCOUNTRY"] - 用户的ISO2国家/地区

    $_SERVER["HTTP_CF_RAY"]用于登录目的的特殊字符串

    在上面的代码中,我们正在检查是否设置了$_SERVER["HTTP_CF_CONNECTING_IP"]。如果它在那里,我们会将其视为用户的IP地址,否则我们将使用默认代码$_SERVER['REMOTE_ADDR']

    方法2:在服务器上安装Cloudflare模块