Защита от DDoS атак на PHP

Предлагаемый метод предназначен для защиты от атаки с нескольких десятков или сотен компьютеров частыми запросами на ваш сайт. Принцип действия защиты от DDoS-атаки – блокировать IP-адреса, частота обращений с которых заведомо больше, чем обычно нужно для работы с вашим сайтом. Предполагается, что на сервере установлен и работает файервол iptables. Защита встраивается в php-код страниц сайта и использует таблицу MySQL для хранения временных данных.

Итак, создаём таблицу access_log. Нам нужно только два поля, для хранения IP-адреса и времени доступа:

CREATE TABLE `access_log` (
    `ip` varchar(15) NOT NULL default '',
    `enter_time` int(11) NOT NULL default '0'
) ENGINE=HEAP;

Теперь пишем функцию для определения слишком активных IP-адресов:

function check_ddos(){
    $rec_limit = 4; // Величина выборки
    $time_limit = 1; // Минимальный допустимый промежуток времени между первой и последней записью в выборке
    $ip = $_SERVER['REMOTE_ADDR'];
    // Соединение с БД:
    if (!$db_connection = mysql_pconnect('localhost', 'root', '')){
        die();
    }else{
        if(!mysql_select_db('ddos_test', $db_connection)){
            die();
        }
    }
    mysql_query('DELETE FROM access_log WHERE enter_time < '.(time() - ($time_limit * 2)), $db_connection);
    mysql_query('INSERT INTO access_log (ip, enter_time) VALUES ("'.$ip.'", '.time().')', $db_connection);
    if ($result = mysql_query('SELECT enter_time FROM access_log WHERE ip="'.$ip.'" ORDER BY enter_time DESC LIMIT '.$rec_limit)){
        while($row = mysql_fetch_row($result)){
            $result_array[] = $row;
        }
    }
    $rec_count = count($result_array);
    if ($rec_count == $rec_limit){
        $first_time = $result_array[$rec_count - 1][0];
        $last_time = $result_array[0][0];
        if (($last_time - $first_time) < $time_limit){
            iptables_ban_ip($ip);
            exit();
        }
    }
}

Для этого примера я создал БД с именем ddos_test. Если вы уже используете MySQL на своём сайте – можете использовать существующее соединение.

Всё, что делает эта функция – при каждом обращении к защищаемой странице сайта пишет в таблицу время обращения и IP-адрес клиента. При этом каждый раз делается выборка из  $rec_limit последних обращений с данного IP, и если время между первым и последним обращениями в этой выборке меньше значения переменной $time_limit (в секундах) – вызывается функция iptables_ban_ip, и данный IP блокируется файерволом. В данном примере, если с одного IP будет более, чем 4 обращения в секунду – IP блокируется. Cама таблица временных данных постоянно очищается от лишних данных и содержит только последние обращения.

Функция для записи особо назойливых IP-адресов в блэк-лист файервола:

function iptables_ban_ip($ip){
    $command = 'sudo iptables -A INPUT -s '.$ip.' -j DROP';
    system($command);
}

Теперь остаётся вставить вызов защиты по возможности в начало нужных файлов, например, в index.php:

check_ddos();

Всё.

P.S. На всякий случай, если кто-то из посетителей вашего сайта страдает от тремола пальцев – вот команда для вызволения его IP из блэк-листа:

iptables -D INPUT -s здесь_IP_адрес -j DROP

Ну и просто пройтись по описанию команд iptables тоже будет не зря.

P.P.S. От серьёзной DDoS атаки эта защита, надо полагать, не будет эффективна, но от упражнений начинающих хакеров помогает «на ура».

 

Powered by vk-site.com