Блокировать определенный IP-блок с моего сайта в PHP

10

Я хотел бы, например, заблокировать каждый IP из базы 89.95 (89.95..). У меня нет файлов .htaccess на моем сервере, поэтому мне придется делать это с помощью PHP.

if ($_SERVER['REMOTE_ADDR'] == "89.95.25.37") die();

Блокирует определенный IP-адрес. Как заблокировать все блоки IP?

Большое спасибо.

Теги:
ip

8 ответов

12
Лучший ответ

Попробуйте strpos()

if(strpos($_SERVER['REMOTE_ADDR'], "89.95") === 0)
{
    die();
}

Если вы заметили, оператор === гарантирует, что 89.95 находится на начальном IP-адреса. Это означает, что вы можете обезопасить столько IP-адресов, сколько захотите, и он будет блокировать независимо от того, какие числа приходят после него.

Например, все они будут заблокированы:

89.95 → 89.95.12.34, 89.95.1234.1, 89.95.1.1
89.95.6 → 89.95.65.34, 89.95.61.1, 89.95.6987

(некоторые из них не являются действительными IP-адресами, хотя)

  • 0
    хе-хе, я удивлен, что strpos здесь работает быстрее, чем substr
  • 0
    @zerkms это не должно вызывать удивления - strpos может немедленно вернуться, если тест не пройден, и ему не нужно выполнять копирование или распределение строк. Кроме того, я просто хотел отметить, что поведение меняется, если вы переключаетесь === для == , так что не делайте этого. Используйте три знака равенства.
Показать ещё 2 комментария
4

Используйте ip2long() для преобразования десятичного десятичного разряда в реальный IP-адрес. Тогда вы можете легко делать диапазоны.

Просто выполните ip2long() в верхнем и нижнем диапазонах, чтобы получить значение, а затем используйте их как константы в вашем коде.

Если вы знакомы с маскировкой подсети, вы можете сделать это следующим образом:

// Deny 10.12.*.*
$network = ip2long("10.12.0.0");
$mask = ip2long("255.255.0.0");
$ip = ip2long($_SERVER['REMOTE_ADDR']);
if (($network & $mask) == ($ip & $mask)) {
  die("Unauthorized");
}

Или, если вы знакомы с этим форматом 10.12.0.0/16:

// Deny 10.12.*.*
$network = ip2long("10.12.0.0");
$prefix = 16;
$ip = ip2long($_SERVER['REMOTE_ADDR']);
if ($network >> (32 - $prefix)) == ($ip >> (32 - $prefix)) {
  die("Unauthorized");
}

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

  • 0
    Спасибо! Вот как мы это делаем.
  • 0
    Достаточно ли будет просто исследовать $_SERVER{'REMOTE_HOST'} ? Потому что, возможно, пользователь использует прокси. Таким образом, есть некоторые другие параметры, которые вы должны проверить, например, REMOTE_ADDR или эти . Я прав? или делать то, что я связал, не полезно?
Показать ещё 1 комментарий
3

Преобразуйте пунктирный квадрат в целое число:

$ip = sprintf('%u', ip2long($_SERVER['REMOTE_ADDR']));

// only allow 10.0.0.0 – 10.255.255.255
if (!($ip >= 167772160 && $ip <=  184549375)) {
    die('Forbidden.');
}
  • 0
    В чем причина использования целых чисел здесь? сделать код более запутанным?
  • 0
    Это не значит, что это снижает полезность этого ответа, но Авторизация звучит скорее как слово «согласие», где избирается определенная группа людей. В этом случае вместо авторизации нескольких человек он не авторизует или запрещает нескольким людям. Поэтому я думаю, что лучшим словом будет «Запрещено».
Показать ещё 10 комментариев
1

Это всегда хорошо срабатывало для меня: Это проверяет правильные серверные переменные и сравнивает их со списком известных IP-адресов.. и да, PHP действительно понимает подстановочные знаки, поэтому используйте * внутри IP-адреса, помогая блокировать диапазоны IP-адресов.

// The blacklisted ips.
$denied_ips = array(
'1.2.3.4',
'2.3.*',
);

// The function to get the visitor IP.
function getUserIP(){
    //check ip from share internet
    if (!empty($_SERVER['HTTP_CLIENT_IP'])){
      $ip=$_SERVER['HTTP_CLIENT_IP'];
    }
    //to check ip is pass from proxy
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
      $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    } else {
      $ip=$_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}
//The user
$visitorIp = getUserIP();

// Now let search if this IP is blackliated
$status = array_search($visitorIp, $denied_ips);

// Let check if $status has a true OR false value.
if($status !== false){
    echo '<div class="error">Your IP has been banned! Stop spamming us!</div>';
    // header("Location: http://zombo.com");
    // exit; 
}

Там также отличная статья в скоропортящейся прессе: http://perishablepress.com/how-to-block-ip-addresses-with-php/

  • 0
    «и да, PHP понимает подстановочные знаки, поэтому использование * внутри IP помогает при блокировке диапазонов IP». Вы уверены, что? конкретная версия php может быть?
  • 0
    Запретить массив с перенаправлением заголовка отлично работает :)
1
$user_ip = $_SERVER['REMOTE_ADDR']; // get user ip

$denyIPs = array("111.111.111", "222.222.222", "333.333.333");
if (in_array ($user_ip, $denyIPs)) {
   // blocked ip
}
else {
   // not blocked
}
  • 0
    привет, я пытался использовать этот формат 222.222.222.0/15, но не работает ...
1

Сделайте подстроку:) Например, для блокировки 89.95.25. * Вы создаете подстроку IP, отсекая последние два числа и сравнивая его с "89.95.25".

0

используя код восстановления, используйте это для поиска по шаблону

// Now let search if this IP is blackliated
$status = false;
foreach($denied_ips as $val)
{
    if (strpos($val,'*') !== false)
    {
        if(strpos($visitorIp, array_shift(explode("*", $val))) === 0)
        {
            $status = true;
            break;
        }
    }
    else
    {
        if(strcmp($visitorIp, $val) === 0)
        {
            $status = true;
            break;
        }
    }
}
-1
$deny = array("111.111.111", "222.222.222", "333.333.333");

if (in_array($_SERVER['REMOTE_ADDR'], $deny)) {
    header("location:http://www.google.com/");
    exit();
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню