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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14985518/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 08:19:29  来源:igfitidea点击:

CloudFlare and logging visitor IP addresses via in PHP

phploggingip-addresscloudflare

提问by tfont

I'm trying to track and log users/visitors that are accessing my website using PHP's $_SERVER['REMOTE_ADDR']to do so. A typical method for IP address tracking in PHP.

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

However, I am using CloudFlare for caching and such and receiving their IP addresses as CloudFlare's:

但是,我使用 CloudFlare 进行缓存等,并以 CloudFlare 的形式接收它们的 IP 地址:

108.162.212.* - 108.162.239.*

108.162.212.* - 108.162.239.*

What would be a correct method of retrieving the actual users/visitors IP address while still using CloudFlare?

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

回答by sharp12345

Extra server variables that are available to cloud flare are:

云耀斑可用的额外服务器变量是:

$_SERVER["HTTP_CF_CONNECTING_IP"]real visitor ip address, this is what you want

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

$_SERVER["HTTP_CF_IPCOUNTRY"]country of visitor

$_SERVER["HTTP_CF_IPCOUNTRY"]访问国

$_SERVER["HTTP_CF_RAY"]

$_SERVER["HTTP_CF_RAY"]

$_SERVER["HTTP_CF_VISITOR"]this can help you know if its http or https

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

you can use it like this:

你可以这样使用它:

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

If you do this, and the validity of the visiting IP address is important, you might need to verify that the $_SERVER["REMOTE_ADDR"]contains an actual valid cloudflare IP address, because anyone can fake the header if he was able to connect directly to the server IP.

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

回答by Callum

Update: CloudFlare has released a module mod_cloudflarefor apache, the module will log and display the actual visitor IP Addresses rather than those accessed by cloudflare! https://www.cloudflare.com/resources-downloads#mod_cloudflare(Answer by: olimortimer)

更新:CloudFlaremod_cloudflare为 apache发布了一个模块,该模块将记录并显示实际访问者的 IP 地址,而不是那些被 cloudflare 访问的 IP 地址!https://www.cloudflare.com/resources-downloads#mod_cloudflare(答案:olimortimer

If you dont have access to the apache runtime you can use the script below, this will allow you to check if the connection was through cloudflare and get the users ip.

如果您无权访问 apache 运行时,您可以使用下面的脚本,这将允许您检查连接是否通过 cloudflare 并获取用户 ip。

I am rewriting my answer i used for another question "CloudFlare DNS / direct IP identifier"

我正在重写我用于另一个问题“ CloudFlare DNS / 直接 IP 标识符”的答案

Cloudflare's ips are stored in public so you can go view them herethen check if the ip is from cloudflare (this will allow us to get the real ip from the http header HTTP_CF_CONNECTING_IP).

Cloudflare 的ip存储在公共中,因此您可以在此处查看它们然后检查该 ip 是否来自 cloudflare(这将允许我们从 http 标头中获取真实 ip HTTP_CF_CONNECTING_IP)。

If you are using this to disable all non cf connections or vice versa, i recommend you to have a single php script file that gets called before every other script such as a common.php or pagestart.php etc.

如果您使用它来禁用所有非 cf 连接,反之亦然,我建议您有一个单独的 php 脚本文件,该文件在每个其他脚本(例如 common.php 或 pagestart.php 等)之前被调用。

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'];
    }
}

To use the script it's quite simple:

使用脚本非常简单:

$ip = getRequestIP();
$cf = isCloudflare();

if($cf) echo "Connection is through cloudflare: <br>";
else    echo "Connection is not through cloudflare: <br>";

echo "Your actual ip address is: ". $ip;
echo "The server remote address header is: ". $_SERVER['REMOTE_ADDR'];

This script will show you the real ip address and if the request is CF or not!

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

回答by olimortimer

Since this question was asked and answered, CloudFlare has released mod_cloudflarefor Apache, which logs & displays the actual visitor IP address rather than the CloudFlare address:

由于提出并回答了这个问题,CloudFlare 已经发布mod_cloudflare了 Apache,它记录并显示了实际访问者的 IP 地址,而不是 CloudFlare 地址:

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

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

回答by Sainan

Cloudflare sends some additional request headers to your server including CF-Connecting-IPwhich we can store into $user_ip, if defined, using this simple one-liner:

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

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

回答by Supun Kavinda

It would be hard to convert HTTP_CF_CONNECTING_IP to REMOTE_ADDR. So you can use apache (.htaccess) auto prepending to do that. So that you do not need to think about whether the $_SERVER['REMOTE_ADDR']has the correct value in all the PHP scripts.

将 HTTP_CF_CONNECTING_IP 转换为 REMOTE_ADDR 会很困难。所以你可以使用 apache (.htaccess) 自动前置来做到这一点。这样您就无需考虑 是否$_SERVER['REMOTE_ADDR']在所有 PHP 脚本中都具有正确的值。

.htaccess code

.htaccess 代码

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

php code (file.php)

php 代码 (file.php)

<?php

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

Learn More here

在这里了解更多

回答by RootTools

HTTP_CF_CONNECTING_IP is only working if you are using cloudflare maybe you transfer your site or remove cloudflare you will forget the value so use this code .

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

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

回答by Ashutosh Kumar

When you are using CloudFlare all your requests between your server and users are routed through CloudFlare servers.

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

In this case there are two methods to get User's Real IP Address:

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

  1. Through Extra Server Headers added by CloudFlare Servers
  2. Adding a CloudFlare Apache/NGINX Module on your server.
  1. 通过 CloudFlare 服务器添加的额外服务器标头
  2. 在您的服务器上添加 CloudFlare Apache/NGINX 模块。

Method 1: Get IP though extra Server Headers

方法一:通过额外的服务器头获取IP

You can use the following code to get user's IP Address:

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

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

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

How it is working?

它是如何工作的?

CloudFlare adds some extra server variables in the request as follows:

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

$_SERVER["HTTP_CF_CONNECTING_IP"]- Real IP Address of user

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

$_SERVER["HTTP_CF_IPCOUNTRY"]- ISO2 Country of the User

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

$_SERVER["HTTP_CF_RAY"]A Special string for loggin purpose

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

In the above code, we are checking if $_SERVER["HTTP_CF_CONNECTING_IP"]is set or not. If it is there we will consider that as user's IP Address else we will use the default code as $_SERVER['REMOTE_ADDR']

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

Method 2: Installing Cloudflare Module on your server

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

回答by xinqiu

For magento 1.x users (I haven't try magento 2.0 yet), check https://tall-paul.co.uk/2012/03/13/magento-show-remote-ip-in-cloudflare-the-right-way/which needs to change app/etc/local.xml and add: HTTP_CF_CONNECTING_IP

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