116 votes

CloudFlare et enregistrement des adresses IP des visiteurs via PHP

J'essaie de suivre et d'enregistrer les utilisateurs/visiteurs qui accèdent à mon site web en utilisant la fonction PHP. $_SERVER['REMOTE_ADDR'] pour le faire. Une méthode typique de suivi des adresses IP en PHP.

Cependant, j'utilise CloudFlare pour la mise en cache et autres et je reçois leurs adresses IP comme celles de CloudFlare :

108.162.212.* - 108.162.239.*

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

2voto

RootTools Points 11

HTTP_CF_CONNECTING_IP ne fonctionne que si vous utilisez cloudflare ; si vous transférez votre site ou supprimez cloudflare, vous oublierez la valeur ; utilisez donc ce code.

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

2voto

Ashutosh Kumar Points 121

Lorsque vous utilisez CloudFlare, toutes les demandes entre votre serveur et les utilisateurs sont acheminées par les serveurs de CloudFlare.

Dans ce cas, il existe deux méthodes pour obtenir l'adresse IP réelle de l'utilisateur :

  1. Grâce aux en-têtes de serveur supplémentaires ajoutés par les serveurs CloudFlare
  2. Ajout d'un module Apache/NGINX CloudFlare sur votre serveur.

Méthode 1 : Obtenir l'adresse IP grâce à des en-têtes de serveur supplémentaires

Vous pouvez utiliser le code suivant pour obtenir l'adresse IP de l'utilisateur :

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

Comment cela fonctionne-t-il ?

CloudFlare ajoute quelques variables de serveur supplémentaires dans la requête comme suit :

$_SERVER["HTTP_CF_CONNECTING_IP"] - Adresse IP réelle de l'utilisateur

$_SERVER["HTTP_CF_IPCOUNTRY"] - ISO2 Pays de l'utilisateur

$_SERVER["HTTP_CF_RAY"] Une chaîne spéciale pour la connexion

Dans le code ci-dessus, nous vérifions si $_SERVER["HTTP_CF_CONNECTING_IP"] est réglé ou non. S'il est présent, nous le considérerons comme l'adresse IP de l'utilisateur, sinon nous utiliserons le code par défaut, à savoir $_SERVER['REMOTE_ADDR']

Méthode 2 : Installation du module Cloudflare sur votre serveur

2voto

Khalil Laleh Points 534

Dans Laravel, ajoutez la ligne suivante à AppServiceProvider :

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

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

Maintenant vous pouvez obtenir l'IP réelle du client en utilisant request()->ip() .

Lire la suite aquí .

2voto

matigo Points 817

Cloudflare a une option pour utiliser une adresse "Pseudo IPv4" dans les en-têtes de la page de gestion du réseau pour le domaine. Vous avez la possibilité d'ajouter ou de remplacer les en-têtes qui sont envoyés à votre serveur.

Cloudflare Dashboard | Network

Dans la documentation :

Qu'est-ce que le Pseudo IPv4 ?

En guise de palliatif pour accélérer l'adoption d'IPv6, Cloudflare propose le Pseudo IPv4 qui prend en charge les adresses IPv6 dans les anciennes applications qui attendent des adresses IPv4. L'objectif est de fournir une adresse IPv4 presque unique pour chaque adresse IPv6, en utilisant l'espace d'adressage IPv4 de classe E, qui est désigné comme expérimental et ne devrait normalement pas voir de trafic. Pour en savoir plus voir ici .

Options

  • Ajouter un en-tête : Ajouter un supplément Cf-Pseudo-IPv4 en-tête seulement
  • Écraser les en-têtes : Remplacer l'existant Cf-Connecting-IP y X-Forwarded-For avec une pseudo-adresse IPv4.

Note : Nous vous recommandons de laisser ce paramètre sur "Off", sauf si vous avez un besoin spécifique.

Vous pouvez en savoir plus sur cette fonctionnalité de cet article de Cloudflare Ce document explique en détail comment ils essaient d'adapter l'espace d'adressage de 128 bits d'IPv6 à l'espace de 32 bits d'IPv4.

Dans le cas où vous souhaiteriez connaître l'adresse IPv6 en même temps que le pseudo IPv4, Cloudflare ajoute une fonction Cf-Connecting-IPv6 lorsque la fonction Pseudo IPv4 est activée. Cela peut être utilisé pour mesurer la part de votre trafic provenant de dispositifs qui sont sur des réseaux IPv6, ce qui peut être utile si vous avez besoin d'un chiffre solide à montrer à la direction avant d'investir dans la mise à jour de systèmes qui sont encore liés aux limitations IPv4.

2voto

Majid Jalilian Points 108

Il est préférable de vérifier les plages d'adresses IP de cloudflare en ligne (car elles peuvent changer à tout moment), puis de vérifier si elles proviennent de cloudflare ou non.

Cloudflare IP txt

Si la source est Cloudflare, vous pouvez utiliser $_SERVER['HTTP_CF_CONNECTING_IP'] pour obtenir l'adresse IP de la requête de votre client mais il n'est pas sûr de l'utiliser pour toutes les requêtes car elle peut être envoyée par n'importe quel utilisateur dans l'en-tête de la requête pour vous tromper.

Vous pouvez utiliser le code suivant pour obtenir l'adresse IP réelle de votre demande client :

function _getUserRealIP() {
    $ipaddress = '';
    if(isset($_SERVER['REMOTE_ADDR']))
        $ipaddress = $_SERVER['REMOTE_ADDR'];
    else if (isset($_SERVER['HTTP_CLIENT_IP']))
        $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
    else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
        $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_X_FORWARDED']))
        $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
    else if(isset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']))
        $ipaddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
        $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_FORWARDED']))
        $ipaddress = $_SERVER['HTTP_FORWARDED'];
    else
        $ipaddress = 'UNKNOWN';
    return $ipaddress;
}

function _readCloudflareIps()
{
    $file = file("https://www.cloudflare.com/ips-v4",FILE_IGNORE_NEW_LINES);
    return $file;
}

function _checkIpInRange($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 _checkIsCloudflare($ip) {
    $cf_ips = _readCloudflareIps();
    $is_cf_ip = false;
    foreach ($cf_ips as $cf_ip) {
        if (_checkIpInRange($ip, $cf_ip)) {
            $is_cf_ip = true;
            break;
        }
    }
    return $is_cf_ip;
}

function getRealIp()
{
    $httpIp = _getUserRealIP();
    $check = _checkIsCloudflare($httpIp);
    if ($check) {
        return $_SERVER['HTTP_CF_CONNECTING_IP'];
    }else{
        return $httpIp;
    }
}

Après avoir importé ces fonctions dans votre code, il vous suffit d'appeler getRealIp() comme une fonction :

$userIp = getRealIp();
echo $userIp();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X