web-dev-qa-db-ja.com

ビジターからリアルIPを取得する方法は?

このPHPコードを使用して、訪問者のIPアドレスを取得しています。

<?php echo $_SERVER['REMOTE_ADDR']; ?>

しかし、訪問者から実際のIPアドレスを取得することはできませんプロキシを使用している場合。この場合、訪問者のIPアドレスを取得する方法はありますか?

82
user1866412

このphpコードを試してください。

<?PHP

function getUserIP()
{
    // Get real visitor IP behind CloudFlare network
    if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
              $_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
              $_SERVER['HTTP_CLIENT_IP'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
    }
    $client  = @$_SERVER['HTTP_CLIENT_IP'];
    $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
    $remote  = $_SERVER['REMOTE_ADDR'];

    if(filter_var($client, FILTER_VALIDATE_IP))
    {
        $ip = $client;
    }
    elseif(filter_var($forward, FILTER_VALIDATE_IP))
    {
        $ip = $forward;
    }
    else
    {
        $ip = $remote;
    }

    return $ip;
}


$user_ip = getUserIP();

echo $user_ip; // Output IP address [Ex: 177.87.193.134]


?>
154
user1866400

これは私が見た最も一般的な手法です。

function getUserIP() {
    if( array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) && !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ) {
        if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',')>0) {
            $addr = explode(",",$_SERVER['HTTP_X_FORWARDED_FOR']);
            return trim($addr[0]);
        } else {
            return $_SERVER['HTTP_X_FORWARDED_FOR'];
        }
    }
    else {
        return $_SERVER['REMOTE_ADDR'];
    }
}

非表示にする方法は多数あるため、常に正しいユーザーIPを取得できるとは限りません。

40
Teneff

これは私のアプローチです:

 function getRealUserIp(){
    switch(true){
      case (!empty($_SERVER['HTTP_X_REAL_IP'])) : return $_SERVER['HTTP_X_REAL_IP'];
      case (!empty($_SERVER['HTTP_CLIENT_IP'])) : return $_SERVER['HTTP_CLIENT_IP'];
      case (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) : return $_SERVER['HTTP_X_FORWARDED_FOR'];
      default : return $_SERVER['REMOTE_ADDR'];
    }
 }

使い方:

$ip = getRealUserIp();
19
El cero

プロキシはHTTP_X_FORWARDED_FORヘッダーを送信できますが、それもオプションです。

また、訪問者はIPアドレスを共有する可能性があることに注意してください。大学のネットワーク、大企業、第三世界/低予算ISPは、多くのユーザーでIPを共有する傾向があります。

7
Halcyon

次のコードを適用して、IPアドレスを取得します。

    if (getenv('HTTP_X_FORWARDED_FOR')) { $pipaddress = getenv('HTTP_X_FORWARDED_FOR');
 $ipaddress = getenv('REMOTE_ADDR'); 
    echo "Your Proxy IP address is : ".$pipaddress. "(via $ipaddress)" ; } 
    else { $ipaddress = getenv('REMOTE_ADDR'); echo "Your IP address is : $ipaddress"; }
    ------------------------------------------------------------------------
5

これが私の機能です。

利点 :

  • $ _SERVERが使用できなかった場合に機能します。
  • プライベートおよび/または予約済みIPをフィルタリングします。
  • X_FORWARDED_FORで転送されたすべてのIPを処理する
  • CloudFlareとの互換性
  • 有効なIPが見つからない場合はデフォルトを設定できます!
  • ショート&シンプル!

/**
 * Get real user ip
 *
 * Usage sample:
 * GetRealUserIp();
 * GetRealUserIp('ERROR',FILTER_FLAG_NO_RES_RANGE);
 * 
 * @param string $default default return value if no valid ip found
 * @param int    $filter_options filter options. default is FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
 *
 * @return string real user ip
 */

function GetRealUserIp($default = NULL, $filter_options = 12582912) {
    $HTTP_X_FORWARDED_FOR = isset($_SERVER)? $_SERVER["HTTP_X_FORWARDED_FOR"]:getenv('HTTP_X_FORWARDED_FOR');
    $HTTP_CLIENT_IP = isset($_SERVER)?$_SERVER["HTTP_CLIENT_IP"]:getenv('HTTP_CLIENT_IP');
    $HTTP_CF_CONNECTING_IP = isset($_SERVER)?$_SERVER["HTTP_CF_CONNECTING_IP"]:getenv('HTTP_CF_CONNECTING_IP');
    $REMOTE_ADDR = isset($_SERVER)?$_SERVER["REMOTE_ADDR"]:getenv('REMOTE_ADDR');

    $all_ips = explode(",", "$HTTP_X_FORWARDED_FOR,$HTTP_CLIENT_IP,$HTTP_CF_CONNECTING_IP,$REMOTE_ADDR");
    foreach ($all_ips as $ip) {
        if ($ip = filter_var($ip, FILTER_VALIDATE_IP, $filter_options))
            break;
    }
    return $ip?$ip:$default;
}
4
Ehsan Chavoshi

プロキシが信頼できるものである場合は、次を試すことができます(プロキシIPが151.101.2.10であると仮定します)

<?php

$trustProxyIPs = ['151.101.2.10'];

$clientIP  = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : NULL;

if (in_array($clientIP, $trustProxyIPs)) {

    $headers = ['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR'];

    foreach ($headers as $key => $header) {

        if (isset($_SERVER[$header]) && filter_var($_SERVER[$header], FILTER_VALIDATE_IP)) {

            $clientIP = $_SERVER[$header];

            break;
        }
    }
}

echo $clientIP;

これにより、直接要求されたクライアントによる偽造フォワードヘッダーが防止され、信頼できるプロキシを介して実際のIPが取得されます。

1
Nick Tsai

はい、$_SERVER["HTTP_X_FORWARDED_FOR"]は、nginxサーバーのプロキシの下でIPを表示する方法です。

しかし、最善の策は、プロキシの下から要求されたページでphpinfo()を実行して、すべての使用可能な変数を調べ、実際のIPを保持する変数を確認することです。

0
Nelson