Скрипт бана PHP

Khvosticov Sergey
Сообщения: 201
Зарегистрирован: 31 дек 2009

Код: Выделить всё

<?php
$ip = getenv('REMOTE_ADDR');
$blocked = "xx.xx.xx.xx"; // Replace the x's with the IP address.
 
if (ereg($blocked,$ip))
{
echo "You Have Been Banned";
exit();
}
?>

Вот собственно мне был нужен , нашёл , выложил. :)
Были времена я срывался и падал вниз, но всегда успевал ухватиться за карниз...

Аватара пользователя
Distructor
Администратор
Сообщения: 1599
Зарегистрирован: 28 дек 2009
пара замечаний по коду:
1 для чего тут регулярное выражение не понятно, достаточно было проверять простым сравнением
2
В REMOTE_ADDR помещается IP-адрес клиента. При тестировании на локальной машине — этот адрес будет равен 127.0.0.1. Однако при тестировании в сети переменная вернёт IP-адрес клиента или последнего прокси-сервера через который клиент попал на сервер. Если клиент использует прокси-сервер узнать его IP-адрес можно при помощи переменной окружения HTTP_X_FORWARDED_FOR
хотя и HTTP_X_FORWARDED_FOR не всегда содержит нужное значение

если в качестве веб-сервера используется Apache то можно заблокировать доступ нескольким IP или подсетям и через .htaccess

Аватара пользователя
AgentSIB
Администратор
Сообщения: 328
Зарегистрирован: 17 май 2010
Вообще лучше использовать либо массив ИП, либо хранить их в базе. Ды и для динамических ип это не спасет. Когда то заморачивался, писал скрипт, который делал следующее: Если ИП в бане, выдавалось сообщения, а браузеру присваивался определенный кукис. Если пользователь переключался - кукис сохранялся и ИП автоматически добавлялся в бан лист, но на сутки, не больше, а старый удалялся. Ну и в этом духе) Конечно данный механизм тоже легко обходится, но уже сложнее.
Frustra fit per plura quod potest fieri per pauciora © Закон "Бритвы Оккама"

Аватара пользователя
Distructor
Администратор
Сообщения: 1599
Зарегистрирован: 28 дек 2009
Khvosticov Sergey
я разве что-то сказал про БД? )
просто указал на 2 недочета кода:
1 - создает ненужную нагрузку
2 - при бане одного пользователя забанит всех сидящих через этот прокси

Khvosticov Sergey
Сообщения: 201
Зарегистрирован: 31 дек 2009
Distructor писал(а):Khvosticov Sergey
я разве что-то сказал про БД? )
просто указал на 2 недочета кода:
1 - создает ненужную нагрузку
2 - при бане одного пользователя забанит всех сидящих через этот прокси

Например phpbb2 - разве бан утроен по другому ? - про написание кода я не говорю - там ведь если по айпи динамике банишь после смены айпи можно перерегиться , а потом вдруг тебе такой айпи попадёться и тебе будет бак как бы.
2.Какую нагрузку ?
3.Предложи свой вариант написания кода.
Были времена я срывался и падал вниз, но всегда успевал ухватиться за карниз...

Аватара пользователя
AgentSIB
Администратор
Сообщения: 328
Зарегистрирован: 17 май 2010
Про БД заговорил я, так как это более удобный способ добавление и удаления ИП из бана.
Насчет нагрузки - не такая уж она и большая, но использование в данном случае регулярных выражений неоправданное.
Для динамических ИП я уже предложил свой алгоритм завязанный еще так же и на кукисах, а для него нужен динамически обновляемый банлист, который лучше реализовать методами базы.

А по поводу прокси - к сожалению нет такого бана, который бы банил на 100% без привязки по ИП. Кукисы всегда можно удалить, а браузер поменять. Идеей супербана уже интересовался, но общего случая найти не удалось. Самое удачное что придумал - привязка кукисов и ИП. Однако данный тип бана обходится переходом на другой ип (переподключением) и одновременной чисткой куисов, либо сменой браузера.
Frustra fit per plura quod potest fieri per pauciora © Закон "Бритвы Оккама"

Аватара пользователя
Distructor
Администратор
Сообщения: 1599
Зарегистрирован: 28 дек 2009
Khvosticov Sergey писал(а):2.Какую нагрузку ?
в любом учебнике по регуляркам написано:
Не используйте функцию preg_match(), если необходимо проверить наличие подстроки в заданной строке. Используйте для этого strpos() либо strstr(), поскольку они выполнят эту задачу гораздо быстрее.

да и кстати функции ereg* помечены как DEPRECATED с PHP 5.3.0, вместо них надо использовать preg* функции.

Khvosticov Sergey писал(а):3.Предложи свой вариант написания кода.
если не рассматривать вопросы повышения взломостийкости, а только исправить приведенные выше недочеты кода, то получится примерно следующее:

Код: Выделить всё

<?php

    
// список забаненных IP
    $banned_ips = array(
        '11.11.11.11',
        '22.22.22.22'
    );

    // функция для определения IP пользователя
    function getClientIp()
    {
        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
            return $_SERVER['HTTP_CLIENT_IP'];
        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            return $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else {
            return $_SERVER['REMOTE_ADDR'];
        }
    }

    if ( array_search( getClientIp(), $banned_ips ) !== false )
    {
        echo "You Have Been Banned";
        exit();
    }

?>
p.s. если список забаненных IP хранится в БД, то правильнее искать соответствие средствами самой СУБД (например через sql запрос "SELECT * FROM bans WHERE ban_ip='".getClientIp()."'"), чем вытаскивать все записи и потом сравнивать.
p.p.s. естественно если прокси не отдает реальный IP пользователя то мы его получить никак не сможем

хотя конечно правильнее дополнительно в момент бана записывать куки пользователю и проверять их наличие до проверки бана по IP


Вернуться в «PHP»