Antiddos 1.0: PHP-скрипт для защиты от Ддос атак. При интеграции с Cloudflare производительность скрипта вырастает многократно.
Старая версия скрипта, с возможностью интеграции с iptables, здесь: https://ddosforum.com/threads/602/
Новая версия пока тестируется, возможны ошибки!
Скрипт считает количество заходов в минуту для каждого пользователя (по IP или по IP+браузер). При превышении установленного лимита пользователю сначала показывается предупреждение, чтобы он больше не обновлял страницу, затем, если предупреждение игнорируется, пользователь банится. При связке с Cloudflare (для этого нужно ввести данные доступа к API Cloudflare в файле настроек), IP пользователя также добавляется в файрвол Cloudflare (Security->WAF->Tools), что снимает нагрузку с сервера. В дальнейшем пользователь может быть разбанен вручную из админки или автоматически по Cron (если срок блокировки истечет).
Алгоритм работы скрипта
Скрипт имеет гибкие настройки, что позволяет адаптировать его под разные типы атак. Например, по умолчанию скрипт считает число заходов для каждой отдельной страницы сайта, а не на весь сайт целиком. То есть пользователь банится, только если будет несколько раз подряд обновлять одну и ту же страницу (что ненормально для человека). Но ддосер может добавить к атакуемой странице случайный GET-параметр, обойдя тем самым стандартные настройки скрипта. Тогда можно изменить настройки так, чтобы счетчик работал только на страницы без GET-параметров.
На случай "умных ДДос атак" предусмотрен также режим Под Атакой. Тогда скрипт считает все посещения сайта за минуту со всех IP (своего рода контроль трафика). Если число посещений превышает установленный в настройках лимит, то всем пользователям сайта показывается предупреждение с просьбой не обновлять страницу (зайти попозже). Проигнорировавшие данное предупреждение попадут в бан.
Алгоритм работы режима "Под атакой"
Производительность скрипта
Скрипт не создает существенной нагрузки на сервер. Операции которые он совершает: проверка существование файла в папке белого списка (file_exists), проверка на бота (по user agent) , чтение и запись файла счетчика, где содержится только число заходов за минуту. Если включен режим Под Атакой, то дополнительно скрипт читает и записывает файл счетчика всех заходов на сайт.
Потребление ресурсов у меня на виртуальном сервере.
При выключенном режиме "Под Атакой":
Израсходованная память: 53.85 kb (0,054 mb)
Израсходованное время: 0.0013718605041504 сек.
При включенном режиме "Под Атакой":
Израсходованная память: 54.38 kb (0,054 mb)
Израсходованное время: 0.0019669532775879 сек.
Для сравнения: главная страница этого форума загружается за 0.237 сек. и потребляет 15 мб памяти. То есть повышение нагрузки на форум при использовании скрипта составляет примерно 1/200 от обычной нагрузки, что не существенно и дает возможность использовать скрипт постоянно.
Настройки находятся в файле config.php.
Настройка времени бана.
Это время в секундах для блокировки по IP. По умолчанию установлена неделя, но вы можете указать значение побольше.
Настройки лимитов.
Таймер режима "Под Атакой".
Настройка рефереров.
Рефереры это сайты, с которых перешли на ваш сайт. Изучите логи, если в вашем случае боты шлют пустые рефереры, то можете указать здесь хотя бы домен вашего сайта, чтобы счетчик не включался при перемещении пользователя по внутренним страницам сайта.
Например, вот так:
Настройки для выявления поисковых ботов.
Список фейковых ботов есть в админке: Список забаненных IP -> Фейковые поисковые боты
Информация о хосте есть в логах. Если хост правильный, относится к поисковой системе, напишите пожалуйста в теме, чтобы я дополнил конфиг.
Настройки крон (задания по расписанию):
Нужно добавит задания в cron.
Для очистки счетчика (раз в 10 минут):
Для разбанивания IP, срок блокировки которых истек (раз в час):
Альтернативный вариант для "продвинутых пользователей":
Процедуры отчистки счетчика и разбана пользователей можно проделать и вручную из админки в разделе меню Cron. Но если скрипт используется постоянно, то правило крон хотя бы для счетчика надо добавить, потому что в папке count создается много файлов в процессе работе скрипта и при попытке их удалить спустя длительное время сервер может зависнуть.
Настройки Cloudflare:
Получить ключ доступа можно в разделе My Profile->API Tokens:
При попытке получить API ключ может зависнуть капча. Попробуйте тогда зайти с другого IP. Возможно это как то связано с блокировками Роскомнадзора, потому что у меня с российского IP капча зависает, а с VPN все нормально.
Чтобы получить ID домена, зайдите в панель управление сайтом и в разделе Overview он справа в нижнем углу.
Должно получиться примерно следующее.
Чтобы определить список стран целевой аудитории, посмотрите географию посещений в панели управления вашего счетчика. Посмотреть буквенные обозначения стран для Cloudflare можно здесь.
По умолчанию указан список стран с большим процентом русскоговорящего населения. Но лучше составить свой список по географии вашего ресурса. Если ваш сайт блокируется Роскомнадзором, то может быть высокая доля пользователей, использующих VPN, как правило это США и страны Европы. Значение "1" включает исключение, значение "0" отключает исключение.
Если же вы не хотите блокировать страны нецелевого трафика, просто удалите все значения из настройки, вот так:
Но отключать блокировку по странам не рекомендуется, во-первых, потому что включенная опция поможет быстро отсечь до 90% ботов, а во-вторых, даже если пользователь зайдет из страны нецелевого трафика, он все равно сможет попасть на сайт после ввода капчи (по умолчанию, для блокировки по стране установлен метод managed_challenge).
Настройка block_method устанавливает метод блокировки по IP, по стране и по диапазону. Блокировка по диапазону IP срабатывает в случае, если не определяется страна.
Возможные методы блокировки: challenge (каптча), block (запрет доступа), js_challenge (ява скриптовая проверка, без ввода каптчи), managed_challenge (каптча только для "подозрительных" IP).
Как вариант, для стран и диапазонов IP можно сделать более мягкую блокировку, вот так:
В исполняемом файле (как-правило index.php) нужно добавить файл include.php.
Например, так (сверху, после <?php).
Скрипт можно подключить сразу на все сайты хостинга. В таком случае нужно будет прописать абсолютный путь к папке скрипта.
Вы также можете сделать исключение для кэшируемых на стороне Cloudflare файлов: изображений, скриптов и стилей.
Либо, если атакуют только главную страницу сайта, можно подключать его только на главной.
Скрипт уязвим к досс атаке HEAD запросами, инструкция как их отсечь на сервере или в Cloudflare здесь: https://ddosforum.com/threads/1040/
Если у вас слабый виртуальный сервер, возможно будет падать база. Тогда нужно сделать bash скрипт, который будет запускать базу с заданной периодичностью, например, раз в 15 минут.
Команда start не будет срабатывать при включенной базе. Антиддос скрипту база не нужна и он будет продолжать банить ботов. Соответственно, когда база снова запустится, нагрузка уже должна снизиться.
Панель администрирования доработана с предыдущей версии.
Появилась возможность удалять забаненные IP из админки, теперь есть фильтр по логам, лог ошибок и т.д.
Визуально:
Если возникли вопросы или обнаружились какие-то ошибки, пишите в теме.
Старая версия скрипта, с возможностью интеграции с iptables, здесь: https://ddosforum.com/threads/602/
Новая версия пока тестируется, возможны ошибки!
Скрипт считает количество заходов в минуту для каждого пользователя (по IP или по IP+браузер). При превышении установленного лимита пользователю сначала показывается предупреждение, чтобы он больше не обновлял страницу, затем, если предупреждение игнорируется, пользователь банится. При связке с Cloudflare (для этого нужно ввести данные доступа к API Cloudflare в файле настроек), IP пользователя также добавляется в файрвол Cloudflare (Security->WAF->Tools), что снимает нагрузку с сервера. В дальнейшем пользователь может быть разбанен вручную из админки или автоматически по Cron (если срок блокировки истечет).
Алгоритм работы скрипта
- Проверка на поискового бота. Настоящие поисковые боты добавляются в белый список, а фейковые банятся (подлинность бота определяется по хосту).
- Проверка пользователя на превышение лимита обращений (за минуту) к текущей странице сайта. В случае превышения лимита пользователь добавляется в бан лист. Также показывается сообщение с email администратора для связи, на случай ошибочной блокировки.
update 11.12.2022
Добавлен лимит для предупреждения пользователя, чтобы он не обновлял страницу в течении минуты. И только если пользователь игнорирует данное предупреждение, то попадает в бан.
- Если забаненный пользователь снова посетит сайт, то в файрвол Cloudflare добавляется правило блокировки по IP, а также по стране, если в настройках установлен список стран целевой аудитории и страна пользователя не из этого списка. По умолчанию, в качестве метода блокировки устанавливается капча (managed_challenge). Если в качестве метода блокировки установлен запрет доступа (block), то дальнейших шагов не происходит.
- Если пользователь проходит капчу Cloudflare, то разбанивается на сайте. А точнее, IP пользователя из бан листа переносится в список IP прошедших капчу.
- Если пользователь повторно превышает лимит (после разбана), то меняется правило блокировки в Cloudflare с капчи на запрет доступа. После чего IP пользователя может быть разбанен либо вручную администратором, либо автоматически, после истечения срока блокировки, который задается в настройках.
Скрипт имеет гибкие настройки, что позволяет адаптировать его под разные типы атак. Например, по умолчанию скрипт считает число заходов для каждой отдельной страницы сайта, а не на весь сайт целиком. То есть пользователь банится, только если будет несколько раз подряд обновлять одну и ту же страницу (что ненормально для человека). Но ддосер может добавить к атакуемой странице случайный GET-параметр, обойдя тем самым стандартные настройки скрипта. Тогда можно изменить настройки так, чтобы счетчик работал только на страницы без GET-параметров.
На случай "умных ДДос атак" предусмотрен также режим Под Атакой. Тогда скрипт считает все посещения сайта за минуту со всех IP (своего рода контроль трафика). Если число посещений превышает установленный в настройках лимит, то всем пользователям сайта показывается предупреждение с просьбой не обновлять страницу (зайти попозже). Проигнорировавшие данное предупреждение попадут в бан.
Алгоритм работы режима "Под атакой"
- В случае превышения лимита общего числа обращений к сайту (за минуту) показывается заглушка "сайт под ддос атакой, зайдите попозже".
- Пользователи, проигнорировавшие предупреждение, попадают в бан (дальше шаг 3 алгоритма работы Antiddos скрипта см. выше).
- Как только общее число обращений к сайту станет ниже установленного лимита, работа сайта автоматически восстанавливается.
update 11.12.2022
Теперь можно в настройках устанавливать продолжительность включения режима "Под атакой" (раньше включался на минуту). Если средняя посещаемость в минуту за установленный временной период (по умолчанию 5 минут) будет меньше лимита посещений, то работа сайта автоматически восстанавливается.
Производительность скрипта
Скрипт не создает существенной нагрузки на сервер. Операции которые он совершает: проверка существование файла в папке белого списка (file_exists), проверка на бота (по user agent) , чтение и запись файла счетчика, где содержится только число заходов за минуту. Если включен режим Под Атакой, то дополнительно скрипт читает и записывает файл счетчика всех заходов на сайт.
Потребление ресурсов у меня на виртуальном сервере.
При выключенном режиме "Под Атакой":
Израсходованная память: 53.85 kb (0,054 mb)
Израсходованное время: 0.0013718605041504 сек.
При включенном режиме "Под Атакой":
Израсходованная память: 54.38 kb (0,054 mb)
Израсходованное время: 0.0019669532775879 сек.
Для сравнения: главная страница этого форума загружается за 0.237 сек. и потребляет 15 мб памяти. То есть повышение нагрузки на форум при использовании скрипта составляет примерно 1/200 от обычной нагрузки, что не существенно и дает возможность использовать скрипт постоянно.
Настройка скрипта
Настройки находятся в файле config.php.
Настройка времени бана.
$config['bantime']=604800;
Это время в секундах для блокировки по IP. По умолчанию установлена неделя, но вы можете указать значение побольше.
Настройки лимитов.
Код:
$config['limit']=8; // Если пользователь в течении минуты заходит на страницу чаще, чем указанное число, то заносится в банлист по IP
$config['limit_warning']=6; // Если пользователь в течении минуты заходит на страницу чаще, чем указанное число, то для этого пользователя показывается предупреждение не обновлять страницу в течении минуты
$config['limit_attack_mode']=53; // Если общее количество посещений сайта за минуту превышает указанное число, то включается режим Под Атакой и все посетители сайта видят предупреждение не обновлять страницу
$config['limit_attack_mode_ban']=2; // Если в режиме Под Атакой пользователь в течении минуты заходит на страницу чаще, чем указанное число раз, то есть игнорирует предупреждение, то заносится в банлист по IP
Код:
$config['attack_mode_timer']=300;
Настройка рефереров.
$config['referer']=[];
Рефереры это сайты, с которых перешли на ваш сайт. Изучите логи, если в вашем случае боты шлют пустые рефереры, то можете указать здесь хотя бы домен вашего сайта, чтобы счетчик не включался при перемещении пользователя по внутренним страницам сайта.
Например, вот так:
$config['referer']=['mydomain.com', 'forum.mydomain.com'];
Настройки для выявления поисковых ботов.
Код:
$config['search_bots']=['Googlebot'=>'Google', 'yandex.com/bots'=>'Yandex', 'mail.ru'=>'mail.ru']; // Список поисковых ботов в виде ассоциативного массива, где ключ это искомая строка в User Agent для определения принадлежности бота к поисковой системе
$config['search_hosts']=['Google'=>['.googlebot.com', '.google.com'], 'Yandex'=>['.yandex.com', '.yandex.ru', '.yandex.net'], 'mail.ru'=>['.mail.ru'], 'msn.com'=>['.msn.com'], 'bing.com'=>['.msn.com'] ]; // Хосты поисковиков для проверки подлинности ботов
Информация о хосте есть в логах. Если хост правильный, относится к поисковой системе, напишите пожалуйста в теме, чтобы я дополнил конфиг.
Настройки крон (задания по расписанию):
Код:
$config['cron']=
[
'banlist'=>3600, // переодичность в секундах для удаления IP из банлиста время бана которых истекло)
'counter'=>600
];
Для очистки счетчика (раз в 10 минут):
/usr/bin/wget --user-agent="antiddos" "http://[домен]/[папка скрипта]/cron/run.php?action=clearcount"
Для разбанивания IP, срок блокировки которых истек (раз в час):
/usr/bin/wget --user-agent="antiddos" "http://[домен]/[папка скрипта]/cron/run.php?action=clearban"
Альтернативный вариант для "продвинутых пользователей":
/usr/bin/php /[путь на сервере к папке скрипта]/cron/run.php clearcount
/usr/bin/php /[путь на сервере к папке скрипта]/cron/run.php clearban
Процедуры отчистки счетчика и разбана пользователей можно проделать и вручную из админки в разделе меню Cron. Но если скрипт используется постоянно, то правило крон хотя бы для счетчика надо добавить, потому что в папке count создается много файлов в процессе работе скрипта и при попытке их удалить спустя длительное время сервер может зависнуть.
Настройки Cloudflare:
Код:
$config['CF']=
[
'email'=>'', // email вашего аккаунта в Cloudflare
'key'=>'', // ключ доступа (Global API Key), узнать можно на странице dash.cloudflare.com/profile
'zone'=>'', // ID домена в Cloudflare, есть во вкладке Overview
'countries'=>['RU'=>1, 'UA'=>1, 'BY'=>1, 'KZ'=>1, 'LV'=>1, 'FI'=>1, 'GE'=>1, 'IL'=>1, 'KG'=>1, 'PL'=>1, 'TJ'=>1, 'UZ'=>1], // страны целевого трафика
'target'=>['ip'=>'ip', 'ip6'=>'ip', 'ip_range'=>'ip_range', 'country'=>'country'],
// Заметки для правил Cloudflare
'notes'=>[
'ip'=>'antiddos, %country%, %time%, %url%',
'ip_range'=>'antiddos, %country%, %time%',
'country'=>'antiddos, country, %ip%, %time%',
'default'=>'antiddos, %time%'
],
'block_method'=>['country'=>'managed_challenge', 'ip_range'=>'managed_challenge', 'ip'=>'managed_challenge'] // методы блокировки для стран нецелевого трафика, диапазона IP и IP
];
При попытке получить API ключ может зависнуть капча. Попробуйте тогда зайти с другого IP. Возможно это как то связано с блокировками Роскомнадзора, потому что у меня с российского IP капча зависает, а с VPN все нормально.
Чтобы получить ID домена, зайдите в панель управление сайтом и в разделе Overview он справа в нижнем углу.
Должно получиться примерно следующее.
Код:
'email'=>'[email protected]',
'key'=>'d81d9c041p3R6i2M4R72c1d229c1f3d37e1c137',
'zone'=>'a88d9c041p3R6i2M4R72c1d239c1f3d37e1c138',
По умолчанию указан список стран с большим процентом русскоговорящего населения. Но лучше составить свой список по географии вашего ресурса. Если ваш сайт блокируется Роскомнадзором, то может быть высокая доля пользователей, использующих VPN, как правило это США и страны Европы. Значение "1" включает исключение, значение "0" отключает исключение.
Если же вы не хотите блокировать страны нецелевого трафика, просто удалите все значения из настройки, вот так:
'countries'=>[],
Но отключать блокировку по странам не рекомендуется, во-первых, потому что включенная опция поможет быстро отсечь до 90% ботов, а во-вторых, даже если пользователь зайдет из страны нецелевого трафика, он все равно сможет попасть на сайт после ввода капчи (по умолчанию, для блокировки по стране установлен метод managed_challenge).
Настройка block_method устанавливает метод блокировки по IP, по стране и по диапазону. Блокировка по диапазону IP срабатывает в случае, если не определяется страна.
Возможные методы блокировки: challenge (каптча), block (запрет доступа), js_challenge (ява скриптовая проверка, без ввода каптчи), managed_challenge (каптча только для "подозрительных" IP).
Как вариант, для стран и диапазонов IP можно сделать более мягкую блокировку, вот так:
'block_method'=>['country'=>'js_challenge', 'ip_range'=>'js_challenge', 'ip'=>'managed_challenge']
Подключение скрипта
В исполняемом файле (как-правило index.php) нужно добавить файл include.php.
Например, так (сверху, после <?php).
PHP:
<?php
include($_SERVER['DOCUMENT_ROOT'].'/[название папки скрипта]/include.php');
PHP:
<?php
include([абсолютный путь к папке скрипта]/include.php');
PHP:
<?php
if (!strpos($_SERVER['REQUEST_URI'], '?css=') && !strpos($_SERVER['REQUEST_URI'], '.jpg?') && !strpos($_SERVER['REQUEST_URI'], '.js?'))
{
include([абсолютный путь к папке скрипта]/include.php');
}
PHP:
<?php
if ($_SERVER['REQUEST_URI']=='/')
{
include([абсолютный путь к папке скрипта]/include.php');
}
Дополнительные меры
Скрипт уязвим к досс атаке HEAD запросами, инструкция как их отсечь на сервере или в Cloudflare здесь: https://ddosforum.com/threads/1040/
Если у вас слабый виртуальный сервер, возможно будет падать база. Тогда нужно сделать bash скрипт, который будет запускать базу с заданной периодичностью, например, раз в 15 минут.
Код:
#!/bin/bash
/bin/systemctl start mysqld
# Может быть так
#/usr/bin/systemctl start mariadb
Панель администрирования доработана с предыдущей версии.
Появилась возможность удалять забаненные IP из админки, теперь есть фильтр по логам, лог ошибок и т.д.
Визуально:
Если возникли вопросы или обнаружились какие-то ошибки, пишите в теме.
Последнее редактирование: