web-dev-qa-db-fra.com

CloudFlare et la journalisation des adresses IP des visiteurs via in PHP

J'essaie de suivre et de consigner les utilisateurs/visiteurs qui accèdent à mon site Web à l'aide du code $_SERVER['REMOTE_ADDR'] de PHP. Une méthode typique pour le suivi des adresses IP en PHP.

Cependant, j'utilise CloudFlare pour la mise en cache, etc., et je reçois leurs adresses IP telles que celles de CloudFlare:

108.162.212. * - 108.162.239. *

Quelle serait une méthode correcte pour récupérer l'adresse IP réelle des utilisateurs/visiteurs tout en utilisant CloudFlare?

69
tfont

Les variables de serveur supplémentaires disponibles pour Cloud Flare sont les suivantes:

$_SERVER["HTTP_CF_CONNECTING_IP"] adresse IP réelle du visiteur, c'est ce que vous voulez

$_SERVER["HTTP_CF_IPCOUNTRY"] pays du visiteur

$_SERVER["HTTP_CF_RAY"]voir description ici

$_SERVER["HTTP_CF_VISITOR"] cela peut vous aider à savoir si c'est http ou https

vous pouvez l'utiliser comme ceci:

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

Si vous faites cela, et que la validité de l'adresse IP de visite est importante, vous devrez peut-être vérifier que le $_SERVER["REMOTE_ADDR"] contient une adresse IP valide de cloudflare, car tout le monde peut simuler l'en-tête s'il était capable de se connecter directement à l'IP du serveur.

204
sharp12345

Depuis que cette question a été posée et répondue, CloudFlare a publié mod_cloudflare pour Apache, qui enregistre et affiche l'adresse IP réelle du visiteur plutôt que l'adresse CloudFlare:

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

10
olimortimer

Cloudflare envoie quelques en-têtes de requête supplémentaires à votre serveur, y compris CF-Connecting-IP que nous pouvons stocker dans $user_ip, si défini, en utilisant cette simple ligne:

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

Je suis en train de réécrire ma réponse que j'ai utilisée pour une autre question " Identifiant d'adresse IP/adresse IP directe de CloudFlare "

Les ips de Cloudflare sont stockés en public afin que vous puissiez aller les voir ici puis vérifiez si l’ip est de cloudflare (cela nous permettra d’obtenir la vraie ip à partir de l’entête http HTTP_CF_CONNECTING_IP).

Si vous utilisez ceci pour désactiver toutes les connexions non-cf ou vice versa, je vous recommande d'avoir un seul fichier script php appelé avant chaque autre script tel que common.php ou pagestart.php, etc.

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

Pour utiliser le script, c'est très simple:

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

if($cf) echo "Cloudflare :D<br>";
else    echo "Not cloudflare o_0";

echo "Your actual ip address is: ". $ip;

Ce script va vous montrer la véritable adresse IP et si la demande est CF ou non!

7
Callum Carmicheal

Il serait difficile de convertir HTTP_CF_CONNECTING_IP en REMOTE_ADDR. Vous pouvez donc utiliser la fonction de prépositionnement automatique Apache (.htaccess) pour le faire. Ainsi, vous n'avez pas besoin de déterminer si le $_SERVER['REMOTE_ADDR'] a la valeur correcte dans tous les scripts PHP.

.htaccess code

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

code php (fichier.php)

<?php

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

En savoir plus ici

2
Supun Kavinda

HTTP_CF_CONNECTING_IP ne fonctionne que si vous utilisez cloudflare. Peut-être que vous transférez votre site ou supprimez cloudflare, vous en oublierez la valeur, utilisez donc ce code.

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

Pour les utilisateurs de magento 1.x (je n'ai pas encore essayé magento 2.0), vérifiez https://tall-paul.co.uk/2012/03/13/magento-show-remote-ip-in-cloudflare- the-right-way/ qui doit changer app/etc/local.xml et ajouter: HTTP_CF_CONNECTING_IP

0
xinqiu