Антиддос скрипты на PHP

Тема в разделе "Защита от Ddos-атак", создана пользователем Devider, 17 авг 2013.

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

    Выкладываю некоторые здесь. Если кому помогут - отписывайтесь, вместе посмеемся над этим ддосером.

    Но прежде чем использовать подобные скрипты, надо оценить обстановку.
    Если ваш хостер предоставляет SSH-доступ, попробуйте с помощью команды
    Код:
    netstat -ntu |wc -l
    определить силу ддоса. Команда выведет количество соединений. Если сервер совсем повис, попробуйте перезагрузить его (через службу поддержки или самостоятельно если такая возможность есть) и отрубите апач
    Код:
    service httpd stop
    если у вас nginx
    Код:
    service nginx stop
    либо, если ддос несильный, закоментируйте срочку _index.php в корне вашего сайта. После чего можно поизучать логи и оценить силу и таргетинг ддоса.

    Если ддос действительно слабенький, можно попробовать использовать PHP скрипты, но предупреждаю, они будут загружать сервер и годятся только как временное решение проблемы.


    Скрипт AntiOverload *FIX*
    Код:
    <?php
    /*
    *--------------------------------------------------------
    * Модуль antioverload
    *--------------------------------------------------------
    * Модуль предназначен для ограничения доступа к сайту или 
    * к страницам, где он включён.
    * Принцип работы в том, что запоминается ip-адрес и время
    * обращения с этого адреса. И если в течение заданного
    * времени происходит обращение с того же адреса, то ему
    * выдаётся ошибка 503.
    * Модуль необходимо подключать к скрипту самым первым.
    * Этим обеспечивается быстрота его работы.
    *--------------------------------------------------------
    */
     
    /* Время задержки в секундах */
    $ad_delay=2;
    /* Путь к папке с временными файлами. Должен существовать */
    $ad_DirName=$_SERVER['DOCUMENT_ROOT'].'/tmp';
     
    /*
    *---------------------------------------------------------
    * Список поисковых роботов.
    * Очень не хорошо, если поисковый робот будет натыкаться
    * на ошибки на сайте. Ему это может сильно не понравиться.
    * Поэтому пишем список юзер-агентов роботов; добавляем или
    * удаляем, что нужно.
    *---------------------------------------------------------
    */
    $ad_Robots_UserAgent=array(
      'aipbot',
      'Aport',
      'eStyleSearch',
      'Gigabot',
      'Gokubot',
      'Google',
      'MJ12bot',
      'msnbot',
      'PlantyNet_WebRobot',
      'StackRambler',
      'TurtleScanner',
      'Yahoo',
      'Yandex',
      'YaDirectBot',
    );
    /*
    *---------------------------------------------------------
    * Список доверенных IP.
    *---------------------------------------------------------
    */
    $ad_good_ip = array(
        '217.107.36.73',
    );
     
    /*
    *----------------------------------------------------------
    * Функция создаёт в указанной директории файл, начинающийся
    * с буквы a (для отличия от других возможных файлов) и
    * содержащий в имени ip-адрес клиента.
    *----------------------------------------------------------
    */
    function ad_WiteIP($dir){
      $f=fopen($dir.'/a'.$_SERVER['REMOTE_ADDR'], 'w');
      fclose($f);
    }
    /*
    *----------------------------------------------------------
    * Проверка на наличие в поле HTTP_USER_AGENT чего-нибудь из
    * вышенаписанного списка.
    *----------------------------------------------------------
    */
    $ad_IsRobot=false;
    foreach ($ad_Robots_UserAgent as $match){
      if (strstr($_SERVER['HTTP_USER_AGENT'], $match)){
          $ad_IsRobot=true;
          break;
      }
    }
    if( in_array($_SERVER['REMOTE_ADDR'], $ad_good_ip) ) {
        $good_ip = true;
    } else {
        $good_ip = false;
    }
    /*
    *---------------------------------------------------------
    * Поисковые роботы не любят, когда к адресу страницы
    * добавляется переменная сессии. Поэтому, если на сайте
    * используются сессии, то их лучше включать, если агент -
    * не робот.
    * Если сессии не используются, то этот кусок можно убрать.
    *---------------------------------------------------------
    */
    if (!$ad_IsRobot AND !$good_ip){
      session_start();
    }
     
    if (!$ad_IsRobot AND !$good_ip){
      /*** Чтение каталога и удаление старых файлов ***/
      $ad_dir      =opendir($ad_DirName)
          or die('Отсутствует директория для временных файлов');
      $ad_now      =time();
      $ad_forbid  =$ad_now-$ad_delay;
      /* IP-адрес в имени файла, начинающегося на букву a, 
          а время обращения - время изменения файла */
      while (false!==($ad_FName=readdir($ad_dir))){
          if (ereg('^a[1-9]',$ad_FName)
            && (@ filemtime($ad_DirName.'/'.$ad_FName)<$ad_forbid)){
            @ unlink($ad_DirName.'/'.$ad_FName);
          }
      }
      closedir($ad_dir);
      /*** Проверка на существование пометки
          о недавнем обращении с данного ip-адреса ***/
      if (file_exists($ad_DirName.'/a'.$_SERVER['REMOTE_ADDR'])){
          /* Если обращение было недавно, то выводим сообщение об ошибке */
          header('HTTP/1.0 503 Service Unavailable');
          header('Status: 503 Service Unavailable');
          header('Retry-After: '.$ad_delay*3);
    ?>
    <!doctype html public "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <title>Ошибка 503</title>
    <meta http-equiv="Content-Type" content="text/html; charset=Windows-1251" />
    </head>
    <body>
    <h1>Ошибка 503 (Service Unavailable)</h1>
    <p>Сервер не может в данный момент выдать запрашиваемую Вами страницу.
    Попробуйте вызвать эту страницу позже (клавиша F5).</p>
    </body>
    </html>
    <?php
          ad_WiteIP($ad_DirName);  // Перед выходом записываем ip
          exit;
      }else{
          ad_WiteIP($ad_DirName);
      }
    }
    ?>
    Антиддос скрипт от админа xaknet.ru:

    Код:
    <?php
     
    class antiDdos
    {
        // дебаг
        public $debug = false;
        // директория для хранения файлов индефикации запросов
        public $dir = '_bots/';
        // номер icq администратора
        public $icq = '123456';
        // сообщение при выключенном сайте
        public $off_message = 'Временные неполадки, пожалуйста, подождите.';
        // индивидуальный индефикатор
        private $indeficator = null;
        // сообщение при бане, работают шаблоны, можно использовать - {ICQ}, {IP}, {UA}, {DATE}
        public $ban_message = 'Вы были заблокированы antiddos системой.
                              Если это ошибка обратитесь к администратору, icq of admin: {ICQ}
                              <hr>(c)XakNet antiddos module, ваш IP - {IP}(<i>{UA}</i>), date - {DATE}';
        // команда выполнения бана в файрволле
        public $exec_ban = 'iptables -A INPUT -s {IP} -j DROP';
        // тип защиты от ддоса:
        /* Возможные значения $ddos 1-5: 
        | 1. Простая проверка по кукам, по умолчанию(рекомендую)   
        | 2. Двойная проверка через $_GET antiddos и meta refresh   
        | 3. Запрос на авторизацию WWW-Authenticate   
        | 4. полное отключение сайта, боты не блокируются!!!   
        | 5. выключать сайт если нагрузка слишком большая на сервере, боты не блокируются!!!   
        */ 
        var $ddos = 1;
        // часть домена поисковых ботов, см strpos()
        private $searchbots = array('googlebot.com', 'yandex.ru', 'ramtel.ru', 'rambler.ru', 'aport.ru', 'sape.ru', 'msn.com', 'yahoo.net');
        // временная переменные нужные для работы скрипта
        private $attack = false;
        private $is_bot = false;
        private $ddosuser;
        private $ddospass;
        private $load;
        public $maxload = 80;
       
        function __construct($debug)
        {
            @session_start() or die('session_start() filed!');
            $this->indeficator = md5(sha1('botik' . strrev(getenv('HTTP_USER_AGENT'))));
            $this->ban_message = str_replace(array('{ICQ}', '{IP}', '{UA}', '{DATE}'), 
                                            array($this->icq, $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT'], date('d.m.y H:i')),
                                            $this->ban_message
                                            );
            if (eregi(ip2long($_SERVER['REMOTE_ADDR']), file_get_contents($this->dir . 'banned_ips')))
                die($this->ban_message);
            $this->exec_ban = str_replace('{IP}', $_SERVER['REMOTE_ADDR'], $this->exec_ban);
            $this->debug = $debug;
            if(!function_exists('sys_getloadavg'))
            {
                function sys_getloadavg()
                {
                    return array(0,0,0);
                }
            }
            $this->load = sys_getloadavg();
            if(!$this->sbots())
            {
                $this->attack = true;
                $f = fopen($this->dir . ip2long($_SERVER["REMOTE_ADDR"]), "a"); 
                fwrite($f, "query\n"); 
                fclose($f); 
            }
        }
       
        /**
        * Старт работы антиддоса
        **/
        function start()
        {
            if($this->attack == false)
                return;
            switch($this->ddos)
            {
                case 1:
                    $this->addos1();
                    break;
                case 2:
                    $this->addos2();
                    break;
                case 3:
                    $this->ddosuser = substr(ip2long($_SERVER['REMOTE_ADDR']), 0, 4);
                    $this->ddospass = substr(ip2long($_SERVER['REMOTE_ADDR']), 4, strlen(ip2long($_SERVER['REMOTE_ADDR'])));
                    $this->addos3();
                    break;
                case 4:
                    die($this->off_message);
                    break;
                case 5:
                    if ($this->load[0] > $this->maxload) 
                    {
                        header('HTTP/1.1 503 Too busy, try again later'); 
                        die('<center><h1>503 Server too busy.</h1></center><hr><small><i>Server too busy. Please try again later. Apache server on ' . $_SERVER['HTTP_HOST'] . ' at port 80 with <a href="http://forum.xaknet.ru/">ddos protect</a></i></small>'); 
                    } 
                    break;
                default:
                    break;
            }
            if ($_COOKIE['ddos'] == $this->indeficator) 
                @unlink($this->dir . ip2long($_SERVER["REMOTE_ADDR"])); 
        }
       
        /**
        * Функция проверяет не является ли клиент поисковым ботом
        **/
        function sbots()
        {
            $tmp = array();
            foreach($this->searchbots as $bot)
            {
                $tmp[] = strpos(gethostbyaddr($_SERVER['REMOTE_ADDR']), $bot) !== false;
                if($tmp[count($tmp) - 1] == true)
                {
                    $this->is_bot = true;
                    break;
                }
            }
            return $this->is_bot;
        }
       
        /**
        * Функция бана
        **/
        private function ban()
        {
            if (! system($this->exec_ban))
            { 
                $f = fopen($this->dir . 'banned_ips', "a"); 
                fwrite($f, ip2long($_SERVER['REMOTE_ADDR']) . '|'); 
                fclose($f); 
            }
            die($this->ban_message); 
        }
        /**
        * Первый тип защиты
        **/
        function addos1()
        {
            if (empty($_COOKIE['ddos']) or !isset($_COOKIE['ddos'])) 
            { 
                $counter = @file($this->dir . ip2long($_SERVER["REMOTE_ADDR"]));
                setcookie('ddos', $this->indeficator, time() + 3600 * 24 * 7 * 356); // ставим куки на год.
                if (count($counter) > 10) { 
                    if (! $this->debug)
                        $this->ban(); 
                    else 
                        die("Блокированы."); 
                } 
                if (! $_COOKIE['ddos_log'] == '1') 
                { 
                    if (! $_GET['antiddos'] == 1) 
                    { 
                        setcookie('ddos_log', '1', time() + 3600 * 24 * 7 * 356); //чтоб не перекидывало постоянно рефрешем. 
                        if(headers_sent())
                            die('Header already sended, check it, line '.__LINE__);
                        header("Location: ./?antiddos=1"); 
                    } 
                } 
            } elseif ($_COOKIE['ddos'] !== $this->indeficator) 
            { 
                if (! $this->debug) 
                    $this->ban(); 
                else 
                    die("Блокированы."); 
            } 
        }
       
        /**
        * Второй тип защиты
        **/
        function addos2()
        {
            if (empty($_COOKIE['ddos']) or $_COOKIE['ddos'] !== $this->indeficator) 
            {
                if (empty($_GET['antiddos'])) 
                { 
                    if (! $_COOKIE['ddos_log'] == '1') 
                        //проверям есть ли запись в куках что был запрос 
                        die('<meta http-equiv="refresh" content="0;URL=?antiddos=' . $this->indeficator . '" />'); 
                } elseif ($_GET['antiddos'] == $this->indeficator) 
                { 
                    setcookie('ddos', $this->indeficator, time() + 3600 * 24 * 7 * 356); 
                    setcookie('ddos_log', '1', time() + 3600 * 24 * 7 * 356); //типо запрос уже был чтоб не перекидывало постоянно рефрешем. 
                } 
                else 
                { 
                    if (!$this->debug) 
                        $this->ban(); 
                    else 
                    { 
                        echo "May be shall not transform address line?"; 
                        die("Блокированы."); 
                    } 
                } 
            } 
        }
       
        /**
        * Третий тип защиты
        **/
        function addos3()
        {
            if (! isset($_SERVER['PHP_AUTH_USER']) || $_SERVER['PHP_AUTH_USER'] !== $this->ddosuser || $_SERVER['PHP_AUTH_PW'] !== $this->ddospass) 
            { 
                header('WWW-Authenticate: Basic realm="Vvedite parol\':  ' . $this->ddospass . ' | Login: ' . $this->ddosuser . '"'); 
                header('HTTP/1.0 401 Unauthorized'); 
                if (! $this->debug) 
                    $this->ban(); 
                else 
                    die("Блокированы."); 
                die("<h1>401 Unauthorized</h1>"); 
            }
        }
    }
    /*
    // Exmaple
    $ad = new antiDdos(false);
    $ad->dir = 'bots/';
    $ad->ddos = 2;
    $ad->start();
    */
    ?>

    Скрипт Boolean

    Код:
    <?php 
    #(c) Boolean. 
    ##################################################################################### 
    ##################################################################################### 
    ##################################################################################### 
    ##################################################################################### 
     
    $config['time']                = 2; 
    #Время обращения к скрипту, после которого будет(возможно) выдан бан. 
    $config['countaban']            = 5; 
    #количество возможных нарушений времени обращения, такая возможность введена для более детально точного отделения пользователей от атакующих ботов. 
    $config['directory']            = '_temp'; 
    #временна директория, должна существовать, и иметь права на запись. 
    $config['checkmask']            = 'check'; 
    #маска для проверки, не стоит трогать. 
    $config['banmask']              = 'ban'; 
    #маска для бана, не стоит трогать. 
     
    #Комманды после нарушения времени и кол-ва обращений. Используйте константу [IP] - IP Бота. 
    $config['commands'][]          = 'iptables -A ISPMGR -s [IP] -j DROP'; 
    $config['commands'][]          = 'iptables -I INPUT -s [IP] -j DROP'; 
     
    #Доверенные IP. 
    $config['white']['ip']          = @file('whiteips.txt'); 
    #Доверенные ЮзерАгенты. 
    $config['white']['useragent'][] = 'Google bot'; 
    $config['white']['useragent'][] = 'Yasha bot'; 
     
    #Сообщение для пользователя. HTML Работает. 
    $config['message']              = file_get_contents("ddosmessage.html"); 
     
    ##################################################################################### 
    ##################################################################################### 
    ##################################################################################### 
    ##################################################################################### 
     
    $ip                            = $_SERVER['REMOTE_ADDR']; 
    $useragent                      = $_SERVER['HTTP_USER_AGENT']; 
    if ( ! is_dir($config['directory']) ) 
        exit("Temp directory not found."); 
     
    if ( ! is_writable($config['directory']) ) 
        exit("Temp directory is not writable."); 
     
    if ( @in_array($ip,$config['white']['ip']) || @in_array($useragent,$config['white']['useragent']) ) 
        $white = true; 
     
    if ( ! $white ){ 
         
        if ( file_exists( $config['directory'] . "/" . $config['checkmask'] . $ip ) ){         
             
            $time = filemtime($config['directory'] . "/" . $config['checkmask'] . $ip); 
     
            $f=fopen( $config['directory'] . "/" . $config['checkmask'] . $ip , 'w' ); 
            fclose($f); 
                     
            if ($time >= time() - $config['time']){ 
                 
                if (file_exists($config['directory'] . "/" . $config['banmask'] . $ip)){ 
                     
                    $count = file_get_contents($config['directory'] . "/" . $config['banmask'] . $ip); 
                    if ($count >= $config['countaban']){             
                        for($i = 0; $i <= count($config['commands']) - 1; $i++) 
                            @system(str_replace("[IP]",$ip,$config['commands'][$i]));                     
                    }else{ 
                        $time = filemtime($config['directory'] . "/" . $config['banmask'] . $ip); 
                        if ($time >= time() - $config['time']){ 
                            $count++; 
                            $f=fopen( $config['directory'] . "/" . $config['banmask'] . $ip , 'w' ); 
                            fwrite($f,$count); 
                            fclose($f); 
                        }else{ 
                            $f=fopen( $config['directory'] . "/" . $config['banmask'] . $ip , 'w' ); 
                            fwrite($f,"1"); 
                            fclose($f);                         
                        } 
                    }       
                         
                }else{ 
                    $f=fopen( $config['directory'] . "/" . $config['banmask'] . $ip , 'w' ); 
                    fwrite($f,"0");   
                    fclose($f); 
                } 
     
                exit($config['message']); 
            } 
             
        }else{     
            $f=fopen( $config['directory'] . "/" . $config['checkmask'] . $ip , 'w');     
            fclose($f);     
        }   
           
    }   
    ?>
     
    17 авг 2013
    Seruy нравится это.
  2. Подскажите пожалуйста где и какую дерикторию создать для скрипта AntiOverload. Я создал DOCUMENT_ROOT в папке tmp и ничего. Пробовал в корневой папке сайта и в папке Punlick_HTML, и в папке php всё в бестолку - пишет не найдена временная папка
     
    3 авг 2014
  3. Скрипт нужно инклюдить в исполняемый файл, в index.php, например.

    Создаем файл, допустим, antiddos.php, туда копируем любой код из вышеприведенных, затем в файле index.php пишем вверху:
    PHP:
    include("antiddos.php");

    exit; 
    // нужно дать скрипту побанить ботов некоторое время, а потом можно закомментировать exit.

    Список забаненных IP, пожалуйста, оставляйте у нас на форуме. Мы будем делать базы.
     
    Последнее редактирование: 8 авг 2014
    8 авг 2014
  4. У меня вопрос по Антиддос скрипт от админа xaknet.ru

    // директория для хранения файлов индефикации запросов
    public $dir = '_bots/';

    Ето нужно создать папку _bots и положить в корень? И нужен ли слеш / в конце?
    И нужно ли в папке _bots создавать какие то файлы или скрипт сам создаст?
     
    8 фев 2016
  5. Я правильно понял, ети скрипты нужно подключать во всремя атаки а не все время они должны быть на сайте?
    у меня если exit; не закомментирован то сайт не работает! Так и должно быть?
     
    8 фев 2016
  6. Скрипты это бред, настраивайте фаервол.
     
    9 фев 2016

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