CloudFlare并通过PHPlogging访问者的IP地址

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

但是,我正在使用CloudFlare进行caching等,并接收CloudFlare的IP地址:

108.162.212。* – 108.162.239。*

在仍使用CloudFlare的情况下,检索实际用户/访问者IP地址的正确方法是什么?

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

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

访问者的$_SERVER["HTTP_CF_IPCOUNTRY"]国家

$_SERVER["HTTP_CF_RAY"] 见这里的描述

$_SERVER["HTTP_CF_VISITOR"]这可以帮助你知道它的http或https

你可以像这样使用它:

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

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

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

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

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

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

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

Cloudflare的ips被公开存储,所以你可以在这里查看它们,然后检查ip是否来自cloudflare(这将允许我们从http头HTTP_CF_CONNECTING_IP获得真实的ip)。

如果你正在使用这个来禁用所有的非cf连接,反之亦然,我build议你有一个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']; } } 

要使用这个脚本很简单:

 $ip = getRequestIP(); $cf = isCloudflare(); if($cf) echo "Cloudflare :D<br>"; else echo "Not cloudflare o_0"; echo "Your actual ip address is: ". $ip; 

这个脚本会告诉你真实的IP地址,如果请求是CF还是不是!

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

HTTP_CF_CONNECTING_IP只在你使用cloudflare的时候工作,也许你转移你的网站或者删除cloudflare,你会忘记这个值,所以使用这个代码。

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

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

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

  1. 通过CloudFlare服务器添加的额外服务器头
  2. 在您的服务器上添加一个CloudFlare Apache / NGINX模块。

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

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

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

它是如何工作的?

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

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

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

$_SERVER["HTTP_CF_RAY"]用于login目的的特殊string

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

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

  • 在Apache服务器上安装CloudFlare模块
  • 在NGINX服务器上安装CloudFlare模块
  • 在EasyApache + CPanel上安装CloudFlare模块