programing

CloudFlare 및 PHP를 통한 방문자 IP 주소 로깅

procenter 2023. 1. 13. 20:23
반응형

CloudFlare 및 PHP를 통한 방문자 IP 주소 로깅

저는의 PHP를 제하고 있는 $_SERVER['REMOTE_ADDR']그렇게 하기 위해서.PHP의 IP입니다.

그러나 캐싱 등에 CloudFlare를 사용하고 CloudFlare의 IP 주소를 수신합니다.

108.162.212.* - 108.162.239.*

CloudFlare를 사용하면서 실제 사용자/방문자의 IP 주소를 검색하는 올바른 방법은 무엇입니까?

클라우드 플레어에서 사용할 수 있는 추가 서버 변수는 다음과 같습니다.

$_SERVER["HTTP_CF_CONNECTING_IP"] ip address, 주소입니다.

$_SERVER["HTTP_CF_IPCOUNTRY"]

$_SERVER["HTTP_CF_RAY"]

$_SERVER["HTTP_CF_VISITOR"] https https의 https의 https의 의 https의 https의 https의 https의 https의 https의 https의 https의 https의 https의 https의 https의

다음과 같이 사용할 수 있습니다.

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

, 중요한 는, 「Visiting IP」, 「Visiting IP」, 「IP」, 「IP」의 유효성이 중요한 것을 .$_SERVER["REMOTE_ADDR"]서버 IP에 직접 접속할 수 있으면 누구나 헤더를 위조할 수 있기 때문에 에는 실제 유효한 클라우드 플레어 IP 주소가 포함되어 있습니다.

업데이트: CloudFlare가 모듈을 출시했습니다.mod_cloudflareApache의 경우 모듈은 Cloudflare에 의해 액세스된 주소가 아닌 실제 방문자의 IP 주소를 기록하고 표시합니다.https://www.cloudflare.com/resources-downloads#mod_cloudflare (답변자: olimortimer)

Apache 런타임에 액세스할 수 없는 경우 아래 스크립트를 사용하여 연결이 CloudFlare를 통해 이루어졌는지 확인하고 사용자 IP를 얻을 수 있습니다.

"CloudFlare DNS / 직접 IP 식별자"라는 다른 질문에 사용한 답변을 다시 씁니다.

Cloudflare의 ip는 공공장소에 저장되어 있기 때문에 여기서 보고 ip가 cloudflare에서 온 것인지 확인할 수 있습니다(이를 통해 http 헤더에서 실제 ip를 가져올 수 있습니다).HTTP_CF_CONNECTING_IP를 참조해 주세요.

이것을 사용하여 CF 이외의 모든 접속을 무효로 하거나 그 반대의 경우, 공통 등의 다른 스크립트보다 먼저 호출되는 단일 php 스크립트파일을 사용하는 것을 추천합니다.php 또는 pagestart.http 등

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인지 여부를 표시합니다.

는 CloudFlare를 했습니다.mod_cloudflareApache CloudFlare IP를 사용합니다.

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

는 Cloudflare를 포함한 에 보냅니다.CF-Connecting-IP해 둘 수 .$user_ip정의되어 있는 경우는, 다음의 심플한 원라이너를 사용합니다.

$user_ip = $_SERVER["HTTP_CF_CONNECTING_IP"] ?? $_SERVER['REMOTE_ADDR'];

HTTP_CF_CONNECTING_IP-REMOTE_ADDR입니다.apache htaccess) (.동 、 (.(.access 、 htaccess 。 때문에 '아까보다'가 될 것 같아요.$_SERVER['REMOTE_ADDR']PHP를 사용합니다.

.htaccess 코드

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

php 코드(file.filename)

<?php

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

자세한 내용은 이쪽

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는 다음과 같이 요청에 몇 가지 서버 변수를 추가합니다.

$_SERVER["HTTP_CF_CONNECTING_IP"]- - "IP

$_SERVER["HTTP_CF_IPCOUNTRY"] User - ISO2 용 - - 。

$_SERVER["HTTP_CF_RAY"]

코드에서는 ''를 하고 있습니다.$_SERVER["HTTP_CF_CONNECTING_IP"]설정 여부입니다.를 「IP 주소」, 「IP 주소」로서 합니다.$_SERVER['REMOTE_ADDR']

방법 2: 서버에 Cloudflare 모듈 설치

에서 Laravel에 합니다.AppServiceProvider:

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


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

하여 실제 클라이언트 IP를 수 .request()->ip().

자세한 것은 이쪽.

Cloudflare에는 도메인의 [Network Management]페이지 헤더에 "Pseudo IPv4" 주소를 사용하는 옵션이 있습니다.서버로 전송되는 헤더를 추가하거나 덮어쓸 수 있습니다.

Cloudflare 대시보드| 네트워크

매뉴얼에서 다음 항목을 참조하십시오.

Pseudo IPv4란?

Cloudflare는 IPv6의 도입을 가속화하기 위한 임시방편으로 IPv4 주소를 필요로 하는 레거시 애플리케이션에서 IPv6 주소를 지원하는 유사 IPv4를 제공합니다.목표는 클래스E IPv4 주소 공간을 사용하여 IPv6 주소별로 거의 일의에 가까운 IPv4 주소를 제공하는 것입니다.클래스 E IPv4 주소 공간은, EXP 로서 지정되어 통상은 트래픽이 인식되지 않습니다.자세한 내용은 여기를 참조하십시오.

옵션들

  • 헤더 추가:추가Cf-Pseudo-IPv4헤더만
  • 머리글 덮어쓰기:기존 덮어쓰기Cf-Connecting-IP그리고.X-Forwarded-For의 IPv4 주소를 가지는 헤더.

주의: 특별한 필요가 없는 한 이 설정을 "Off"로 두는 것이 좋습니다.

기능에 대한 자세한 내용은 Cloudflare의 이 기사를 참조하십시오.이 기사에서는 IPv4에 있는 32비트 공간에 IPv6의 128비트 주소 공간을 수용하는 방법에 대해 자세히 설명합니다.

유사 IPv4와 함께 IPv6 주소를 알고 싶은 경우 Cloudflare는Cf-Connecting-IPv6header(Pseudo IPv4가 네이블로 되어 있는 경우).이것은, IPv6 네트워크상의 디바이스로부터 발신되는 트래픽의 양을 측정하기 위해서 사용할 수 있습니다.이것은, IPv4 의 제한에 아직 바인드 되고 있는 갱신 시스템에 투자하기 전에, 확실한 수치를 사용해 관리를 표시할 필요가 있는 경우에 편리합니다.

magento 1.x 사용자(아직 magento 2.0을 시도하지 않았습니다)의 경우 app/etc/local.xml을 변경해야 하는 https://tall-paul.co.uk/2012/03/13/magento-show-remote-ip-in-cloudflare-the-right-way/을 확인하고 HTTP_CF_CONNECTING_IP를 추가합니다.

Cloudflare IP 범위를 온라인으로 확인하고(언제든지 변경될 수 있으므로), Cloudflare에서 온 것인지 여부를 확인하는 것이 좋습니다.

Cloudflare IP txt

Cloudflare를 사용할 수 .$_SERVER['HTTP_CF_CONNECTING_IP']클라이언트의 ip-address를 취득할 수 있지만, 모든 요구에 대해 ip-address를 사용하는 것은 안전하지 않습니다.이는 요청 헤더에 있는 모든 사용자가 사용자를 속이기 위해 전송할 수 있기 때문입니다.

다음 코드를 사용하여 클라이언트 요청의 실제 IP 주소를 가져올 수 있습니다.

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

에는 Import를 호출하기만 .getRealIp()다음과 같이 합니다.

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

Larabel로 가져오는 또 다른 방법은 HTTP_CF_CONNECTING_IP 헤더를 읽는 것입니다.

$request->server('HTTP_CF_CONNECTING_IP')

자세한 내용은 여기를 참조하십시오.Larabel / PHP에서 Cloudflare의 배후에 실제 클라이언트 IP를 얻는 방법

언급URL : https://stackoverflow.com/questions/14985518/cloudflare-and-logging-visitor-ip-addresses-via-in-php

반응형