Ограничение использования ресурсов для IP на общем хосте

Недавно у меня был один IP-вызов одной и той же страницы 15 000 раз подряд, который израсходовал много ресурсов сервера (что привело к получению предупреждения от службы Host). Я нахожусь на общем хосте, поэтому не могу загрузить новые модули и, следовательно, не имею реальных возможностей действительно ограничить пропускную способность IP.

Итак, я пытаюсь выяснить, как я могу использовать наименьшее количество ресурсов для определения нарушающего IP-адреса и перенаправления его на страницу 403 Forbidden. Я уже проверяю обычные хаки и использую Project HoneyPot, но делать это для каждого из 15 000 обращений к страницам неэффективно (и, как этот, он не охватывает их всех).

В настоящее время я регистрирую доступ к каждой странице в таблицу MySQL под названием visitors, Я могу представить несколько способов сделать это:

Вариант 1: использование MySql:
1) Запрос visitors таблица количества обращений с IP за последние 10 секунд.
2) Если число больше определенного (15?), Отметьте последнюю запись в visitors как заблокировано для этого IP.
3) С каждым последующим запросом страницы, запрос на visitors Таблица покажет IP как заблокированный, и я могу затем перенаправить на страницу 403 Forbidden.

Вариант 2. Изменение файла включения на лету, который содержит IP-адреса из черного списка:
1) Include файл, который возвращает массив IP-адресов из черного списка
2) Если текущего IP нет в списке, запросите visitors Таблица, как в варианте 1, чтобы увидеть, больше ли количество обращений с IP за последние 10 секунд, чем определенное число.
3) Если IP нарушает, измените include файл, чтобы включить этот IP-адрес, как показано ниже.

По сути, мой вопрос: который использует больше ресурсов (х 15 000): запрос к базе данных или код ниже, который использует include прочитать файл и затем array_search (), ИЛИ есть ли лучший способ сделать это?

<?php

$ip = $_SERVER['REMOTE_ADDR'];
$filename='__blacklist.php';

if (file_exists($filename)){
// get array of excluded ip addresses
$array = (include $filename);
// if current address is in list, send to 403 forbidden page
var_dump($array);

if (is_array($array) && array_search($ip, $array) !== false){
blockAccess("Stop Bugging Me!");
}
} else {
echo "$filename does not exist";
}

// evaluate some condition which if true will cause IP to be added to blacklist - this will be a query to a MySql table determining number of hits to the site over a period of time like the last 10 seconds.
if (TRUE){
blockip($ip);
}

// debug - let's see what is blocked
// $array = (include $filename);
// var_dump($array);

// add the ip to the blacklist
function blockip($ip){
$filename='__blacklist.php';
if (! file_exists($filename)){
// create the include file
$handle = fopen($filename, "w+");
// write beginning of file - 111.111.111.111 is a placeholder so all new ips can be added
fwrite($handle, '<?php return array("111.111.111.111"');
} else {
// let's block the current IP
$handle = fopen($filename, 'r+');
// Don't use filesize() on files that may be accessed and updated by parallel processes or threads
// (as the filesize() return value is maintained in a cache).
// use fseek & ftell instead
fseek($handle, 0 ,SEEK_END);
$filesize = ftell($handle);

if ($filesize > 20){
// remove ); from end of file so new ip can be added
ftruncate($handle, $filesize-2);

// go to end of file
fseek($handle, 0 ,SEEK_END);

} else {
// invalid file size - truncate file
$handle = fopen($filename, "w+");
// write beginning of file with a placeholder so a new ip can be added
fwrite($handle, '<?php return array("111.111.111.111"');
}
}

//add new ip and closing of array
fwrite($handle, "," . PHP_EOL . '"' . $ip . '");');fclose($handle);
}function blockAccess($message) {
header("HTTP/1.1 403 Forbidden");
echo "<!DOCTYPE html>\n<html>\n<head>\n<meta charset='UTF-8' />\n<title>403 Forbidden</title>\n</head>\n<body>\n" .
"<h1>Forbidden</h1><p>You don't have access to this page.</p>" .
"\n</body>\n</html>";
die();
}

?>

0

Решение

Здесь есть много моментов, на которые следует обратить внимание.

Это в основном сводится к серверу, на котором он размещен. Общий хостинг не известен хорошим IO, и вам придется это проверить. Это также зависит от того, сколько IP-адресов вы будете в черном списке.

В идеале вы не хотите, чтобы злоумышленники обращались к PHP, когда вы определили, что они вредоносные. Единственный реальный способ сделать это в совместно используемой среде на Apache — заблокировать их от htaccess. Не рекомендуется, но есть возможность изменить htaccess из PHP.

Order Deny,Allow
Deny from xxx.xxx.xxx.xxx

Когда я читаю ваш вопрос, меня беспокоит то, что вы, похоже, не понимаете проблему. Если вы получаете 15 000 обращений за промежуток времени в секундах, у вас не должно быть 15 000 подключений к базе данных, и все эти запросы не должны обрабатывать PHP. Вам нужно кэшировать эти запросы. Если это происходит, ваша система в корне ошибочна. Для одного пользователя в домашнем интернете физически не должно быть возможности резко увеличить использование ресурсов.

В вашей ситуации я предлагаю приобрести VPS или что-то еще, что позволит вам использовать обратный прокси-сервер и использовать гораздо больше кэширования / внесения в черный список / мониторинга ресурсов.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]