CloudFlare und Protokollierung von Besucher-IP-Adressen über in PHP

82

Ich versuche, Benutzer / Besucher, die auf meine Website zugreifen, mithilfe von PHPs zu verfolgen und zu protokollieren $_SERVER['REMOTE_ADDR']. Eine typische Methode zur IP-Adressverfolgung in PHP.

Ich verwende CloudFlare jedoch zum Zwischenspeichern und dergleichen und erhalte ihre IP-Adressen als CloudFlare:

108.162.212. * - 108.162.239. *

Was wäre eine korrekte Methode zum Abrufen der tatsächlichen Benutzer- / Besucher-IP-Adresse, während CloudFlare weiterhin verwendet wird?

tfont
quelle

Antworten:

239

Zusätzliche Servervariablen, die für Cloud Flare verfügbar sind, sind:

$_SERVER["HTTP_CF_CONNECTING_IP"] echte Besucher-IP-Adresse, das ist was Sie wollen

$_SERVER["HTTP_CF_IPCOUNTRY"] Land des Besuchers

$_SERVER["HTTP_CF_RAY"]

$_SERVER["HTTP_CF_VISITOR"] Dies kann Ihnen helfen zu wissen, ob es http oder https ist

Sie können es so verwenden:

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

Wenn Sie dies tun und die Gültigkeit der besuchenden IP-Adresse wichtig ist, müssen Sie möglicherweise überprüfen, ob diese $_SERVER["REMOTE_ADDR"]eine tatsächlich gültige Cloudflare-IP-Adresse enthält, da jeder den Header fälschen kann, wenn er eine direkte Verbindung zur Server-IP herstellen konnte.

scharf12345
quelle
15
+1 zum Ersetzen von REMOTE_ADDR durch die echte IP, sodass keine weiteren Änderungen am Code erforderlich sind.
Aalaap
11
Wenn Sicherheit wichtig ist, sollte überprüft werden, ob die Anforderung aus einem Cloudflare-IP-Bereich stammt ( cloudflare.com/ips ). Wie zum Beispiel in diesem Joomla! Plugin: github.com/piccaso/joomla-cf/blob/master/cf/cf.php
Florian Fida
Cloudflare hat diesen Code auch auf seiner Website aufgelistet. support.cloudflare.com/hc/en-us/articles/…
C0nw0nk
Beste Antwort, aber auch ein großes Lob für die Aufnahme von HTTP_CF_IPCOUNTRY, auf das ich noch nie gestoßen bin.
David Bell
http_cf_connecting_ip gibt manchmal Dinge wie: 2a01: 6500: a043: 33a6: b36a: 7259: 4de5: 2500 eine Idee warum?
Michael
15

Update : CloudFlare hat ein Modul mod_cloudflarefür Apache veröffentlicht. Das Modul protokolliert und zeigt die tatsächlichen Besucher-IP-Adressen an und nicht die, auf die Cloudflare zugreift! https://www.cloudflare.com/resources-downloads#mod_cloudflare (Antwort von: olimortimer )

Wenn Sie keinen Zugriff auf die Apache-Laufzeit haben, können Sie das folgende Skript verwenden. Auf diese Weise können Sie überprüfen, ob die Verbindung über Cloudflare hergestellt wurde, und die IP-Adresse des Benutzers abrufen.

Ich schreibe meine Antwort um, die ich für eine andere Frage verwendet habe: " CloudFlare DNS / Direct IP Identifier ".

Die IPs von Cloudflare werden öffentlich gespeichert, sodass Sie sie hier anzeigen und dann überprüfen können, ob die IP von Cloudflare stammt (dies ermöglicht es uns, die echte IP aus dem http-Header abzurufen HTTP_CF_CONNECTING_IP).

Wenn Sie dies verwenden, um alle Nicht-CF-Verbindungen zu deaktivieren oder umgekehrt, empfehle ich Ihnen, eine einzige PHP-Skriptdatei zu haben, die vor jedem anderen Skript aufgerufen wird, z. B. eine common.php oder eine pagestart.php usw.

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

Um das Skript zu verwenden, ist es ganz einfach:

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

Dieses Skript zeigt Ihnen die echte IP-Adresse und ob die Anfrage CF ist oder nicht!

Callum
quelle
Dies ist die richtige Antwort. Beachten Sie jedoch, dass Sie die IP-Adressen regelmäßig aktualisieren müssen. Die aktuellen im obigen Code sind bereits ungültig und daher schlägt der Code fehl. Die neuesten IP- Adressen erhalten Sie hier: cloudflare.com/ips Idealerweise sollten Sie diese in einer Datei speichern, damit Sie nur die externe Datei aktualisieren müssen, oder noch besser, rufen Sie
Rafark
11

Seit diese Frage gestellt und beantwortet wurde, hat CloudFlare mod_cloudflarefür Apache freigegeben , das die tatsächliche IP-Adresse des Besuchers anstelle der CloudFlare-Adresse protokolliert und anzeigt:

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

Olimortimer
quelle
2019 - Sie unterstützen nicht mehr mod_cloudflare, aber es kann verwendet werden. Es heißt etwas Neues mod_remoteip. Referenz: support.cloudflare.com/hc/en-us/articles/…
sinaza
@sinaza wahrscheinlich am besten, um eine neue Antwort zu erstellen, da meine Antwort für mod_cloudflarevor 4 Jahren war
Olimortimer
@sjagr in Bezug auf Ihre Änderungen sind sie falsch - CloudFlare ist eigentlich Cloudflare, wie ich ursprünglich gepostet habe
Olimortimer
10

Cloudflare sendet einige zusätzliche Anforderungsheader an Ihren Server, einschließlich CF-Connecting-IPderer, in denen wir $user_ip, falls definiert, mithilfe dieses einfachen Einzeilers speichern können :

$user_ip = (isset($_SERVER["HTTP_CF_CONNECTING_IP"])?$_SERVER["HTTP_CF_CONNECTING_IP"]:$_SERVER['REMOTE_ADDR']);
Sainan
quelle
Das Problem dabei ist, dass dies nur ein einfacher Header ist, sodass jeder ihn einfach auf die gewünschte IP-Adresse einstellen kann, was eine große Sicherheitslücke darstellt.
Rafark
@rafark Nicht, wenn Ihr Server ordnungsgemäß konfiguriert ist und sich hinter Cloudflare befindet.
Sainan
Ja natürlich. Dies ist per se eine gute Lösung, aber vor der Verwendung von HTTP_CF_CONNECTING_IP sollten noch Überprüfungen durchgeführt werden, wie in
Callums
@rafark Ich stimme auch zu, aber das ist eine Menge PHP-Code, der bereits in einer anderen Form in Ihrer Apache-Konfiguration vorhanden ist (ich hoffe). Dieser Code dient eher dem einfachen Debuggen und wenn ein Angreifer Zugriff auf Ihre Debugging-Umgebung hat, denke ich Sie haben wichtigere Probleme zu lösen.
Sainan
2

Es wäre schwierig, HTTP_CF_CONNECTING_IP in REMOTE_ADDR zu konvertieren. Sie können dazu Apache (.htaccess) verwenden, das automatisch vorangestellt wird. Damit Sie nicht darüber nachdenken müssen, ob der $_SERVER['REMOTE_ADDR']in allen PHP-Skripten den richtigen Wert hat.

.htaccess-Code

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

PHP-Code (file.php)

<?php

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

Erfahren Sie hier mehr

Supun Kavinda
quelle
1

HTTP_CF_CONNECTING_IP funktioniert nur, wenn Sie Cloudflare verwenden. Vielleicht übertragen Sie Ihre Site oder entfernen Cloudflare. Sie werden den Wert vergessen. Verwenden Sie diesen Code.

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

Wenn Sie CloudFlare verwenden, werden alle Ihre Anforderungen zwischen Ihrem Server und den Benutzern über CloudFlare-Server weitergeleitet.

In diesem Fall gibt es zwei Methoden, um die tatsächliche IP-Adresse des Benutzers abzurufen:

  1. Über zusätzliche Server-Header, die von CloudFlare-Servern hinzugefügt wurden
  2. Hinzufügen eines CloudFlare Apache / NGINX-Moduls auf Ihrem Server.

Methode 1: IP über zusätzliche Server-Header abrufen

Sie können den folgenden Code verwenden, um die IP-Adresse des Benutzers abzurufen:

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

Wie funktioniert es?

CloudFlare fügt der Anforderung einige zusätzliche Servervariablen wie folgt hinzu:

$_SERVER["HTTP_CF_CONNECTING_IP"] - Echte IP-Adresse des Benutzers

$_SERVER["HTTP_CF_IPCOUNTRY"] - ISO2-Land des Benutzers

$_SERVER["HTTP_CF_RAY"] Eine spezielle Zeichenfolge für Protokollierungszwecke

Im obigen Code prüfen wir, ob $_SERVER["HTTP_CF_CONNECTING_IP"]eingestellt ist oder nicht. Wenn es dort ist, werden wir berücksichtigen, dass wir als IP-Adresse des Benutzers den Standardcode als verwenden$_SERVER['REMOTE_ADDR']

Methode 2: Installieren des Cloudflare-Moduls auf Ihrem Server

Ashutosh Kumar
quelle