Способ работы большинства веб-серверов (например, Apache) - поддерживать набор рабочих потоков. Когда выполняется скрипт PHP, один поток запускает скрипт PHP.
Когда ваш сценарий выполняет sleep(100)
, выполнение сценария занимает 100 секунд. Это означает, что ваш рабочий поток связан на 100 секунд.
Проблема в том, что у вас очень ограниченное число рабочих потоков - скажем, у вас есть 10 потоков и 10 человек, которые входят в систему - теперь ваш веб-сервер не может обслуживать дальнейшие ответы.
Лучший способ ограничить скорость входа в систему (или другие действия) - это использовать какой-нибудь быстрый способ хранения в памяти ( memcached идеально подходит для этого), но для этого требуется запустить отдельный процесс и довольно сложно (вы можете сделать это, если вы запускаете что-то вроде Facebook ..).
Проще, у вас может быть таблица базы данных, в которой хранятся user_id
или ip_address
, first_failed
и failure_counter
.
Каждый раз, когда вы получаете неудачный вход в систему, вы (в псевдокоде) должны делать:
if (first_failed in last hour) and (failure_counter > threshold):
return error_403("Too many authentication failures, please wait")
elseif first_failed in last hour:
increment failure_counter
else:
reset first_failed to current time
increment failure_counter
Возможно, не самый эффективный, и есть лучшие способы, но он должен довольно хорошо прекратить грубую атаку. Использование memcached в основном то же самое, но база данных заменяется memcached (что быстрее)