1. Гость, мы просим Вас ознакомиться с Правилами Форума и Отказом от ответственности!

Модуль для защиты сайта/форума/реги от флуда

Тема в разделе 'PHP', создана пользователем dead_bot, 21 окт 2010.

  1. TopicStarter Overlay

    dead_bot Пользователи

    Сообщения:
    7
    Лайки:
    1
    Репутация:
    0
    Данным скриптом и подобными ему уже давно пользуются огромное количество проектов (подобие данного скрипта стоит и в движке этого форума).
    Данный скрипт не является моей интелектуальной собственностью . Автором скрипта является Дмитрий Бородин , за что ему огромное спасибо !

    И так ! Вот он :

    Код:
    
    <?
    /*
    =================================================================
    _DIMA_NOFLOOD.PHP, version 1.1, 2002-11-11
    =================================================================
    
    (c) Dmitry Borodin
    
    
    Что это:
    
    Модуль защиты от флуда PHP-сайтов методом частых вызовов 
    PHP-файлов, для создания большой нагрузки. Защищает так же
    от автоматического выкачивания сайта с одного IP.
    
    =================================================================
    
    Описание
    ~~~~~~~~
    Для подключения этого модуля напишите include("_dima_noflood.php")
    в самом начале вашей программы. В случае флуда этот модуль завершит
    работу по команде exit. При нормальной работе - только увеличит 
    счетчики загрузок и никак не отразится на вашем скрипте.
    
    Для настройки программы создайте сколько угодно правил на разное 
    кол-во секунд. Например, первое правило "не более 11 загрузок за 10 
    секунд" надо записать как "$nf_flood[10]=>11". Если хочется второе
    правило, допустим "не более 200 загрузок за час", то 
    дополнительно в тот же массив надо дописать "$nf_flood[3600]=>200" 
    (3600 - это 1 час). Правил может быть любое кол-во (но чем меньше,
    тем быстрее работает).
    
    Если по какому либо правилу возникает флуд, т.е. кол-во загрузок 
    за последние Х секунд превысило N заданных раз, то происходит 
    следующее:
    1. доступ для этого IP-адреса закрывается
    2. остальные правила как считали, так и продолжают считать/следить
    за допустимой нагрузкой
    3. сработавшее на флуд правило запоминает текущее время каждого 
    обращения, из-за чего при регулярных продолжениях вызовов сайта
    этот счетчик не будет никогда сброшен
    Сработавшее флуд-правило очистит счетчик запросов, т.е. снимет игнор,
    только если в течении Х секунд к сайту не будет ни одного запроса.
    Если сработало правило флуда на 5 минут, то пользователь-флудер 
    должен покинуть ваш сайт минимум на 5 минут. Если этот пользователь
    обратится через 4 минуты на сайт, то время окончания игнора повторно 
    увеличится на 5 минут. Таким образом, это очень продвинута защита от 
    скачиваний - стоит программе превысить любое из правил флуда, 
    то повторные попытка что-то скачать только оттянут время снятия 
    игнора. Дополнительно это приведет к срабатыванию более строгих 
    правил, например на 60 минут (и придется уже минимум 60 минут 
    не обращаться к сайту, чтобы игнор был сброшен).
    
    Раз в $nf_cron_run секунд запускается функция поиска старых файлов,
    которые устарели не менее, чем на $nf_old_file секунд. По-умолчанию,
    поиск производится раз в 20 минут, при котором стираются все файлы,
    которые устарели минимум на 2 часа. Внимание! Программа стирает ВСЕ
    файлы в своем каталоге ($nf_path), которые не начинаются с ".". 
    Поэтому, чтобы закрыть каталог от доступа через браузер, положите
    туда файл ".htaccess" из 2х строк:
    Order Allow,Deny
    Deny from all
    
    Кроме проверки на флуд программа не позволит вызвать ни одного 
    вашего PHP-скрипта параллельно. Т.е. если идет параллельный вызов,
    а старый вызов (и процесс с PHP-скриптом) еще не закончился,
    то более новый запрос будет отвергнут. Это достигается простым 
    открытием файла. Файл после открытия не закрывается, из-за чего 
    остается блокированным на весь период работы вашего скрипта.
    
    Сообщения/ошибки:
    - в случае параллельного вызова программа пишет 
    "Parallel processing disable." и завершает работу
    - при достижении флуда программа пишет "Flood detect!" и завершается
    - если невозможно открыть файл на запись/чтение, то программа пишет 
    короткое имя файла (без каталога) и причину, работа не прерывается,
    т.е. ваш скрипт получит управление (такие ошибки возможны только 
    при первоначальной настройке программы)
    
    Когда вы меняете набор флуд правил в $nf_flood, то сразу после этого 
    стирайте все файла в каталоге $nf_path!
    
    =================================================================
    */
    
    //
    // Путь к каталогу, где будут копится файлы
    // В этом каталоге будут стерты все файлы, кроме тех, что начинаются 
    // с "." в имени.
    //
    // ОБЯЗАТЕЛЬНО ЗАДАЙТЕ КАТАЛОГ ДЛЯ ВРЕМЕННЫХ ФАЙЛОВ:
    //
    //$nf_path=getenv("DOCUMENT_ROOT")."/tmp-ip/";
    
    //exit(getcwd());
    $nf_path="/var/www/data/talken/tmp-ip/";
    
    // имя файла для юзера - генерится из его IP-адреса
    $nf_fip=$nf_path.getenv("REMOTE_ADDR");
    
    // имя файла для встроенного крона (должно начинаться с точки)
    $nf_fcron=$nf_path.".time";
    
    //
    // сек  => кол-во
    //
    //    не более скольки загрузок за сколько секунд можно сделать, 
    //    чтобы не получить игнор
    //
    $nf_flood=array(
    10   => 10,      // не более 10 загрузок за 10 секунд
    60   => 30,      // не более 30 загрузок за минуту
    300  => 50,      // не более 50 загрузок за 5 минут
    3600 => 200,     // не более 200 загрузок за час
    );
    
    $nf_cron_run=1200; // раз в сколько секунд проверять старые файлы
    
    $nf_old_file=7200; // через сколько секунд считать файл старым (и удалять)
    
    
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    
    
    
    function cron_update($fn,$update) {
    
    if (!file_exists($fn)) {
    if (!@touch($fn)) {
    echo "не могу создать <b>".basename($fn)."</b>, проверьте права на файлы (w+)<br>";
    return -1;
    }
    }
    else { 
    if (time()-filemtime($fn)<$update) {return 0;}
    }
    
    $f=@fopen($fn,"r+");
    if (!$f) {
    echo "не могу открыть <b>".basename($fn)."</b>, проверьте права на файлы (r+)<br>";
    return -1;
    }
    if (!flock($f,6)) {return;}
    $text=fgets($f,100);
    if (time()-intval($text)<$update) {return 0;}
    fseek($f,0,SEEK_SET);
    fwrite($f,time()."    ");
    fclose($f);
    
    return 1;
    
    }
    
    
    $nf_cron_code=cron_update($nf_fcron,$nf_cron_run);
    if ($nf_cron_code==-1) return;
    if ($nf_cron_code==1) {
    if ($nf_dir=@opendir($nf_path)) {
    $nf_time=time()-$nf_old_file;
    while (($nf_tmp=readdir($nf_dir))!==false) {
    if ($nf_tmp[0]==".") continue;
    if (filemtime($nf_path.$nf_tmp)<$nf_time && 
    preg_match("!^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$!",$nf_tmp))
    {
    if (!unlink($nf_path.$nf_tmp)) {
    echo "не могу удалить <b>$nf_tmp</b><br>";
    }
    }
    }
    closedir($nf_dir);
    }
    }
    unset($nf_cron_code);
    
    
    if (file_exists($nf_fip)) {
    $nf_f=@fopen($nf_fip,"r+");
    if (!flock($nf_f,6)) exit("Parallel processing disable.");
    if (!$nf_f) {
    echo "не могу открыть <b>".basename($nf_fip)."</b> (r+)<br>";
    return;
    }
    $nf_buf=fgets($nf_f,1000);
    $nf_buf=explode("|",$nf_buf);
    }
    else {
    for ($nf_i=0; $nf_i<count($nf_flood)*2; $nf_i++) $nf_buf[]=0;
    $nf_f=@fopen($nf_fip,"a+");
    if (!$nf_f) {
    echo "не могу создать <b>".basename($nf_fip)."</b> (a+)<br>";
    return;
    }
    if (!flock($nf_f,6)) exit("Parallel processing disable.");
    }
    
    
    $nf_i=0;
    $nf_stopflag=0;
    
    //echo "<pre>";print_r($nf_buf);
    
    foreach ($nf_flood as $nf_k=>$nf_v) {
    if ($nf_buf[$nf_i+1]+$nf_k<time()) { 
    $nf_buf[$nf_i]=1;
    $nf_buf[$nf_i+1]=time();
    }
    else {
    if ($nf_buf[$nf_i]>$nf_v) {
    $nf_stopflag=1;
    $nf_buf[$nf_i+1]=time();
    }
    $nf_buf[$nf_i]++;
    }
    $nf_i+=2;
    }
    
    
    ftruncate($nf_f,0);
    fseek($nf_f,0);
    fputs($nf_f,implode("|",$nf_buf));
    
    //print_r($nf_buf);
    if ($nf_stopflag) exit("Flood detect!");
    
    unset($nf_f);
    unset($nf_i);
    unset($nf_k);
    unset($nf_v);
    unset($nf_stopflag);
    unset($nf_buf);
    unset($nf_fip);
    unset($nf_path);
    unset($nf_flood);
    unset($nf_cron_run);
    unset($nf_cron_idle);
    
    ?>
    
    
    
    

    Часто видел что на некоторых серверах в статистике онлайн 100-300 человек а акков в базе 6к+ человек .
    Правильно настроев скрип и заинклудив его в регу можно получить результат -> у человека 3 попытки зайти на страницу реги , после этого рега закрывается на 1-2 часа .
    Хотя... вы сами найдете ему применение ! :D
  2. TheMazzahaka Пользователи

    Сообщения:
    223
    Лайки:
    76
    Пол:
    Мужской
    Репутация:
    0
    Команда:
    J-Games Dev
    Динам IP\Прокси=Клал я на этот скриптЭ х)

    А так скрипт норм чо.
  3. TopicStarter Overlay

    dead_bot Пользователи

    Сообщения:
    7
    Лайки:
    1
    Репутация:
    0
    хм... надо будет подумать над этим...
  4. Botchal MMORPG-DEVS.RU Пользователи

    Сообщения:
    182
    Лайки:
    66
    Репутация:
    0
    Уже давно мною реализовано и выложено, у меня это называется антидос а тут анти частое вызывание файлов
Черновик сохранён Черновик удалён

Поделиться этой страницей