Данная статья посвящена примитивной защите от DDoS-атак.
Примечание: видео материал можно посмотреть тут (Настраиваем fail2ban: защита от DoS и подбора паролей). Ниже изложен краткий конспект видео урока.
apt install fail2ban -y apt install ipset -y
Примечание: ipset нам понадобиться ниже.
Делаем копию файла /etc/fail2ban/jail.conf jail.local, чтобы после обновления fail2ban настройки не «перетёрлись»:
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Шаг 1.
Создаём блокировку для «частых запросов«в NGINX (подробнее об этом модуле тут).
limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s; server { ... limit_req zone=perip burst=5 nodelay; }
Если скорость поступления запросов превышает описанную в зоне, то их обработка задерживается так, чтобы запросы обрабатывались с заданной скоростью. Избыточные запросы задерживаются до тех пор, пока их число не превысит максимальный размер всплеска. При превышении запрос завершается с ошибкой.
На примере выше указано: в среднем не более 1 запроса в секунду со всплеском не более 5 запросов (т.е. это некий буфер после наполнения, которого будет ошибка).
Примечание: 10m — это размер выделяемой памяти для хранения состояния.
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
В данном случае состояния хранятся в зоне “one” размером 10 мегабайт, и средняя скорость обработки запросов для этой зоны не может превышать 1 запроса в секунду.
В качестве ключа используется IP-адрес клиента. Обратите внимание, что вместо переменной $remote_addr
используется переменная $binary_remote_addr
. Длина значения переменной $binary_remote_addr
всегда равна 4 байтам для IPv4-адресов или 16 байтам для IPv6-адресов. При этом размер состояния всегда равен 64 байтам на 32-битных платформах и 128 байтам на 64-битных платформах. В зоне размером 1 мегабайт может разместиться около 16 тысяч состояний размером 64 байта или около 8 тысяч состояний размером 128 байт.
При переполнении зоны удаляется наименее востребованное состояние. Если и это не позволяет создать новое состояние, запрос завершается с ошибкой.
Пример:
# файл конфига *.conf NGINX для сайта limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s; server { ... location /dev { ... limit_req zone=perip burst=5 nodelay; } }
Если будет превышен указанный лимит, то в логах NGINX (/var/log/nginx/access.log) будут следующие строки:
... 10.10.6.100 - - [13/Oct/2022:03:51:12 +0000] "GET /dev/exists HTTP/1.1" 503 197 "-" "PostmanRuntime/7.29.2" "-" 10.10.6.100 - - [13/Oct/2022:03:51:13 +0000] "GET /dev/exists HTTP/1.1" 503 197 "-" "PostmanRuntime/7.29.2" "-" ...
И в /var/log/nginx/error.log:
2022/10/13 03:51:11 [error] 729700#729700: *38917 limiting requests, excess: 5.353 by zone "def_lkk", client: 10.10.6.100, server: lkk-sk.it-serv.ru, request: "GET /dev/exists HTTP/1.1", host: "lkk-sk.it-serv.ru" 2022/10/13 03:51:12 [error] 729700#729700: *38917 limiting requests, excess: 5.517 by zone "def_lkk", client: 10.10.6.100, server: lkk-sk.it-serv.ru, request: "GET /dev/exists HTTP/1.1", host: "lkk-sk.it-serv.ru"
Пользователь же увидит следующие HTML-код:
<html> <head><title>503 Service Temporarily Unavailable</title></head> <body> <center><h1>503 Service Temporarily Unavailable</h1></center> <hr><center>nginx/1.20.2</center> </body> </html>
Шаг 2.
Настраиваем fail2ban. Переходим в файл /etc/fail2ban/jail.local и редактируем параметры:
banaction = iptables-multiport banaction_allports = iptables-allports
на
banaction = iptables-ipset-proto6 banaction_allports = iptables-ipset-proto6-allports
Шаг 3.
Находим правило nginx-limit-req и приводим его к следующему виду:
#port = http,https #logpath = %(nginx_error_log)s port = http,https enabled = true filter = nginx-limit-req action = iptables-multiport[name=ReqLimit, port="http,https", protocol=tcp] logpath = /var/log/nginx/*error.log findtime = 600 bantime = 3600 maxretry = 4
enabled — указание на активность jail’а (включен/выключен);
port — здесь указываются порты, для которых будет работать наш фильтр. Можно указать словами или прописать конкретные значения (http, https, all, 22…);
filter — здесь указываем название нашего фильтра (имя файла до .conf), в нашем случае это new_filter
;
logpath — это путь к файлу с логами, которые будет анализировать фильтр; поскольку мы будем работать с логами подключения, то и путь указываем к этим логам /var/log/nginx/*error.log;
maxretry, findtime, bantime — параметры для поиска и бана (количество попыток, вызывающее срабатывание, время, за которое производится поиск и время бана; здесь они указаны в секундах, но можно для указания времени указывать часы, дни и недели, добавляя после значения h, d и w соответственно.
Шаг 4.
В каталоге /etc/fail2ban/action.d создаём файл iptables-blocktype.local и добавляем туда следующий текст:
[Init] blocktype = DROP
Данная настройка позволяет экономить ресурсы системы при защите от атак.
Шаг 5.
Проверяем работу fail2ban
ps afx | grep fail
Результатом должно быть:
Примечание: не забываем после обновлений конфига перезапускать fail2ban:
systemctl restart fail2ban
Делаем специально запросы таким образом, чтобы была блокировка. Результатом будет:
iptables -L -v -n
Смотрим информацию, которая хранится в fail2ban:
fail2ban-client status nginx-limit-req
Общие рекомендации:
# какие jail активные fail2ban-client status
# принудительно убрать конкретный IP из бана fail2ban-client set nginx-limit-req unbanip 10.10.6.100
# принудительная блокировка IP по правилу jail fail2ban-client set [name-of-jail] banip [ip-address]
# проверяем, как работает проверка fail2ban-regex /var/log/nginx/error*.log /etc/fail2ban/filter.d/nginx-limit-req.conf
Шаг 6.
Переключаемся на ipset. В файл /etc/fail2ban/jail.local комментируем строку action для jail=nginx-limit-req
Таким образом переключаемся на ipset. Перезапускаем fail2ban:
systemctl restart fail2ban
После повторного бана информацию, которая содержится в ipset
ipset -L
Полезные ссылки:
- https://serveradmin.ru/nastroyka-fail2ban-dlya-zashhityi-wordpress/ — Защита админки wordpress с помощью fail2ban
- https://nginx.org/ru/docs/http/ngx_http_limit_req_module.html — Модуль ngx_http_limit_req_module
- https://www.youtube.com/watch?v=GEwjjuxXow0 — Настраиваем fail2ban: защита от DoS и подбора паролей
- https://www.youtube.com/watch?v=mUiNYCrz-1M — Fail2ban — самое полное руководство по установке и настройке.