avatar_Everybody

Простая защита от DoS-атак с помощью MySQL

Автор Everybody, 2008 Дек. 13, 02:18

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Ключевые слова [SEO] phpmysqlзащита от dos-атак

Everybody

Организовать простую защиту от DoS-атак для сайтов, использующих PHP + MySQL, можно следующим образом. В MySQL создается таблица (будем называть ее ip_check) с полями lasttime, count, ip (все поля — типа INTEGER, причем ip — первичный ключ).

Сразу после подключения к базе данных выполняется проверка, есть ли для данного IP-адреса запись в таблице. Если записи нет, она создается, при этом в count пишется 1, в lasttime — текущее время. Если запись уже есть, то проверяется, когда она была сделана (поле lasttime), и если прошло менее определенного количества секунд, то поле count увеличивается на 1, в противном случае приравнивается единице, и производится обновление записи в таблице (записывается новый count и lasttime). Далее происходит проверка величины count, и если она превысила некоторое пороговое значение, выдается статус 500 (или 403 или 503), сообщение об ошибке, и выполнение скрипта завершается.

Таким образом, для выполнения проверки требуется всего одной таблица с предельно простой структурой и 2 запроса SQL. Также можно добавить еще одно поле status, в которое ставить 1, если IP-адрес забанен навсегда по каким-то причинам, и совместить проверку на DoS-атаки с проверкой на забаненные IP-адреса без добавления дополнительных запросов. При необходимости можно еще одним запросом добавить учет суммарной нагрузки за все время или нагрузки по подсетям.

Кроме того, перед завершением скрипта можно добавить проверку, сколько времени заняло его выполнение, и если оно превышает какую-то пороговую величину (например, 10 секунд), начислять этому IP-адресу "штрафные очки" (т.е. дополнительно увеличивать поле count).

В виде кода это можно представить следующим образом:
// $link -- соединение с БД, $ip_text -- IP-адрес
define('ALERT_TIME',300);
define('ALERT_COUNT',150); 

function check_dos($ip_text, $link)  {
$ip=ip2long($ip_text);
$res=mysql_query($link,'SELECT lasttime, count, status FROM ip_check WHERE ip="'.$ip.'"');
if (mysql_num_rows($res)==0) { // нет такого IP
$count=1;
mysql_query($link,'INSERT INTO ip_check (lasttime,count,ip,status) VALUES ('.time().',1,"'.$ip.'",0)');
}
else {
$data=mysql_fetch_row($res);
$status=$data[2];
if ($status!=2 && ($data
  • <time()-ALERT_TIME || $data[1]<ALERT_COUNT)))  $count=1;
elseif ($status!=2) { $count=$data[1]+1; if ($count>=ALERT_COUNT) $status=1; }
 if ($status!=2) {
  mysql_query($link,'UPDATE ip_check SET count='.$count,', status='.$status.', lasttime='.time().' WHERE ip="'.$ip.'"';
 }
 if ($status) {
  header($_SERVER['HTTP_PROTOCOL'].' 503 Temporary Unavailable');
  trigger_error('Превышено число допустимых запросов!',E_USER_ERROR);
 }
}

Кроме того, периодически следует очищать базу от старых записей (например, по cron). Кроме того, если ожидается большая интенсивность атак, возможно, имеет смысл заменить UPDATE-запрос на последовательность DELETE/INSERT, но в этом случае необходимо будет регулярно проводить оптимизацию таблицы.


CnaM

Всё это ерунда если ктот и захочет комуто навредить то я думаю от масового ботнета ничего не спасёт ...

Everybody

Не спасет от ддоса такого точно ничего, кроме роутера (не самого дешевого)
Этот метод был найден в сети еще давно и если разобратся то он повесить может не только выполнением php скрипта так и еще с офигенскими запросами к дб...
Спасет от простого флудера и не более.

Похожие темы (5)