CloudFlare и протоколирование посетителей IP-адресов через PHP
Я пытаюсь отслеживать и регистрировать пользователей/посетителей, которые обращаются к моему сайту с помощью PHP $_SERVER['REMOTE_ADDR']
, чтобы сделать это. Типичный метод отслеживания IP-адресов в PHP.
Однако я использую CloudFlare для кэширования и, таким образом, получаю их IP-адреса как CloudFlare:
108.162.212. * - 108.162.239. *
Каким будет правильный метод получения фактического IP-адреса пользователей/посетителей при использовании CloudFlare?
Ответы
Ответ 1
Дополнительные серверные переменные, доступные для облачной вспышки:
$_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-адреса важна, вам может потребоваться проверить, что $_SERVER["REMOTE_ADDR"]
содержит фактический действительный IP-адрес облачного флэш-памяти, потому что любой может подделать заголовок, если он смог напрямую подключиться на IP-адрес сервера.
Ответ 2
Поскольку этот вопрос задавали и отвечали, CloudFlare выпустил mod_cloudflare
для Apache, который регистрирует и отображает фактический IP-адрес посетителя, а не адрес CloudFlare:
https://www.cloudflare.com/resources-downloads#mod_cloudflare
Ответ 3
Обновление: CloudFlare выпустила модуль mod_cloudflare
для apache, модуль будет регистрировать и отображать фактические IP-адреса посетителей, а не те, к которым обращался cloudflare! https://www.cloudflare.com/resources-downloads#mod_cloudflare (Ответ: олимортимер)
Если у вас нет доступа к среде исполнения Apache, вы можете использовать приведенный ниже скрипт, это позволит вам проверить, было ли соединение через cloudflare, и получить IP-адрес пользователя.
Я переписываю свой ответ, который использовал для другого вопроса "CloudFlare DNS/прямой IP-идентификатор"
IP-адреса Cloudflare хранятся в открытом доступе, поэтому вы можете просмотреть их здесь, а затем проверить, является ли IP-адрес облачным (это позволит нам получить реальный IP-адрес из заголовка http HTTP_CF_CONNECTING_IP
).
Если вы используете это для отключения всех не-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'];
}
}
Использовать скрипт довольно просто:
$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'];
Этот скрипт покажет вам реальный IP-адрес, а если запрос CF или нет!
Ответ 4
Cloudflare отправляет на ваш сервер дополнительные заголовки запросов, включая CF-Connecting-IP
, которые мы можем сохранить в $user_ip
, если они определены, используя этот простой однострочный интерфейс:
$user_ip = (isset($_SERVER["HTTP_CF_CONNECTING_IP"])?$_SERVER["HTTP_CF_CONNECTING_IP"]:$_SERVER['REMOTE_ADDR']);
Ответ 5
Было бы трудно преобразовать HTTP_CF_CONNECTING_IP в REMOTE_ADDR. Таким образом, вы можете использовать apache (.htaccess) для автоматического предопределения. Так что вам не нужно думать о том, имеет ли $_SERVER['REMOTE_ADDR']
правильное значение во всех сценариях PHP.
Код .htaccess
php_value auto_prepend_file "/path/to/file.php"
php код (file.php)
<?php
define('CLIENT_IP', isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : $_SERVER['REMOTE_ADDR']);
Подробнее здесь
Ответ 6
HTTP_CF_CONNECTING_IP работает только в том случае, если вы используете cloudflare, возможно, вы переносите свой сайт или удаляете cloudflare, вы забудете значение, поэтому используйте этот код.
$ip=$_SERVER["HTTP_CF_CONNECTING_IP"];
if (!isset($ip)) {
$ip = $_SERVER['REMOTE_ADDR'];
}
Ответ 7
Для пользователей magento 1.x(я еще не пробовал magento 2.0), проверьте https://tall-paul.co.uk/2012/03/13/magento-show-remote-ip-in-cloudflare-the-right-way/, которому необходимо изменить приложение /etc/local.xml и добавьте:
HTTP_CF_CONNECTING_IP
Ответ 8
Когда вы используете CloudFlare, все ваши запросы между вашим сервером и пользователями маршрутизируются через серверы CloudFlare.
В этом случае есть два способа получить реальный IP-адрес пользователя:
- Через дополнительные серверные заголовки, добавленные серверами CloudFlare.
- Добавление модуля CloudFlare Apache/NGINX на ваш сервер.
Способ 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"]
Специальная строка для цели loggin
В приведенном выше коде мы проверяем, установлен ли параметр $_SERVER["HTTP_CF_CONNECTING_IP"]
или нет. Если он есть, мы будем считать, что в качестве пользовательского IP-адреса else мы будем использовать код по умолчанию как $_SERVER['REMOTE_ADDR']
Способ 2. Установка модуля Cloudflare на сервере