পিএইচপি-তে কোনও ব্যবহারকারীর সঠিক আইপি ঠিকানা পুনরুদ্ধার করার সবচেয়ে সঠিক উপায় কী?


301

আমি জানি $ _SERVER এর আধিক্য রয়েছে আইপি ঠিকানা পুনরুদ্ধারের জন্য উপলব্ধ ভেরিয়েবলের শিরোনামের । আমি ভাবছিলাম যে কোনও ব্যবহারকারীর আসল আইপি অ্যাড্রেসটি কীভাবে সঠিকভাবে পুনরুদ্ধার করতে হবে (সাধারণ কোনও পদ্ধতি নিখুঁতভাবে জেনে নেই) বলেন ভেরিয়েবলগুলি ব্যবহার করে কীভাবে একটি সাধারণ sensক্যমত্য আছে?

গভীরতার সমাধান খুঁজতে চেষ্টা করে আমি কিছুটা সময় ব্যয় করেছি এবং বেশ কয়েকটি উত্সের ভিত্তিতে নিম্নলিখিত কোডটি নিয়ে এসেছি। যদি কেউ দয়া করে উত্তরের গর্তগুলি ছুঁড়ে দিতে পারে বা আরও সঠিক কোনও বিষয়ে কিছুটা আলোকপাত করতে পারে তবে আমি এটি পছন্দ করব।

সম্পাদনায় @ অ্যালিক্স থেকে অপ্টিমাইজেশন অন্তর্ভুক্ত রয়েছে

 /**
  * Retrieves the best guess of the client's actual IP address.
  * Takes into account numerous HTTP proxy headers due to variations
  * in how different ISPs handle IP addresses in headers between hops.
  */
 public function get_ip_address() {
  // Check for shared internet/ISP IP
  if (!empty($_SERVER['HTTP_CLIENT_IP']) && $this->validate_ip($_SERVER['HTTP_CLIENT_IP']))
   return $_SERVER['HTTP_CLIENT_IP'];

  // Check for IPs passing through proxies
  if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
   // Check if multiple IP addresses exist in var
    $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    foreach ($iplist as $ip) {
     if ($this->validate_ip($ip))
      return $ip;
    }
   }
  }
  if (!empty($_SERVER['HTTP_X_FORWARDED']) && $this->validate_ip($_SERVER['HTTP_X_FORWARDED']))
   return $_SERVER['HTTP_X_FORWARDED'];
  if (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && $this->validate_ip($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']))
   return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
  if (!empty($_SERVER['HTTP_FORWARDED_FOR']) && $this->validate_ip($_SERVER['HTTP_FORWARDED_FOR']))
   return $_SERVER['HTTP_FORWARDED_FOR'];
  if (!empty($_SERVER['HTTP_FORWARDED']) && $this->validate_ip($_SERVER['HTTP_FORWARDED']))
   return $_SERVER['HTTP_FORWARDED'];

  // Return unreliable IP address since all else failed
  return $_SERVER['REMOTE_ADDR'];
 }

 /**
  * Ensures an IP address is both a valid IP address and does not fall within
  * a private network range.
  *
  * @access public
  * @param string $ip
  */
 public function validate_ip($ip) {
     if (filter_var($ip, FILTER_VALIDATE_IP, 
                         FILTER_FLAG_IPV4 | 
                         FILTER_FLAG_IPV6 |
                         FILTER_FLAG_NO_PRIV_RANGE | 
                         FILTER_FLAG_NO_RES_RANGE) === false)
         return false;
     self::$ip = $ip;
     return true;
 }

সতর্কতার শব্দ (আপডেট)

REMOTE_ADDRএখনও একটি আইপি ঠিকানার সবচেয়ে নির্ভরযোগ্য উত্স প্রতিনিধিত্ব করে । $_SERVERএখানে উল্লিখিত অন্যান্য ভেরিয়েবলগুলি খুব সহজেই একটি দূরবর্তী ক্লায়েন্টের দ্বারা ছদ্মবেশী হতে পারে। এই সমাধানের উদ্দেশ্য হ'ল প্রক্সিটির পিছনে বসে থাকা কোনও ক্লায়েন্টের আইপি ঠিকানা নির্ধারণের চেষ্টা করা। আপনার সাধারণ উদ্দেশ্যে, আপনি সরাসরি থেকে ফিরে আসা আইপি ঠিকানার সাথে এটি ব্যবহার করে বিবেচনা করতে পারেন$_SERVER['REMOTE_ADDR'] এবং উভয়ই সঞ্চয় করে বিবেচনা করতে পারেন।

99.9% ব্যবহারকারীর জন্য এই সমাধানটি আপনার প্রয়োজনগুলির জন্য উপযুক্ত হবে suit এটি আপনাকে আপনার নিজের অনুরোধ শিরোনাম ইনজেকশন দিয়ে আপনার সিস্টেমের অপব্যবহার করতে দেখা 0.1% দূষিত ব্যবহারকারীদের হাত থেকে রক্ষা করবে না। যদি REMOTE_ADDRকোনও গুরুত্বপূর্ণ বিষয় মিশনের জন্য আইপি ঠিকানার উপর নির্ভর করে, তবে কোনও প্রক্সিটির পিছনে থাকা লোকদের কেটারিং বিরক্ত করবেন না।


2
হোয়াটস্মিইপ ডটকম প্রশ্নের জন্য, আমি ভাবছি তারা এই স্ক্রিপ্টের মতো কিছু করেন, আপনি কি এটি স্থানীয়ভাবে চালাচ্ছেন? আপনার যদি অভ্যন্তরীণ আইপি কেন থাকে তবে আপনি যদি সর্বজনীন ইন্টারফেসের মাধ্যমে কিছুই প্রেরণ করেন না তবে পিএইচপি করার কোনও তথ্য নেই
ম্যাট

2
এটি বাস্তবায়ন করার সময় আপনি এটি মাথায় রেখেছেন তা
কেভিন পেনো

19
মনে রাখবেন যে এই সমস্ত এইচটিটিপি শিরোনামগুলি সংশোধন করা সত্যিই সহজ: আপনার সমাধানের সাথে, আমাকে কেবল একটি এলোমেলো আইপি সহ একটি এক্স-ফরওয়ার্ড-ফর শিরোনাম প্রেরণের জন্য আমার ব্রাউজারটি কনফিগার করতে হবে এবং আপনার স্ক্রিপ্টটি আনন্দের সাথে একটি জাল ঠিকানা ফেরত দেবে। সুতরাং আপনি যা করার চেষ্টা করছেন তার উপর নির্ভর করে এই সমাধানটি কেবল REMOTE_ADDR ব্যবহার করার চেয়ে কম নির্ভরযোগ্য হতে পারে।
gnomnain

14
ওএমএফজি, "অবিশ্বস্ত আইপি"! প্রথমবার আমি এখানে এসও তেমন বাজে কথা দেখি। একমাত্র নির্ভরযোগ্য আইপি ঠিকানাটি REMOTE_ADDR
আপনার প্রচলিত

3
-1 এটি স্পোফিংয়ের পক্ষে ঝুঁকিপূর্ণ। আপনি যা করছেন তা ব্যবহারকারীর কাছে তার আইপি ঠিকানাটি কী হওয়া উচিত তা জিজ্ঞাসা করছেন।
রোক

উত্তর:


268

আইপি ঠিকানা পাওয়ার জন্য এখানে একটি সংক্ষিপ্ত এবং ক্লিনার উপায়:

function get_ip_address(){
    foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){
        if (array_key_exists($key, $_SERVER) === true){
            foreach (explode(',', $_SERVER[$key]) as $ip){
                $ip = trim($ip); // just to be safe

                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
                    return $ip;
                }
            }
        }
    }
}

আমি আসা করি এটা সাহায্য করবে!


আপনার কোডটি ইতিমধ্যে সম্পূর্ণরূপে সম্পূর্ণ বলে মনে হচ্ছে, আমি এতে কোনও সম্ভাব্য বাগ দেখতে পাচ্ছি না (সাধারণ আইপি ক্যাভ্যাটগুলি বাদে) আমি validate_ip()ফিল্টার এক্সটেনশনের উপর নির্ভর করতে ফাংশনটি পরিবর্তন করব যদিও:

public function validate_ip($ip)
{
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false)
    {
        return false;
    }

    self::$ip = sprintf('%u', ip2long($ip)); // you seem to want this

    return true;
}

এছাড়াও আপনার HTTP_X_FORWARDED_FORস্নিপেট এটি থেকে সরল করা যেতে পারে:

// check for IPs passing through proxies
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
    // check if multiple ips exist in var
    if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') !== false)
    {
        $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);

        foreach ($iplist as $ip)
        {
            if ($this->validate_ip($ip))
                return $ip;
        }
    }

    else
    {
        if ($this->validate_ip($_SERVER['HTTP_X_FORWARDED_FOR']))
            return $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
}

এটি:

// check for IPs passing through proxies
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
    $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);

    foreach ($iplist as $ip)
    {
        if ($this->validate_ip($ip))
            return $ip;
    }
}

আপনি আইপিভি 6 ঠিকানাও বৈধ করতে চাইতে পারেন।


4
আমি অবশ্যই এই filter_varস্থির প্রশংসা করি কারণ এটি আইপি ঠিকানায় একচেটিয়া স্বাক্ষরযুক্ত স্বাক্ষরযুক্ত ইন চেকগুলি সরিয়ে দেয়। আমি এটিও পছন্দ করি যে এটি আমাকে আইপিভি 6 ঠিকানারও বৈধতা দেওয়ার বিকল্প দেয়। HTTP_X_FORWARDED_FORঅপ্টিমাইজেশান অনেক প্রশংসা করেন। কয়েক মিনিটের মধ্যে আমি কোডটি আপডেট করব।
কোরি বলিউ

33
-1 এটি আপনি যা করছেন তা ছদ্মবেশের পক্ষে ঝুঁকির সাথে ব্যবহারকারীকে জিজ্ঞাসা করছে তার আইপি ঠিকানাটি কী হওয়া উচিত।
রোক

7
@ রুক: হ্যাঁ, আমি জানি। ওপি এটি সম্পর্কে অবগত এবং আমি আমার উত্তরেও এটি উল্লেখ করেছি। তবে মন্তব্যের জন্য ধন্যবাদ।
অ্যালিক্স অ্যাক্সেল

1
এফওয়াইআই: অ্যালিক্স এক্সেলের কোডটি কাজ করতে আমাকে FILTER_FLAG_IPV6 সরিয়ে ফেলতে হয়েছিল।
অন্ধকারআসপিচ

2
@ রুবেনারপ 81 টিসিপি সকেট হ্যান্ডলারটি কেবলমাত্র একমাত্র উত্স, সমস্ত কিছু আক্রমণকারী নিয়ন্ত্রিত। উপরের কোডটি আক্রমণকারীর স্বপ্ন।
রোক

12

তারপরেও তবে কোনও ব্যবহারকারীর আসল আইপি ঠিকানা পাওয়া বিশ্বাসযোগ্য হতে চলেছে। তাদের যা করার দরকার তা হ'ল একটি বেনামে প্রক্সি সার্ভার (একটি যা http_x_forwarded_for, http_forwarded, ইত্যাদির জন্য শিরোনামকে সম্মান দেয় না) এবং আপনি যা পান তা হ'ল তাদের প্রক্সি সার্ভারের আইপি ঠিকানা।

তারপরে আপনি দেখতে পাচ্ছেন যে অজ্ঞাতনামা প্রক্সি সার্ভারের আইপি ঠিকানাগুলির একটি তালিকা রয়েছে কিনা তবে এটি নিশ্চিত করার কোনও উপায় নেই যে এটিও 100% যথাযথ এবং এটি সবচেয়ে বেশি আপনাকে জানাতে হবে যে এটি প্রক্সি সার্ভার। এবং যদি কেউ চালাক হয়ে থাকে তবে তারা এইচটিটিপি ফরোয়ার্ডের জন্য শিরোনাম ফাঁকি দিতে পারে।

ধরা যাক আমি স্থানীয় কলেজ পছন্দ করি না। তারা কী আইপি ঠিকানাগুলি নিবন্ধভুক্ত করেছে তা আমি খুঁজে বের করেছি এবং খারাপ সাইটগুলি করে তাদের আইপি ঠিকানাটি আপনার সাইটে নিষিদ্ধ করা হয়েছে, কারণ আমি বুঝতে পেরেছি যে আপনি এইচটিটিপি ফরোয়ার্ডকে সম্মান করেন। তালিকাটি অন্তহীন।

তারপরে আপনি যেমন অনুমান করেছিলেন, এমন কলেজ নেটওয়ার্কের মতো অভ্যন্তরীণ আইপি অ্যাড্রেসগুলি আগে উল্লেখ করা হয়েছিল। অনেকগুলি একটি 10.xxx ফর্ম্যাট ব্যবহার করে। সুতরাং আপনারা যা জানবেন তা হ'ল এটি একটি ভাগ করা নেটওয়ার্কের জন্য ফরওয়ার্ড করা হয়েছিল।

তারপরে আমি এর মধ্যে বেশি কিছু শুরু করব না, তবে গতিশীল আইপি অ্যাড্রেসগুলি ব্রডব্যান্ডের উপায়। So. এমনকি যদি আপনি কোনও আইপি অ্যাড্রেস পান তবে এটি দীর্ঘতম সময়ে 2 - 3 মাসের মধ্যে পরিবর্তিত হওয়ার প্রত্যাশা করুন।


ইনপুট জন্য ধন্যবাদ। আমি বর্তমানে সেশন হাইজ্যাকিং সীমাবদ্ধ করার জন্য সীমিত ফ্যাক্টর হিসাবে তাদের ক্লাস সি আইপি ব্যবহার করে সেশন প্রমাণীকরণে সহায়তা করতে ব্যবহারকারীর আইপি ঠিকানাটি ব্যবহার করছি তবে কারণের মধ্যে গতিশীল আইপিগুলির অনুমতি দিচ্ছি। স্পুফড আইপি এবং বেনামে প্রক্সি সার্ভার হ'ল এমন একটি জিনিস যা আমাকে নির্বাচিত ব্যক্তিদের একটি গ্রুপের জন্য মোকাবেলা করতে হবে।
কোরি বলিউ

@cballou - অবশ্যই এই উদ্দেশ্যে REMOTE_ADDR ব্যবহার করা সঠিক to এইচটিটিপি শিরোনামের উপর নির্ভর করে যে কোনও পদ্ধতির হেডার স্পোফিংয়ের পক্ষে ঝুঁকিপূর্ণ। একটি অধিবেশন কত দিন? গতিশীল আইপি দ্রুত পরিবর্তন হয় না।
এমজেডবি

তারা করে, বিশেষত যদি আমি তাদের চাই (ম্যাক ঠিকানা পরিবর্তন করুন যা অনেক ড্রাইভার সমর্থন করে)। এটি সর্বশেষ যে সার্ভারের সাথে কথা বলেছে তা পেতে কেবলমাত্র REMOTE_ADDRই যথেষ্ট। সুতরাং একটি প্রক্সি পরিস্থিতিতে আপনি প্রক্সি আইপি পাবেন।

8

আমরা ব্যাবহার করি:

/**
 * Get the customer's IP address.
 *
 * @return string
 */
public function getIpAddress() {
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
        return $_SERVER['HTTP_CLIENT_IP'];
    } else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        return trim($ips[count($ips) - 1]);
    } else {
        return $_SERVER['REMOTE_ADDR'];
    }
}

HTTP_X_FORWARDED_FOR উপর বিস্ফোরিত করা কারণ অদ্ভুত বিষয় আমরা IP ঠিকানা সনাক্ত ছিল যখন স্কুইড ব্যবহার করা হয়েছিল।


ওফস, আমি ঠিক বুঝতে পেরেছি যে আপনি মূলত একই জিনিসটি বিস্ফোরিত করে এবং আরও কিছু করে। আরও কিছুটা অতিরিক্ত। সুতরাং আমি সন্দেহ করি যে আমার উত্তরটি অনেক সাহায্য করেছিল। :)
gabrielk

এটি লোকালহোস্টের ঠিকানাটি
ফেরায়

3

আমার উত্তরটি মূলত @ অ্যালিক্সএক্সেলের উত্তরের সংস্করণ মাত্র একটি পালিশ, সম্পূর্ণ-বৈধ এবং সম্পূর্ণ প্যাকেজড:

<?php

/* Get the 'best known' client IP. */

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

                foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key)
                    {
                        if (array_key_exists($key, $_SERVER)) 
                            {
                                foreach (explode(',', $_SERVER[$key]) as $ip)
                                    {
                                        $ip = trim($ip);

                                        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false)
                                            {
                                                return $ip;
                                            };
                                    };
                            };
                    };

                return false;
            };
    };

$best_known_ip = getClientIP();

if(!empty($best_known_ip))
    {
        $ip = $clients_ip = $client_ip = $client_IP = $best_known_ip;
    }
else
    {
        $ip = $clients_ip = $client_ip = $client_IP = $best_known_ip = '';
    };

?>

পরিবর্তন করুন:

  • এটি ফাংশন নামটি সহজ করে দেয় ('উটকেস' বিন্যাস শৈলীর সাথে)।

  • এটিতে আপনার কোডের অন্য অংশে ফাংশনটি ইতিমধ্যে ঘোষণা করা হয়নি তা নিশ্চিত করার জন্য এটিতে একটি চেক অন্তর্ভুক্ত রয়েছে।

  • এটি 'ক্লাউডফ্লেয়ার' সামঞ্জস্যতা গ্রহণ করে।

  • এটি 'getClientIP' ফাংশনের একাধিক "আইপি-সম্পর্কিত" পরিবর্তনশীল নামগুলি প্রত্যাবর্তিত মানকে আরম্ভ করে।

  • এটি নিশ্চিত করে যে যদি ফাংশনটি কোনও বৈধ আইপি ঠিকানা না ফেরায় তবে সমস্ত ভেরিয়েবলগুলি একটি খালি স্ট্রিংয়ের পরিবর্তে সেট করা হবে null

  • এটি কোডের কেবল (45) লাইন।


2

সবচেয়ে বড় প্রশ্ন কোন উদ্দেশ্যে?

আপনার কোডটি যতটা সম্ভব বিস্তৃত - তবে আমি দেখতে পাচ্ছি যে আপনি যদি প্রক্সি অ্যাডেড শিরোনামের মতো দেখতে পান তবে আপনি সিআইআইআইআইপি-র ইনস্টলটি ব্যবহার করেন, তবে আপনি যদি নিরীক্ষণের উদ্দেশ্যে এই তথ্যটি চান তবে সতর্ক করে দেওয়া হবে - এটি খুব সহজ জাল.

অবশ্যই আপনার কোনও ধরণের প্রমাণীকরণের জন্য আইপি ঠিকানা ব্যবহার করা উচিত নয় - এমনকি এগুলি ছদ্মবেশী হতে পারে।

আপনি কোনও নন-পোস্ট পোর্টের মাধ্যমে সার্ভারের সাথে ফিরে সংযোগকারী ফ্ল্যাশ বা জাভা অ্যাপলেটটি ঠেকিয়ে ক্লায়েন্ট আইপি ঠিকানার আরও ভাল পরিমাপ পেতে পারেন (যার ফলে স্বচ্ছ প্রক্সি বা প্রক্সি-ইনজেকশনের শিরোনামগুলি মিথ্যা এমন ক্ষেত্রে প্রকাশিত হবে - মনে রাখবেন যে যেখানে ক্লায়েন্ট কেবলমাত্র একটি ওয়েব প্রক্সি বা আউটগোয়িং পোর্টের মাধ্যমে সংযোগ করতে পারে সেখানে অ্যাপলেট থেকে কোনও সংযোগ থাকবে না।

সি


বিবেচনায় নিয়ে আমি কেবল একটি পিএইচপি সমাধান সমাধানের সন্ধান করছি, আপনি $_SERVER['CLIENT_IP']কি বিবৃতি দিলে আমি দ্বিতীয় হিসাবে যুক্ত করার পরামর্শ দিচ্ছি ?
কোরি বলিউ

না - কেবলমাত্র যদি আপনি ফিরে আসা তথ্যের উপরে কোনও তাত্পর্য রাখতে চান, তবে নেটওয়ার্কের শেষ পয়েন্টের ঠিকানা (ক্লায়েন্ট আইপি) পাশাপাশি প্রক্সি অ্যাডেড শিরোনামগুলিতে আলাদা মান বোঝানোর জন্য যে কোনও কিছু সংরক্ষণ করা ভাল ধারণা হবে eg প্রচুর 192.168.1.x ঠিকানা দেখুন তবে বিভিন্ন ক্লায়েন্ট
আইপিএস

1

আমি বুঝতে পারলাম উপরে আরও ভাল এবং আরও সংক্ষিপ্ত উত্তর রয়েছে, এবং এটি কোনও ফাংশন বা চারপাশের সবচেয়ে কৌতূহলী স্ক্রিপ্ট নয়। আমাদের ক্ষেত্রে আমাদের স্পোফযোগ্য x_forwarded_for এবং আরও নির্ভরযোগ্য রিমোট_এডিআর উভয়ই প্রতি-প্রতি সরল সুইচটিতে আউটপুট করতে হবে। এটি অন্য ফাংশনগুলিতে ইনজেকশনের জন্য ফাঁকাগুলিকে অনুমতি দেওয়ার দরকার ছিল যদি না-না হয় বা যদি একা থাকে (কেবলমাত্র পূর্বরূপিত ফাংশনটি ফিরিয়ে দেওয়ার চেয়ে)। প্ল্যাটফর্ম সেটিংসের জন্য এটি প্রতি সুইচ কাস্টমাইজড লেবেল (গুলি) সহ একটি "চালু বা বন্ধ" বৈচিত্র্যের প্রয়োজন। অনুরোধের উপর নির্ভর করে ip আইপি-র গতিশীল হওয়ার জন্যও এটির একটি উপায় প্রয়োজন ছিল যাতে এটি ফরওয়ার্ড_ফর্ম রূপ নেয়।

এছাড়াও আমি কাউকে অ্যাডসেট () বনাম! খালি () এর ঠিকানা দেখতে পাইনি - x_forwarded_ এর জন্য এখনও কিছু প্রবেশ করা সম্ভব নয় কারণ এখনও ফাঁকা ভেরির ফলস্বরূপ isset () এর সত্যতা পাওয়া যায়, এর আশেপাশে আসার একটি উপায় হল && ব্যবহার করা এবং উভয়কে শর্ত হিসাবে একত্রিত করা। মনে রাখবেন আপনি "পিডব্লিউএনইডি" এর মতো শব্দগুলিকে x_forwarded_ হিসাবে ছদ্মবেশী করতে পারেন যাতে আপনার আউটপুটটি কোথাও সুরক্ষিত বা ডিবিতে রেকর্ড করা হয় তা নিশ্চিত করেই আপনি আসল আইপি সিনট্যাক্সে জীবাণুমুক্ত হন।

এছাড়াও, x_forwarder_for এ অ্যারে দেখতে আপনার যদি কোনও মাল্টি-প্রক্সির প্রয়োজন হয় তবে আপনি গুগল অনুবাদ ব্যবহার করে পরীক্ষা করতে পারেন। আপনি যদি পরীক্ষা করতে হেডারদের ফাঁকি দিতে চান, তবে এটি Chrome ক্লায়েন্ট শিরোনামের প্রসারণ এক্সটেনশানটি দেখুন। এটি আন প্রক্সির পিছনে থাকাকালীন কেবল মানক দূরবর্তী_অ্যাড্রিতে ডিফল্ট হবে।

আমি যেখানেই রিমোট_আড্ডার খালি থাকতে পারি তার কোনও কারণ নেই, তবে এটি কেবল ক্ষেত্রে ফ্যালব্যাক হিসাবে রয়েছে।

// proxybuster - attempts to un-hide originating IP if [reverse]proxy provides methods to do so
  $enableProxyBust = true;

if (($enableProxyBust == true) && (isset($_SERVER['REMOTE_ADDR'])) && (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) && (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))) {
    $ip = end(array_values(array_filter(explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']))));
    $ipProxy = $_SERVER['REMOTE_ADDR'];
    $ipProxy_label = ' behind proxy ';
} elseif (($enableProxyBust == true) && (isset($_SERVER['REMOTE_ADDR']))) {
    $ip = $_SERVER['REMOTE_ADDR'];
    $ipProxy = '';
    $ipProxy_label = ' no proxy ';
} elseif (($enableProxyBust == false) && (isset($_SERVER['REMOTE_ADDR']))) {
    $ip = $_SERVER['REMOTE_ADDR'];
    $ipProxy = '';
    $ipProxy_label = '';
} else {
    $ip = '';
    $ipProxy = '';
    $ipProxy_label = '';
}

নীচে ফাংশন (গুলি) বা ক্যোয়ারী / প্রতিধ্বনি / দর্শনগুলিতে ব্যবহারের জন্য এগুলি গতিশীল করার জন্য, লগ জেন বা ত্রুটি প্রতিবেদনের জন্য বলুন, গ্লোবালগুলি ব্যবহার করুন বা আপনার ইচ্ছামতো যেখানে ইচ্ছুক সেখানে ইকো করুন অন্যান্য শর্ত বা স্ট্যাটিক-স্কিমা-আউটপুট তৈরি না করেই ফাংশন।

function fooNow() {
    global $ip, $ipProxy, $ipProxy_label;
    // begin this actions such as log, error, query, or report
}

আপনার সমস্ত দুর্দান্ত চিন্তাভাবনার জন্য আপনাকে ধন্যবাদ। যদি এটি আরও ভাল হতে পারে তবে দয়া করে আমাকে জানান, এখনও এই শিরোনামগুলিতে নতুন নতুন :)


1

আমি এই ফাংশনটি নিয়ে এসেছি যা কেবল আইপি ঠিকানাটি দেয় না তবে আইপি তথ্য সহ একটি অ্যারে দেয়।

// Example usage:
$info = ip_info();
if ( $info->proxy ) {
    echo 'Your IP is ' . $info->ip;
} else {
    echo 'Your IP is ' . $info->ip . ' and your proxy is ' . $info->proxy_ip;
}

ফাংশনটি এখানে:

/**
 * Retrieves the best guess of the client's actual IP address.
 * Takes into account numerous HTTP proxy headers due to variations
 * in how different ISPs handle IP addresses in headers between hops.
 *
 * @since 1.1.3
 *
 * @return object {
 *         IP Address details
 *
 *         string $ip The users IP address (might be spoofed, if $proxy is true)
 *         bool $proxy True, if a proxy was detected
 *         string $proxy_id The proxy-server IP address
 * }
 */
function ip_info() {
    $result = (object) array(
        'ip' => $_SERVER['REMOTE_ADDR'],
        'proxy' => false,
        'proxy_ip' => '',
    );

    /*
     * This code tries to bypass a proxy and get the actual IP address of
     * the visitor behind the proxy.
     * Warning: These values might be spoofed!
     */
    $ip_fields = array(
        'HTTP_CLIENT_IP',
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_FORWARDED',
        'HTTP_X_CLUSTER_CLIENT_IP',
        'HTTP_FORWARDED_FOR',
        'HTTP_FORWARDED',
        'REMOTE_ADDR',
    );
    foreach ( $ip_fields as $key ) {
        if ( array_key_exists( $key, $_SERVER ) === true ) {
            foreach ( explode( ',', $_SERVER[$key] ) as $ip ) {
                $ip = trim( $ip );

                if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) !== false ) {
                    $forwarded = $ip;
                    break 2;
                }
            }
        }
    }

    // If we found a different IP address then REMOTE_ADDR then it's a proxy!
    if ( $forwarded != $result->ip ) {
        $result->proxy = true;
        $result->proxy_ip = $result->ip;
        $result->ip = $forwarded;
    }

    return $result;
}

1

যেমনটি আগে কেউ বলেছিল, এখানে কী কী কারণে আপনি ব্যবহারকারীর আইপিস সংরক্ষণ করতে চান তা এখানে রয়েছে।

আমি একটি নিবন্ধকরণ সিস্টেমের একটি উদাহরণ দেব যা আমি কাজ করি এবং অবশ্যই আমার সন্ধানে ঘন ঘন আসা আসা এই পুরাতন আলোচনায় সমাধানের অবদান রাখব।

অনেক পিএইচপি নিবন্ধন লাইব্রেরি ব্যবহার আইপি আউট ব্যর্থ ব্যবহারকারীর আইপি উপর ভিত্তি করে করার জন্য প্রচেষ্টার সংখ্যা শ্বাসনালী / লক। এই টেবিলটি বিবেচনা করুন:

-- mysql
DROP TABLE IF EXISTS `attempts`;
CREATE TABLE `attempts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ip` varchar(39) NOT NULL, /*<<=====*/
  `expiredate` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 -- sqlite
...

তারপরে, যখন কোনও ব্যবহারকারী কোনও লগইন বা পাসওয়ার্ড পুনরায় সেট করার মতো সার্ভিসিং সম্পর্কিত কিছু করার চেষ্টা করে, তখন একটি ক্রিয়াকলাপ শুরুতে ডাকা হয়:

public function isBlocked() {
      /*
       * used one of the above methods to capture user's ip!!!
       */
      $ip = $this->ip;
      // delete attempts from this ip with 'expiredate' in the past
      $this->deleteAttempts($ip, false);
      $query = $this->dbh->prepare("SELECT count(*) FROM {$this->token->get('table_attempts')} WHERE ip = ?");
      $query->execute(array($ip));
      $attempts = $query->fetchColumn();
      if ($attempts < intval($this->token->get('attempts_before_verify'))) {
         return "allow";
      }
      if ($attempts < intval($this->token->get('attempts_before_ban'))) {
         return "captcha";
      }
      return "block";
   }

উদাহরণস্বরূপ বলুন, $this->token->get('attempts_before_ban') === 10এবং 2 ব্যবহারকারী একই আইপিএসের জন্য আসে আগের কোডগুলিতে যেমন শিরোনামকে ছদ্মবেশী করা যায় , তারপরে 5 টি চেষ্টা করার পরে উভয়কেই নিষিদ্ধ করা হয় ! সবচেয়ে খারাপ, যদি সমস্ত একই প্রক্সি থেকে আসে তবে কেবল প্রথম 10 জন ব্যবহারকারী লগইন হবে এবং বাকি সমস্তগুলি নিষিদ্ধ করা হবে!

এখানে সমালোচনাটি হ'ল আমাদের টেবিলে একটি অনন্য সূচক প্রয়োজন attemptsএবং আমরা এটি একটি সংমিশ্রণ থেকে এটি পেতে পারি:

 `ip` varchar(39) NOT NULL,
 `jwt_load varchar(100) NOT NULL

যেখানে jwt_loadএকটি HTTP কুকি অনুসরণ থেকে আসে JSON ওয়েব টোকেন প্রযুক্তি যেখানে আমরা শুধুমাত্র সংরক্ষণ এনক্রিপ্ট পে লোড যে উচিত প্রত্যেক ব্যবহারকারীর জন্য একটি অবাধ / অনন্য মান ধারণ করে। অবশ্যই অনুরোধটি এটিকে সংশোধন করা "SELECT count(*) FROM {$this->token->get('table_attempts')} WHERE ip = ? AND jwt_load = ?"উচিত: এবং ক্লাসটিও একটি শুরু করা উচিত private $jwt


0

আমি বিস্মিত হই যদি সম্ভবত বিপরীত ক্রমে বিস্ফোরিত HTTP_X_FORWARDED_FOR এর উপরে আপনার পুনরুক্তি করা উচিত, যেহেতু আমার অভিজ্ঞতাটি হ'ল ব্যবহারকারীর আইপি ঠিকানাটি কমা-বিচ্ছিন্ন তালিকার শেষে শেষ হয়, তাই আপনি শিরোনামের শুরুতে শুরু করে, আপনি প্রত্যাবর্তিত প্রক্সিগুলির মধ্যে একটির আইপি ঠিকানা পাওয়ার সম্ভাবনা বেশি, এটি সম্ভবত প্রক্সিটির মাধ্যমে অনেক ব্যবহারকারী আসতে পারে বলে সম্ভবত সেশন হাইজ্যাকিংয়ের অনুমতি দিতে পারে।


1
উপর HTTP_X_FORWARDED_FOR উইকিপিডিয়া পৃষ্ঠা পড়া রয়ে: en.wikipedia.org/wiki/X-Forwarded-For ... আমি প্রস্তাব অর্ডার প্রকৃতপক্ষে, ডানদিকে যেমন আপনার কোড এটা আছে বাম দেখুন। তবে, আমাদের লগগুলি থেকে আমি দেখতে পাচ্ছি যে অনেকগুলি ক্ষেত্রেই বন্যের প্রক্সিগুলির দ্বারা এটি সম্মান করা হয়নি এবং আপনার যে আইপি ঠিকানাটি যাচাই করতে চান তা তালিকার উভয় প্রান্তে থাকতে পারে।
ক্রিস উইথারস

1
বা মাঝামাঝি সময়ে, যদি কিছু প্রক্সিগুলি বাম থেকে ডান ক্রমকে সম্মান করে এবং অন্যরা তা না করে।
ব্রিলিয়ান্ড

0

এই জন্য ধন্যবাদ, খুব দরকারী।

কোডটি সিনথেটিকভাবে সঠিক ছিল কিনা তা সাহায্য করবে। 20 লাইনের আশেপাশে অনেকগুলি there's অনেকগুলি I'm

আমি পাগল হতে পারি, তবে কয়েকটি বৈধ এবং অবৈধ ঠিকানার উপর চেষ্টা করার পরে, বৈধতা_আইপি () এর একমাত্র সংস্করণটি এটি ছিল:

    public function validate_ip($ip)
    {
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE) === false)
            return false;
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) === false)
            return false;
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false)
            return false;

        return true;
    }

0

আপনি যদি ক্লাউডফ্লেয়ার ক্যাচিং লেয়ার পরিষেবাদি ব্যবহার করেন তবে এখানে একটি পরিবর্তিত সংস্করণ রয়েছে

function getIP()
{
    $fields = array('HTTP_X_FORWARDED_FOR',
                    'REMOTE_ADDR',
                    'HTTP_CF_CONNECTING_IP',
                    'HTTP_X_CLUSTER_CLIENT_IP');

    foreach($fields as $f)
    {
        $tries = $_SERVER[$f];
        if (empty($tries))
            continue;
        $tries = explode(',',$tries);
        foreach($tries as $try)
        {
            $r = filter_var($try,
                            FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 |
                            FILTER_FLAG_NO_PRIV_RANGE |
                            FILTER_FLAG_NO_RES_RANGE);

            if ($r !== false)
            {
                return $try;
            }
        }
    }
    return false;
}

0

উত্তরের একটি ভিবি.এনইটি সংস্করণ:

Private Function GetRequestIpAddress() As IPAddress
    Dim serverVariables = HttpContext.Current.Request.ServerVariables
    Dim headersKeysToCheck = {"HTTP_CLIENT_IP", _
                              "HTTP_X_FORWARDED_FOR", _
                              "HTTP_X_FORWARDED", _
                              "HTTP_X_CLUSTER_CLIENT_IP", _
                              "HTTP_FORWARDED_FOR", _
                              "HTTP_FORWARDED", _
                              "REMOTE_ADDR"}
    For Each thisHeaderKey In headersKeysToCheck
        Dim thisValue = serverVariables.Item(thisHeaderKey)
        If thisValue IsNot Nothing Then
            Dim validAddress As IPAddress = Nothing
            If IPAddress.TryParse(thisValue, validAddress) Then
                Return validAddress
            End If
        End If
    Next
    Return Nothing
End Function

3
প্রশ্নে "পিএইচপি" ট্যাগ রয়েছে
লুচানিনভ

0

অন্য একটি পরিষ্কার উপায়:

  function validateIp($var_ip){
    $ip = trim($var_ip);

    return (!empty($ip) &&
            $ip != '::1' &&
            $ip != '127.0.0.1' &&
            filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false)
            ? $ip : false;
  }

  function getClientIp() {
    $ip = @$this->validateIp($_SERVER['HTTP_CLIENT_IP']) ?:
          @$this->validateIp($_SERVER['HTTP_X_FORWARDED_FOR']) ?:
          @$this->validateIp($_SERVER['HTTP_X_FORWARDED']) ?:
          @$this->validateIp($_SERVER['HTTP_FORWARDED_FOR']) ?:
          @$this->validateIp($_SERVER['HTTP_FORWARDED']) ?:
          @$this->validateIp($_SERVER['REMOTE_ADDR']) ?:
          'LOCAL OR UNKNOWN ACCESS';

    return $ip;
  }

0

সিমফনির অনুরোধ শ্রেণি থেকে https://github.com/symfony/symfony/blob/1bd125ec4a01220878b3dbc3ec3156b073996af9/src/Symfony/Comp घटक/HttpFoundation/Request.php

const HEADER_FORWARDED = 'forwarded';
const HEADER_CLIENT_IP = 'client_ip';
const HEADER_CLIENT_HOST = 'client_host';
const HEADER_CLIENT_PROTO = 'client_proto';
const HEADER_CLIENT_PORT = 'client_port';

/**
 * Names for headers that can be trusted when
 * using trusted proxies.
 *
 * The FORWARDED header is the standard as of rfc7239.
 *
 * The other headers are non-standard, but widely used
 * by popular reverse proxies (like Apache mod_proxy or Amazon EC2).
 */
protected static $trustedHeaders = array(
    self::HEADER_FORWARDED => 'FORWARDED',
    self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',
    self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST',
    self::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
    self::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT',
);

/**
 * Returns the client IP addresses.
 *
 * In the returned array the most trusted IP address is first, and the
 * least trusted one last. The "real" client IP address is the last one,
 * but this is also the least trusted one. Trusted proxies are stripped.
 *
 * Use this method carefully; you should use getClientIp() instead.
 *
 * @return array The client IP addresses
 *
 * @see getClientIp()
 */
public function getClientIps()
{
    $clientIps = array();
    $ip = $this->server->get('REMOTE_ADDR');
    if (!$this->isFromTrustedProxy()) {
        return array($ip);
    }
    if (self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) {
        $forwardedHeader = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]);
        preg_match_all('{(for)=("?\[?)([a-z0-9\.:_\-/]*)}', $forwardedHeader, $matches);
        $clientIps = $matches[3];
    } elseif (self::$trustedHeaders[self::HEADER_CLIENT_IP] && $this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) {
        $clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP])));
    }
    $clientIps[] = $ip; // Complete the IP chain with the IP the request actually came from
    $firstTrustedIp = null;
    foreach ($clientIps as $key => $clientIp) {
        // Remove port (unfortunately, it does happen)
        if (preg_match('{((?:\d+\.){3}\d+)\:\d+}', $clientIp, $match)) {
            $clientIps[$key] = $clientIp = $match[1];
        }
        if (!filter_var($clientIp, FILTER_VALIDATE_IP)) {
            unset($clientIps[$key]);
        }
        if (IpUtils::checkIp($clientIp, self::$trustedProxies)) {
            unset($clientIps[$key]);
            // Fallback to this when the client IP falls into the range of trusted proxies
            if (null ===  $firstTrustedIp) {
                $firstTrustedIp = $clientIp;
            }
        }
    }
    // Now the IP chain contains only untrusted proxies and the client IP
    return $clientIps ? array_reverse($clientIps) : array($firstTrustedIp);
}

অপরিবর্তিত সম্পত্তি: $ সার্ভার
C47

0

আমি অবাক হয়েছি কেউই ফিল্টার_ইনপুট উল্লেখ করেনি, তাই এখানে অ্যালিক্স অ্যাক্সেলের উত্তরটি এক-লাইনে সংশ্লেষিত হয়েছে:

function get_ip_address(&$keys = ['HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'])
{
    return empty($keys) || ($ip = filter_input(INPUT_SERVER, array_pop($keys), FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE))? $ip : get_ip_address($keys);
}

-1

আপনি আপনার নিজের প্রশ্নের উত্তর দিয়েছেন! :)

function getRealIpAddr() {
    if(!empty($_SERVER['HTTP_CLIENT_IP']))   //Check IP address from shared Internet
    {
        $IPaddress = $_SERVER['HTTP_CLIENT_IP'];
    }
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //To check IP address is passed from the proxy
    {
        $IPaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    else
    {
        $IPaddress = $_SERVER['REMOTE_ADDR'];
    }
    return $IPaddress;
}

সূত্র


-6
/**
 * Sanitizes IPv4 address according to Ilia Alshanetsky's book
 * "php|architect?s Guide to PHP Security", chapter 2, page 67.
 *
 * @param string $ip An IPv4 address
 */
public static function sanitizeIpAddress($ip = '')
{
if ($ip == '')
    {
    $rtnStr = '0.0.0.0';
    }
else
    {
    $rtnStr = long2ip(ip2long($ip));
    }

return $rtnStr;
}

//---------------------------------------------------

/**
 * Returns the sanitized HTTP_X_FORWARDED_FOR server variable.
 *
 */
public static function getXForwardedFor()
{
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
    {
    $rtnStr = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
elseif (isset($HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR']))
    {
    $rtnStr = $HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR'];
    }
elseif (getenv('HTTP_X_FORWARDED_FOR'))
    {
    $rtnStr = getenv('HTTP_X_FORWARDED_FOR');
    }
else
    {
    $rtnStr = '';
    }

// Sanitize IPv4 address (Ilia Alshanetsky):
if ($rtnStr != '')
    {
    $rtnStr = explode(', ', $rtnStr);
    $rtnStr = self::sanitizeIpAddress($rtnStr[0]);
    }

return $rtnStr;
}

//---------------------------------------------------

/**
 * Returns the sanitized REMOTE_ADDR server variable.
 *
 */
public static function getRemoteAddr()
{
if (isset($_SERVER['REMOTE_ADDR']))
    {
    $rtnStr = $_SERVER['REMOTE_ADDR'];
    }
elseif (isset($HTTP_SERVER_VARS['REMOTE_ADDR']))
    {
    $rtnStr = $HTTP_SERVER_VARS['REMOTE_ADDR'];
    }
elseif (getenv('REMOTE_ADDR'))
    {
    $rtnStr = getenv('REMOTE_ADDR');
    }
else
    {
    $rtnStr = '';
    }

// Sanitize IPv4 address (Ilia Alshanetsky):
if ($rtnStr != '')
    {
    $rtnStr = explode(', ', $rtnStr);
    $rtnStr = self::sanitizeIpAddress($rtnStr[0]);
    }

return $rtnStr;
}

//---------------------------------------------------

/**
 * Returns the sanitized remote user and proxy IP addresses.
 *
 */
public static function getIpAndProxy()
{
$xForwarded = self::getXForwardedFor();
$remoteAddr = self::getRemoteAddr();

if ($xForwarded != '')
    {
    $ip    = $xForwarded;
    $proxy = $remoteAddr;
    }
else
    {
    $ip    = $remoteAddr;
    $proxy = '';
    }

return array($ip, $proxy);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.