Вы не можете просто предотвратить DoS-атаки, связав регулирование до одного IP-адреса или имени пользователя. Черт, с помощью этого метода вы даже не можете предотвратить попытки быстрого входа в систему.
Почему? Потому что атака может охватывать несколько IP-адресов и учетных записей пользователей, чтобы обойти ваши попытки регулирования.
Я видел в другом месте сообщения о том, что в идеале вы должны отслеживать все неудачные попытки входа на сайт и связывать их с меткой времени, например:
CREATE TABLE failed_logins (
id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(16) NOT NULL,
ip_address INT(11) UNSIGNED NOT NULL,
attempted DATETIME NOT NULL,
INDEX `attempted_idx` (`attempted`)
) engine=InnoDB charset=UTF8;
Небольшое примечание по полю ip_address: вы можете хранить данные и извлекать данные, соответственно, с помощью INET_ATON () и INET_NTOA (), которые по сути эквивалентны преобразованию IP-адреса в беззнаковое целое число и обратно.
# example of insertion
INSERT INTO failed_logins SET username = 'example', ip_address = INET_ATON('192.168.0.1'), attempted = CURRENT_TIMESTAMP;
# example of selection
SELECT id, username, INET_NTOA(ip_address) AS ip_address, attempted;
Определите определенные пороги задержки на основе общего количества неудачных попыток входа в систему за заданный промежуток времени (15 минут в этом примере). Вы должны основывать это на статистических данных, взятых из вашей failed_logins
таблицы, поскольку они будут меняться со временем в зависимости от количества пользователей и того, сколько из них могут вспомнить (и ввести) свой пароль.
> 10 failed attempts = 1 second
> 20 failed attempts = 2 seconds
> 30 failed attempts = reCaptcha
Выполняйте запросы к таблице при каждой неудачной попытке входа в систему, чтобы найти количество неудачных попыток входа в систему за заданный период времени, скажем, за 15 минут:
SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute);
Если количество попыток за указанный период времени превышает ваш лимит, либо принудительно дросселируйте, либо заставьте всех пользователей использовать капчу (то есть reCaptcha) до тех пор, пока количество неудачных попыток за данный период времени не станет меньше порогового значения.
// array of throttling
$throttle = array(10 => 1, 20 => 2, 30 => 'recaptcha');
// retrieve the latest failed login attempts
$sql = 'SELECT MAX(attempted) AS attempted FROM failed_logins';
$result = mysql_query($sql);
if (mysql_affected_rows($result) > 0) {
$row = mysql_fetch_assoc($result);
$latest_attempt = (int) date('U', strtotime($row['attempted']));
// get the number of failed attempts
$sql = 'SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute)';
$result = mysql_query($sql);
if (mysql_affected_rows($result) > 0) {
// get the returned row
$row = mysql_fetch_assoc($result);
$failed_attempts = (int) $row['failed'];
// assume the number of failed attempts was stored in $failed_attempts
krsort($throttle);
foreach ($throttle as $attempts => $delay) {
if ($failed_attempts > $attempts) {
// we need to throttle based on delay
if (is_numeric($delay)) {
$remaining_delay = time() - $latest_attempt - $delay;
// output remaining delay
echo 'You must wait ' . $remaining_delay . ' seconds before your next login attempt';
} else {
// code to display recaptcha on login form goes here
}
break;
}
}
}
}
Использование reCaptcha на определенном пороге гарантирует, что атака с нескольких направлений будет остановлена, и обычные пользователи сайта не будут испытывать значительную задержку при законных неудачных попытках входа в систему.
person
Corey Ballou
schedule
19.01.2010
418 I'm a teapot
вместо 404 здесь. en.wikipedia.org/wiki/Http_status_codes; o) - person deceze♦   schedule 19.01.2010