Ограничение доступа к сайту с использованием IP-адреса

Я хотел бы знать, есть ли способ ограничить пользователей сайта таким образом, чтобы они могли получать доступ только к внутренним страницам сайта, если они находятся в определенном диапазоне IP-адресов или определенной сети?

Текущие PHP-скрипты, которые я получаю, не могут отличить реальные IP-адреса от Proxies?

благодаря

я бы не ограничивал ip-адреса. как вы сказали, вы не можете знать, является ли это прокси. Кроме того, IP-адреса могут быть легко подделаны.

Вы рассматривали использование файлов apache .htaccess для этого? Ограничение IP с помощью htaccess

Вы можете попробовать скрипт, который я создал, который позволяет очень продвинутые правила 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 # # xy - 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 fucked up hybrid mother fuckers? 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 fuck? return IPID_INVALID; } } ?> 

Вы можете использовать его, если не пытаетесь перепродать его, и сохраняете заголовок как есть.

Прокси-серверы должны установить HTTP-заголовок X-Forwarded-For , который вы можете найти с помощью $_SERVER['HTTP_X_FORWARDED_FOR'] . В противном случае для получения IP-адреса можно использовать $_SERVER['REMOTE_ADDR'] . Как отмечали другие, обе эти функции могут быть легко подделаны, и нет необходимости в том, чтобы прокси устанавливали заголовок запроса X-Forwarded-For .

В PHP есть функция ip2long() которая дает вам целое число для проверки диапазона.

Чтобы получить местоположение IP-адреса, вам нужна таблица поиска, которая отображает диапазоны IP-адресов для приближения географических местоположений (такие таблицы поиска обычно не являются бесплатными). Существует множество услуг, которые предлагают географическую привязку IP-адресов, некоторые из которых упоминаются здесь и здесь .

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