【问题标题】:Restricting access to a site using IP address使用 IP 地址限制对站点的访问
【发布时间】:2010-11-26 10:03:11
【问题描述】:

我想知道是否有办法限制网站的用户,使他们只能在一定的 IP 地址范围或特定的网络内访问网站的内页?

我得到的当前 PHP 脚本无法区分真实 IP 和代理?

谢谢

【问题讨论】:

    标签: php ip-address


    【解决方案1】:

    我不会限制 IP 地址。正如你所说,你不知道它是否是代理。此外,IP 地址很容易被欺骗。

    【讨论】:

    • 感谢您的回答,您对如何根据位置限制访问网站有什么建议吗?
    • 不,恐怕不会。你必须使用 IP 地址,但我知道没有办法“阻止代理”
    • 除了使用带有密码的 .htaccess 文件之外,使用验证 IP 地址就足够了。 htaccesstools.com/htpasswd-generator
    • 但是你只能使用密码……
    【解决方案2】:

    您是否考虑过为此使用 apache .htaccess 文件? IP restriction with htaccess

    【讨论】:

      【解决方案3】:

      代理服务器应设置X-Forwarded-For HTTP 标头,您可以使用$_SERVER['HTTP_X_FORWARDED_FOR'] 查找该标头。否则$_SERVER['REMOTE_ADDR'] 可以用来获取IP 地址。正如其他人所指出的,这两者都可以很容易地被欺骗,并且不需要代理设置 X-Forwarded-For 请求标头。

      在 PHP 中有一个 ip2long() 函数,它给你一个整数用于范围检查。

      要获取 IP 地址的位置,您需要一个将 IP 地址范围映射到大致地理位置的查找表(此类查找表通常不是免费的)。提供 IP 地址地理定位的服务有很多,其中一些提到了herehere

      【讨论】:

        【解决方案4】:

        您可以试用我创建的允许非常高级的 IP 规则的脚本。我在几年前编写了它,所以我提前为它的当前形状道歉。

        编辑: 如果您在语法中寻找“&”运算符,请不要打扰。我在编写代码时忘记添加它,现在回头看这个脚本让我一想到再次触摸它就畏缩不前。

        <?php
        ##############################################################
        # IP Expression Class                                        #
        # Easy IP-based Access Restrictions                          #
        # Change Log:                                                #
        # - Added Range and limited IPv6 support                     #
        # - Changed name from IPAR to IPEX                           #
        #                                #
        ##############################################################
        # Example Rules:                                             #
        # 69.[10-20].[^50].*                                         #
        # 69.*.[1-5 | 10-20 |^30].*                                  #
        # 60.12.2.*                                                  #
        # 127.*                                                      #
        # 69.1.1.1-70.1.1.1   <-- This is a range                    #
        #                                                            #
        # Usage:                                                     #
        # Ipex::IsMatch($rule, $ip);                                 #
        #                                                            #
        # [range] - Defines a range for a section of the IP          #
        # |   - OR token. IP can match this range/number         #
        # ^       - NOT token. IP can not match this range/number    #
        # x-y     - Defines a range from x to y                      #
        # x       - Exactly match x (x = a hex or dec number)        #
        # *       - Match any number                                 #
        #                                #
        #----------===============================-------------------#
        #           [ Written by Chris Tarquini ]                    #
        #----------===============================-------------------#
        ##############################################################
        
        define('IPR_DENY', false);
        define('IPR_ALLOW', true);
        define('IPR_ERR_MISMATCH',-1);
        define('IPR_ERR_RANGE_MISMATCH',-2);
        define('IPR_ERR_RANGE_INVALID',-3);
        define('IPR_ERR_INVALID_RULE',-4);
        
        class IPEX
        {
        
            const TOKEN_RANGE_BEGIN = '[';
            const TOKEN_RANGE_END = ']';
            const TOKEN_WILDCARD = '*';
            const TOKEN_RANGE_SPLIT = '-';
            const TOKEN_OR = '|';
            const TOKEN_NOT = '^';
            const DEBUG_MODE = TRUE;
        
            private static function trace($err){if(self::DEBUG_MODE) echo "$err\r\n";}
            private static function FixRule($rule,$count = 4, $split='.')
            {
                $rule = explode($split,$rule);
                $filler = 0;
                $size = sizeof($rule);
                for($i = 0; $i < $count; $i++)
                {
                    if($i > $size) { $rule[] = $filler; $size++;}
                    else if(empty($rule[$i])) { $filler = self::TOKEN_WILDCARD; $rule[$i] = $filler;}
                }
                return $rule;   
            }
        
            private static function FixIP($rule,$count = 4, $split='.')
            {
                $rule = explode($split,$rule);
                $size = sizeof($rule);
                for($i = 0;  $i < $count; $i++)
                {
                    if($i > $size) { $rule[] = 0; $size++;}
                    else if(empty($rule[$i])) { $rule[$i] = 0;}
                }
                return $rule;   
            }
            private static function GetIpType(&$ip)
            {
                $mode = IPID::Identify($ip,$newip);
                if($mode == IPID_IPv4_Embed) { $ip = $newip; return IPID_IPv4;}
                return $mode;
            }
            private static function FixIPRange(&$start, &$stop)
            {
                $count = 4; $split = '.';
                if(self::GetIpType($start) == IPID_IPv6) {$count = 8; $split = ':';}
        
                $q = 0;
                while($q < 2)
                {
                    $filler = ($q == 0) ? 0 : 255;
                    $arr = explode($split,($q == 0) ? $start : $stop);
                    $size = sizeof($arr);
                    for($i = 0; $i < $count; $i++)
                    {
                        if($i > $size){ $arr[] = $filler; $size++;}
                        else if(empty($arr[$i])){ $arr[$i] = $filler; }
                    }
                    if($q == 0) $start = implode($split, $arr);
                    else $stop = implode($split,$arr);
                    $q++;
                }
        
            }
            public static function IsInRange($start, $stop, $ip)
            {
                //Sorry guys we only support IPv4 for this ;(
                self::FixIPRange($start,$stop);
                self::trace("fixed: start = $start, stop = $stop");
                $start = ip2long($start); $stop = ip2long($stop);
                $ip = ip2long($ip);
                self::trace("start = $start, stop = $stop, ip = $ip");
                return ($ip >= $start && $ip <= $stop);
            }
            public static function IsAllowed($rule, $ip){return self::IsMatch($rule,$ip);}
            public static function IsMatch($rule,$ip)
            {
                $mode = self::GetIpType($ip);
                self::trace("ip type: $mode");
                if(strpos($rule, self::TOKEN_RANGE_SPLIT) !== false && strpos($rule,self::TOKEN_RANGE_BEGIN) === false)
                {
                    self::trace("ip range mode");
                    $test = explode(self::TOKEN_RANGE_SPLIT, $rule);
                    self::trace("range size: ".sizeof($test));
                    print_r($test);
                    if(sizeof($test) != 2) return IPR_ERR_RANGE_INVALID;
                    $start = $test[0]; $end = $test[1];
                    if(empty($start) || empty($end)) return IPR_ERR_RANGE_INVALID;
                    self::trace("range start: $start, range stop: $end");
                    $rm1 = (self::IsHex($start)) ? $mode : self::GetIpType($start);
                    $rm2 = (self::IsHex($end)) ? $mode : self::GetIpType($end);
                    self::trace("range types: $rm1, $rm2\r\nip type: $mode");
                    if($rm1 != $rm2  || $rm1 != $mode) return IPR_ERR_RANGE_MISMATCH;
                    if($mode == IPID_IPv6) { return IPR_ERR_IPv6_NOTSUPPORTED;}     
                    return self::IsInRange($start,$end,$ip);
                }
        
                if(self::GetIpType($rule) != $mode) return IPR_ERR_MISMATCH;
        
        
                //all is good so far
                $count = 4;
                $split = '.'; if($mode==IPID_IPv6){$count = 8; $split=':';}
                $rule = self::FixRule($rule, $count,$split);
        
                $ip = self::FixIp($ip,$count,$split);
                self::trace("ip: ".implode($split,$ip));
                self::trace('rule: '.implode($split,$rule));
                for($i = 0; $i < $count; $i++)
                {
                    $r = str_replace(' ', '', $rule[$i]);
                    $ri = false;
        if($r == self::TOKEN_WILDCARD) continue;
                    if($mode == IPPID_IPv6 && self::IsHex($r)) { $ri = hexdec($r);}else if(is_numeric($r)) $ri = $r;
        
        
                    $x = $ip[$i];
                    if($mode == IPPID_IPv6) $x = hexdec($x);
                    //* Exact Match *//
                    self::trace("rule[$i]: $ri");
                    self::trace("ip[$i]: $x");
                    if($ri !== false && $ri != $x) return IPR_DENY;
                    $len = strlen($r);
                    for($y = 0; $y < $len; $y++)
                    {
                        self::trace("y = $y");
                        if(substr($r, $y,1) == self::TOKEN_RANGE_BEGIN)
                        {
                            ++$y;
                            self::trace("found range, y = $y");
                            $negflag = false;
                            $start = false;
                            $stop = false;
                            $allows = 0;
                            $denys = 0;
                            $q = 0;
                            $c = substr($r,$y,1);
                            while($c !== false)
                            {
                                self::trace("in range, char: $c");
                                //* Flags *//
                                $break = false;
                                $exec = false;
                                $toggle = false;
                                $reset = false;
        
                                if($c === self::TOKEN_RANGE_END) {$skiphex = true;$break = true; $exec = true; self::trace("found end of range");}
                                if($c === self::TOKEN_NOT) {if($q > 0){ $toggle = true; $exec = true;} else $negflag = !$negflag; $skiphex =false; self::trace("found TOKEN_NOT");}
                                if($c === self::TOKEN_OR) { $exec = true; $reset = true;$skiphex=true;self::trace("found TOKEN_OR");} 
                                if($c === self::TOKEN_RANGE_SPLIT){ $skiphex = false;++$q; self::trace("found range split");}
        
                                //* Read Hex Tokens *//
                                if(!$skiphex && self::IsHexChar($c))
                                {
                                    $n = self::ReadNextHexToken($r,$y);
                                    if($mode == IPID_IPv6) $n = hexdec($n);
                                    if($q == 0) $start = $n;
                                    else if($q == 1) $stop = $n;
                                    --$y; //fixes error
                                    self::trace("parsed number: $n, y = $y");
                                }   
                                if($reset) {$negflag = false; $start = false; $stop = false;  $q = 0;}
                                if($exec)
                                {
                                    self::trace("executing: start = $start, stop = $stop, x = $x");
                                    self::trace("negflag = $negflag");
                                    if($stop !== false && $x >= $start && $x <= $stop)
                                    {
                                        if($negflag) { ++$denys; $allows = 0; break;}
                                        else ++$allows;
                                    }
                                    else if($stop === false && $start == $x)
                                    {
                                        if($negflag) { ++$denys; $allows = 0; break;}
                                        else ++$allows;
                                    }
                                    self::trace("exec complete: allows = $allows, denys = $denys"); 
                                    $q = 0;
                                }
                                if($toggle) $negflag = !$negflag;
                                if($break) break;
                                ++$y;
                                $c = substr($r,$y,1);
                            } 
                            if(!$allows) return IPR_DENY;
                        }
                    }
        
        
                }
                        return IPR_ALLOW;   
        
            }
            private static function ReadNextHexToken($buff, &$offset, $max = -1)
            {
                $str = '';
                if($max == -1) { $max = strlen($buff);}
                for(; $offset < $max; $offset++)
                {
                    $c = substr($buff,$offset, 1);
                    if(self::IsHexChar($c))
                        $str .= $c;
                    else
                        return $str;
                }
                return $str;
            }
            private static function IsHex($x){ $len = strlen($x); for($i = 0; $i < $len; $i++) if(!self::IsHexChar(substr($x,$i,1))) return false; return true;}
            private static function IsHexChar($x){self::trace("isHex($x);"); return (in_array(strtoupper($x),array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F')));
        }
        }
        
        
        
        ######################
        # IP Identify Class  #
        #####################
        define('IPID_INVALID',false);
        define('IPID_IPv4',2);
        define('IPID_IPv6',3);
        define('IPID_IPv4_Embed',6);
        
        class IPID
        {
        
                public static function Identify($ip,&$ipconvert = false)
                {
                        $ip = strtoupper($ip);
                        $ipconvert = $ip;
                        // Check if we are IPv4
                        if(strpos($ip,':') === false && strpos($ip,'.') !== false)
                                return IPID_IPv4;
                        //Is it one of those hybrids?
                        else if(strpos($ip,':FFFF') !== false && strpos($ip,'.') !== false)
                        {
                                $ipconvert = substr($ip,strpos($ip,':FFFF:')+6);
                                return IPID_IPv4_Embed;
                        }
                        // Is it IPv6?
                        else if(strpos($ip,':') !== false)  return IPID_IPv6;
                        // What the...?
                        return IPID_INVALID;
                }
        
        
        }
        ?>
        

        你可以使用它,只要你不尝试转售它并且保持标题不变。

        【讨论】:

          【解决方案5】:
          <?php
              //This function returns True if visitor IP is allowed.
              //Otherwise it returns False.
              function CheckAccess()
              {
                  //allowed IP. Change it to your static IP
                  $allowedip = '127.0.0.1';
                  $ip = $_SERVER['REMOTE_ADDR'];
                  return ($ip == $allowedip);
              }
          

          【讨论】:

            猜你喜欢
            • 2016-01-29
            • 1970-01-01
            • 2019-05-04
            • 2010-12-05
            • 2011-05-13
            • 1970-01-01
            • 1970-01-01
            • 2011-07-05
            • 2015-08-16
            相关资源
            最近更新 更多