Модифицировать index.php - защита от F5

hasvanbinsun

Проверенные
Сообщения
407
Реакции
75
Баллы
5,530
При многократном обращении к главной странице авторизованным пользователем, процессы PHP наглухо забивают CPU.

Необходимо защитить форум от подобных фокусов. Данная тема будет полезна пользователям которые используют слабые VPS или шаред хостинг.

Нашел вот такой материал

Не давно один мой знакомый показал мне один фокус как уложить сайт на лопатки!

или проще говоря как вывести сайт из строя, все оказалось довольно просто все что нужно это перейти на сайт жертвы и зажать на секунд 10 кнопку F5, тем самым происходит обновления страницы чаще чем раз в 1 секунду, из за таких частых обращений и ложится сервер, правда не на долго но все равно не приятно.

Данная информация сразу заставила задуматься и принять экстренные меры :-)

Так был написан простенький, но эффективный скрипт на ограничение запросов к сайту.

Код:
#F5
session_start();
if(isset($_SESSION[session_id()]) AND (time()-$_SESSION[session_id()]) <= 1){
die('<html><head><meta http-equiv="Refresh" content="2" /><title>You have made too many requests per second.</title></head>
<body><h1>You have made too many requests per second.</h1>Please, wait few seconds and refresh this page.</body></html>');
}else{$_SESSION[session_id()] = time();}

или

Код:
header('Content-Type: text/html;charset=UTF-8');
session_start();
$limit = 5;
if(isset($_SESSION[session_id()]) AND (time()-$_SESSION[session_id()]) <= $limit)
  exit('Фууууу.. ддоссер.... кышь!');
else
    $_SESSION[session_id()] = time();

или

Код:
<?php
  session_start(); // Начинаем сессию
  $ts = time(); // Получаем текущее время
  $s_time = (empty($_SESSION["time"]))? 0: $_SESSION["time"]; // Если пользователь обращается к скрипту впервые, то устанавливаем значение 0, иначе берём его из сессии
  $_SESSION["time"] = $ts; // Обновляем значение сессии
  if ($ts - $s_time > 2) { // Если с момента предыдущего обращения прошло больше 2 секунд
    echo "Тут сложный скрипт"; // Выполняем скрипт
  }
  else echo "Хватит постоянно обновлять страницу!"; // Выводим сообщение об ошибке
?>

Внимание, вопрос знатокам и любителям PHP. Как это можно прикрутить к форуму? Возможно установить такую защиту как для авторизованных, так и для обычных пользователей которые бродят по форуму?
 
Последний PHP скрипт работает но он только выводит сообщение: Хватит обновлять страницу)) А другие у меня не работали
 
Тогда предлагаем пути решения проблемы в этой теме.

Есть плагин, DeDos - Anti DOS for spam bots/scrapers/tors
Но по опеределенным причинам он мне не подходит. Какие ещё есть варианты?
 
Для начала ограничение запросов на уровне файрволла или веб-сервера. Любые решения, основанные на редактировании движка (в том числе и плагин выше) будут хуже.
 
Последнее редактирование:
Для начала ограничение запросов на уровне файрволла или веб-сервера.

Не подходит такой вариант. Нужно сделать именно через инклуд PHP или через модификацию Xenforo.

Проблема решена настройкой nginx_limit через куки. Мой конфиг:

В http
limit_req_zone $cookie_xf_session zone=one:10m rate=200r/m;

В локейшн
limit_req zone=one burst=30 nodelay;

Всем спасибо за внимание.
 
Последнее редактирование:
А не лучше поставит ограничения на один адрес запрет одновременно 10 запросов ?
только что вчера сделал на своём сайте.
конечно он не работает на xenforo. но я сделал на уровни бд. кстати машина своя поэтому там могу сделать что хочу :-)
 
А не лучше поставит ограничения на один адрес запрет одновременно 10 запросов ?
только что вчера сделал на своём сайте.
конечно он не работает на xenforo. но я сделал на уровни бд. кстати машина своя поэтому там могу сделать что хочу :-)

В моем случае не проще. И ещё для работы этого способа, лучше подключать limit не на основной локейшн, а на PHP. Что бы не блокировались файлы (картинки) при перезагрузке страницы или слишком частых запросах.
 
А не лучше поставит ограничения на один адрес запрет одновременно 10 запросов ?
только что вчера сделал на своём сайте.
конечно он не работает на xenforo. но я сделал на уровни бд. кстати машина своя поэтому там могу сделать что хочу :-)
почему не работает на xenforo? :-D
Пример конфига:
описываем 2 зоны в http{...} в nginx.conf
Код:
  limit_req_zone  $binary_remote_addr  zone=one:10m   rate=4r/s; #ограничение 4 запроса/сек  для 1 ip
    limit_conn_zone $binary_remote_addr zone=two:10m; #описание зоны на ограничение одновременных соединений с 1ip
    limit_conn two 30; #для зоны two устанавливаем значение в 30 одновременных соединений (будет работать одновременно для всех виртуальных хостов). Значение подобрано по максимальному количеству возможных потоках в современных браузерах
Далее, путём практического тестирования вычисляем значение максимального всплеска запросов в секунду для 1 ip и пишет в server{...}, для location, где указывается php-интерпретатор
Код:
limit_req       zone=one  burst=10; #у меня отрабатывает без ложных сбрасываний при таком значении

Для полной красоты ситуации, если установлено мало виртуальных хостов и не планируется расширение, то для xenforo я бы полностью отказался от apache и работал бы на связке nginx+php-fpm (желательно начиная с версии 5.6, т.к. в него включён по дефолту php-акселератор opcache)+memcached+percona (форк mysql, не вдаваясь в подробности, даже с дефолт настройками прирост скорости очевиден). А если ещё и с настройками поэксперементируешь всего этого, то поймёшь, какой быстрый может быть xenforo :D
 
Практичней задавать разные зоны и на локешенах разделить логон/авторизацию/восстановление пароля/поиск/еще_что-то своими зонами, скажем на уровне 1-2 r/s.
И не забывать что помимо браузеров есть поисковые боты, которые не всегда ведут себя по crawl-delay. Можно переназначать ошибку (limit_req_status) и заворачивать ее в свой локейшн (лучше @) со своим логом - парсить дешевле.
Это если в двух словах.

limit_req zone=one burst=10;
Возможно красивее будет
Код:
limit_req zone=one burst=10 nodelay;
 
Современный облачный хостинг провайдер | Aéza
Назад
Сверху Снизу