Интеграция Fail2ban с CSF для противодействия DDoS на nginx

  • Tutorial
Набор скриптов ConfigServer Security & Firewall (CSF) изначально обладает достаточно богатыми возможностями по организации защиты сервера хостинга Web с помощью фильтра пакетов iptables. В частности с его помощью можно противостоять затоплению атакуемого хоста пакетами TCP SYN, UDP и ICMP слабой и средней силы. Дополняет CSF встроенный Login Failure Daemon (lfd), который осуществляет мониторинг журналов на предмет наличия многочисленных неудачных попыток авторизации в различных сетевых сервисах с целью подбора пароля. Такие попытки блокируются путем внесения адреса IP злоумышленника в черный список CSF.

Существует другой сторонний инструмент, реализующий аналогичный функционал: Fail2ban. Несмотря на схожесть решаемых задач, между lfd и Fail2ban присутствует кардинальное отличие. Первый имеет закрытую архитектуру и поддерживает ограниченный набор сервисов. В то время как второй позволяет самостоятельно разработать фильтры практически под любые задачи. Однако сожительствуют CSF и Fail2ban в пределах одного сервера плохо, поскольку обращаются с правилами iptables несколько бесцеремонно. Постараемся решить эту проблему на примере ОС Linux Debian v7.XX amd64 так, что бы извлечь максимум из возможностей обоих инструментов. А в качестве примера организуем защиту от атак DDoS на nginx.

В моей конфигурации CSF был изначально установлен и настроен на сервере. Останавливаться на этом вопросе подробно я не буду, материала по нему достаточно. Рекомендую внести следующие настройки в файл "/etc/csf/csf.conf":
SYNFLOOD = "1"
SYNFLOOD_RATE = "100/s"
SYNFLOOD_BURST = "10"

CONNLIMIT = "80;110,443;110"

PORTFLOOD = "80;tcp;20;1,443;tcp;20;1"

CT_LIMIT = "300"
CT_INTERVAL = "60"


Такая конфигурация позволит CSF противодействовать тем хостам, которые задействованы в атаке затопления пакетами TCP SYN или открывают большое количество подключений к портам TCP сервера HTTP.
Переходим к установке Fail2ban, по окончании которой его необходимо остановить и отключить автозапуск:
service fail2ban stop
update-rc.d -f fail2ban remove


Запускать Fail2ban мы будем средствами CSF. Для этого необходимо создать скрипт "/etc/csf/csfpost.sh":
#!/bin/sh
/etc/init.d/fail2ban reload


Он же обеспечит автоматическую загрузку правил Fail2ban в iptables, если CSF будет перезагружать свои, например, в случае обновления.
Идея интеграции Fail2ban с CSF строится на том, что для блокировки адресов IP злоумышленников первый будет использовать черный список второго, а не напрямую правила iptables. Однако полностью от iptables в Fail2ban мы не отказываемся.
Отключаем все фильтры в Fail2ban. Большую их часть перекрывает lfd. Fail2ban будем использовать только для того, что не поддерживает lfd.
sed -i "s|enabled  = true|enabled  = false|g" /etc/fail2ban/jail.conf


Добавляем поддержку CSF в Fail2ban. Для этого создадим файл настроек "/etc/fail2ban/action.d/csf-ip-deny.conf" следующего содержания:
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = csf -d <ip> Added by Fail2Ban for <name>
actionunban = csf -dr <ip>


Заменим для всех фильтров Fail2ban действие блокировки на созданный «csf-ip-deny»:
sed -i -e "s|banaction = |banaction = csf-ip-deny\n#banaction = |" /etc/fail2ban/jail.conf


Для особо назойливых злоумышленников предусмотрена длительная блокировка. Реализуется этот механизм путем контроля журнала самого Fail2ban. Создаем файл настроек "/etc/fail2ban/filter.d/fail2ban.conf":
[Definition]
# Count all bans in the logfile
failregex = fail2ban.actions: WARNING \[(.*)\] Ban <HOST>
# Ignore our own bans, to keep our counts exact.
# In your config, name your jail 'fail2ban', or change this line!
ignoreregex = fail2ban.actions: WARNING \[fail2ban\] Ban <HOST>


Добавляем в "/etc/fail2ban/jail.conf" следующие строки:
## fail2ban with CSF to block repeat offenders
[fail2ban]
enabled  = true
filter   = fail2ban
action   = iptables-allports
#          sendmail-whois[name=fail2ban]
logpath  = /var/log/fail2ban.log
maxretry = 10
# Find-time: 1 day
findtime = 86400
# Ban-time: 1 week
bantime = 604800


Т.е. те из злоумышленников, кто в течение суток блокировался другими фильтрами 10 и более раз, будет заблокирован этим фильтром на неделю. Обратите внимание, что тут используется действие «iptables-allports», а не «csf-ip-deny». Это не ошибка. Так нужно, что бы длительная блокировка не оказалась случайно снятой другими фильтрами.

Теперь на примере организации защиты nginx от атак DDoS рассмотрим создание правил фильтрации Fail2ban. Начнем с настройки nginx, в нем необходимо задействовать возможности модулей ngx_http_limit_conn_module и ngx_http_limit_req_module. Для этого добавляем следующие строки в настройки:
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn perip 100;
limit_conn_zone $server_name zone=perserver:10m;
limit_conn perserver 200;
limit_req_zone $binary_remote_addr zone=reqip:10m rate=10r/s;
limit_req zone=reqip burst=30;


Таким образом, мы установили лимиты на не более чем 100 подключений с одного адреса IP единовременно со скоростью 10-30 новых подключений в секунду и не более 200 – к одному сайту всего с любого количества адресов IP. Превышения будет фиксироваться в журнале ошибок, для которого мы настроим фильтры Fail2ban.
Создаем следующие файлы настроек.
"/etc/fail2ban/filter.d/nginx-conn-limit.conf"
# Fail2Ban configuration file
#

[Definition]
# Option:  failregex
# Notes.:  Regexp to catch a generic call from an IP address.
# Values:  TEXT
#
failregex = limiting connections by zone.*client: <HOST>

# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =


"/etc/fail2ban/filter.d/nginx-req-limit.conf"
# Fail2Ban configuration file
#
 
[Definition]
# Option:  failregex
# Notes.:  Regexp to catch a generic call from an IP address.
# Values:  TEXT
#
failregex = limiting requests.*client: <HOST>
 
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =


"/etc/fail2ban/filter.d/nginx-dos.conf"
# Fail2Ban configuration file
#

[Definition]
# Option:  failregex
# Notes.:  Regexp to catch a generic call from an IP address.
# Values:  TEXT
#
failregex = ^<HOST> -.*"(GET|POST).*HTTP.*"$

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =


Добавляем в "/etc/fail2ban/jail.conf":
[nginx-conn-limit]
enabled = true
filter = nginx-conn-limit
action = csf-ip-deny[name=nginx-conn-limit]
logpath = /var/log/nginx/error.log
maxretry = 4
findtime = 21600
bantime = 3600
 
[nginx-req-limit]
enabled = true
filter = nginx-req-limit
action = csf-ip-deny[name=nginx-req-limit]
logpath = /var/log/nginx/error.log
maxretry = 4
findtime = 21600
bantime = 3600

[nginx-dos]
# Based on apache-badbots but a simple IP check (any IP requesting more than
# 240 pages in 60 seconds, or 4p/s average, is suspicious)
enabled = true
filter  = nginx-dos
action = csf-ip-deny[name=nginx-dos]
logpath = /var/log/nginx/access.log
maxretry = 240
findtime = 60
bantime  = 3600


Фильтры «nginx-conn-limit» и «nginx-req-limit» будут блокировать тех, кто превышает лимиты на подключения к nginx, а «nginx-dos» – тех, кто слишком часто обращается к сайтам: более 240 страниц в минуту.

Часто целью атак является широкой распространенная CMS WordPress: перебор паролей и большое количество запросов XML-RPC. Организуем защиту от них тоже.
"/etc/fail2ban/filter.d/nginx-wp-login.conf"
[Definition]
failregex = <HOST> .*POST /wp-login.php
ignoreregex =</source>

"/etc/fail2ban/filter.d/nginx-wp-xmlrpc.conf"
<source lang="bash">[Definition]
failregex = <HOST> .*POST /xmlrpc.php
ignoreregex =


"/etc/fail2ban/filter.d/nginx-wp-register.conf"
[Definition]
failregex = ^<HOST> .* "GET /wp-login.php\?action=register HTTP/.*" .*$
ignoreregex =


Добавляем в "/etc/fail2ban/jail.conf":
[nginx-wp-login]
enabled = true
filter = nginx-wp-login
action = csf-ip-deny[name=nginx-wp-login]
logpath = /var/log/nginx/access.log
maxretry = 4
findtime = 600
bantime = 3600
 
[nginx-wp-xmlrpc]
enabled = true
filter = nginx-wp-xmlrpc
action = csf-ip-deny[name=nginx-wp-xmlrpc]
logpath = /var/log/nginx/access.log
maxretry = 4
findtime = 600
bantime = 3600

[nginx-wp-register]
enabled = true
filter = nginx-wp-register
action = csf-ip-deny[name=nginx-wp-register]
logpath = /var/log/nginx/access.log
maxretry = 4
findtime = 600
bantime = 3600


Вот, что можно будет наблюдать в журнале Fail2ban во время атаки DDoS на nginx:
spoiler
2015-01-04 13:44:10,660 fail2ban.actions: WARNING [nginx-req-limit] Ban 188.191.47.46
2015-01-04 13:44:11,668 fail2ban.actions: WARNING [nginx-conn-limit] Ban 109.187.63.199
2015-01-04 13:44:21,061 fail2ban.actions: WARNING [nginx-req-limit] 188.191.47.46 already banned
2015-01-04 13:44:29,382 fail2ban.actions: WARNING [nginx-conn-limit] Ban 178.123.155.115
2015-01-04 13:44:36,584 fail2ban.actions: WARNING [nginx-conn-limit] Ban 109.62.153.190
2015-01-04 13:44:38,246 fail2ban.actions: WARNING [nginx-dos] Ban 5.143.158.88
2015-01-04 13:44:38,826 fail2ban.actions: WARNING [nginx-req-limit] Ban 178.158.206.140
2015-01-04 13:44:41,739 fail2ban.actions: WARNING [nginx-conn-limit] Ban 5.44.168.38
2015-01-04 13:44:49,877 fail2ban.actions: WARNING [nginx-dos] Ban 91.214.131.71
2015-01-04 13:44:52,333 fail2ban.actions: WARNING [nginx-conn-limit] Ban 176.125.48.22
2015-01-04 13:44:53,395 fail2ban.actions: WARNING [nginx-req-limit] Ban 91.207.211.222
2015-01-04 13:44:53,773 fail2ban.actions: WARNING [nginx-dos] Ban 178.158.206.140
2015-01-04 13:44:54,849 fail2ban.actions: WARNING [nginx-conn-limit] Ban 5.143.158.88
2015-01-04 13:44:57,395 fail2ban.actions: WARNING [nginx-req-limit] 91.207.211.222 already banned
2015-01-04 13:44:57,765 fail2ban.actions: WARNING [nginx-dos] Ban 37.232.87.169
2015-01-04 13:44:58,073 fail2ban.actions: WARNING [nginx-conn-limit] Ban 77.34.22.95
2015-01-04 13:44:58,506 fail2ban.actions: WARNING [nginx-req-limit] Ban 93.80.45.244
2015-01-04 13:45:02,733 fail2ban.actions: WARNING [nginx-dos] Ban 176.120.38.238
2015-01-04 13:45:05,615 fail2ban.actions: WARNING [nginx-conn-limit] Ban 178.173.4.162


А вот так будут блокироваться чрезмерно назойливые злоумышленники:
spoiler
2015-01-04 11:43:29,618 fail2ban.actions: WARNING [nginx-wp-login] Ban 95.163.121.129
2015-01-04 12:43:30,160 fail2ban.actions: WARNING [nginx-wp-login] Unban 95.163.121.129
2015-01-04 12:56:53,543 fail2ban.actions: WARNING [nginx-wp-login] Ban 95.163.121.129
2015-01-04 13:56:54,279 fail2ban.actions: WARNING [nginx-wp-login] Unban 95.163.121.129
2015-01-04 14:02:40,932 fail2ban.actions: WARNING [nginx-wp-login] Ban 95.163.121.129
2015-01-04 15:02:41,040 fail2ban.actions: WARNING [nginx-wp-login] Unban 95.163.121.129
2015-01-04 15:12:16,906 fail2ban.actions: WARNING [nginx-wp-login] Ban 95.163.121.129
2015-01-04 16:12:16,937 fail2ban.actions: WARNING [nginx-wp-login] Unban 95.163.121.129
2015-01-04 16:55:33,362 fail2ban.actions: WARNING [nginx-wp-login] Ban 95.163.121.129
2015-01-04 17:55:34,142 fail2ban.actions: WARNING [nginx-wp-login] Unban 95.163.121.129
2015-01-04 18:23:37,665 fail2ban.actions: WARNING [nginx-wp-login] Ban 95.163.121.129
2015-01-04 19:23:38,136 fail2ban.actions: WARNING [nginx-wp-login] Unban 95.163.121.129
2015-01-04 19:45:46,850 fail2ban.actions: WARNING [nginx-wp-login] Ban 95.163.121.129
2015-01-04 20:03:17,247 fail2ban.actions: WARNING [nginx-wp-login] Ban 92.255.28.42
2015-01-04 20:45:47,085 fail2ban.actions: WARNING [nginx-wp-login] Unban 95.163.121.129
2015-01-04 21:03:17,297 fail2ban.actions: WARNING [nginx-wp-login] Unban 92.255.28.42
2015-01-04 21:09:51,996 fail2ban.actions: WARNING [nginx-wp-login] Ban 92.255.28.42
2015-01-04 21:16:22,336 fail2ban.actions: WARNING [nginx-wp-login] Ban 95.163.121.129
2015-01-04 22:09:52,036 fail2ban.actions: WARNING [nginx-wp-login] Unban 92.255.28.42
2015-01-04 22:13:27,799 fail2ban.actions: WARNING [nginx-wp-login] Ban 92.255.28.42
2015-01-04 22:16:23,295 fail2ban.actions: WARNING [nginx-wp-login] Unban 95.163.121.129
2015-01-04 22:24:56,755 fail2ban.actions: WARNING [nginx-wp-login] Ban 95.163.121.129
2015-01-04 23:13:28,058 fail2ban.actions: WARNING [nginx-wp-login] Unban 92.255.28.42
2015-01-04 23:16:50,235 fail2ban.actions: WARNING [nginx-wp-login] Ban 92.255.28.42
2015-01-04 23:24:56,843 fail2ban.actions: WARNING [nginx-wp-login] Unban 95.163.121.129
2015-01-05 00:00:42,183 fail2ban.actions: WARNING [nginx-wp-login] Ban 95.163.121.129
2015-01-05 00:00:43,851 fail2ban.actions: WARNING [fail2ban] Ban 95.163.121.129
2015-01-05 00:16:50,263 fail2ban.actions: WARNING [nginx-wp-login] Unban 92.255.28.42
2015-01-05 00:23:22,863 fail2ban.actions: WARNING [nginx-wp-login] Ban 92.255.28.42
2015-01-05 01:00:42,637 fail2ban.actions: WARNING [nginx-wp-login] Unban 95.163.121.129
2015-01-05 01:23:23,750 fail2ban.actions: WARNING [nginx-wp-login] Unban 92.255.28.42
2015-01-05 01:26:16,543 fail2ban.actions: WARNING [nginx-wp-login] Ban 92.255.28.42
2015-01-05 02:26:16,681 fail2ban.actions: WARNING [nginx-wp-login] Unban 92.255.28.42
2015-01-05 02:32:28,850 fail2ban.actions: WARNING [nginx-wp-login] Ban 92.255.28.42
2015-01-05 03:32:29,350 fail2ban.actions: WARNING [nginx-wp-login] Unban 92.255.28.42
2015-01-05 03:39:18,048 fail2ban.actions: WARNING [nginx-wp-login] Ban 92.255.28.42
2015-01-05 04:39:18,609 fail2ban.actions: WARNING [nginx-wp-login] Unban 92.255.28.42
2015-01-05 04:43:38,428 fail2ban.actions: WARNING [nginx-wp-login] Ban 92.255.28.42
2015-01-05 05:43:39,091 fail2ban.actions: WARNING [nginx-wp-login] Unban 92.255.28.42
2015-01-05 05:47:47,722 fail2ban.actions: WARNING [nginx-wp-login] Ban 92.255.28.42
2015-01-05 05:47:50,212 fail2ban.actions: WARNING [fail2ban] Ban 92.255.28.42
2015-01-05 06:47:48,343 fail2ban.actions: WARNING [nginx-wp-login] Unban 92.255.28.42


В последнее время участились случаи, когда злоумышленники осуществляют распределенный перебор паролей с разных адресов IP одной подсети класса C. Алгоритм работы Fail2ban не способен распознать такое поведение:
spoiler
2015-01-05 14:01:14,432 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.176
2015-01-05 14:01:14,656 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.249
2015-01-05 14:01:35,906 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.198
2015-01-05 14:02:39,536 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.154
2015-01-05 14:02:53,766 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.132
2015-01-05 14:02:53,980 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.202
2015-01-05 14:04:00,782 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.136
2015-01-05 14:04:05,007 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.104
2015-01-05 14:04:07,234 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.167
2015-01-05 14:04:25,473 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.143
2015-01-05 14:05:26,993 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.253
2015-01-05 14:06:25,719 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.230
2015-01-05 14:06:27,945 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.162
2015-01-05 14:07:23,484 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.153
2015-01-05 14:07:56,962 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.140
2015-01-05 14:08:11,207 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.142
2015-01-05 14:09:37,759 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.137
2015-01-05 14:10:59,757 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.175
2015-01-05 14:11:04,030 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.117
2015-01-05 14:11:23,273 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.218
2015-01-05 14:11:41,517 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.139
2015-01-05 14:13:22,590 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.204
2015-01-05 14:13:24,808 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.220
2015-01-05 14:14:36,124 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.190
2015-01-05 14:14:38,356 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.179
2015-01-05 14:14:38,577 fail2ban.actions: WARNING [nginx-wp-login] Ban 193.176.147.137
2015-01-05 14:14:49,805 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.188
2015-01-05 14:15:48,398 fail2ban.actions: WARNING [nginx-wp-login] Unban 193.176.147.131


Устраним этот недостаток с помощью следующего скрипта, который будет выполняться каждый час планировщиком cron.
"/etc/cron.hourly/fail2ban-subnets"
#!/bin/bash

log="/var/log/fail2ban.log"
limit=30
grep=`which grep`

${grep} "fail2ban.actions.*Ban" ${log} | ${grep} -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" | awk -F'.' '{print $1"."$2"."$3}' | sort -u | while read line
	do
		count=$(${grep} -c "fail2ban.actions.*Ban.*${line}" ${log})
			if [ ${count} -ge ${limit} ]
				then
					/usr/sbin/csf -td ${line}.0/24 7d "Subnet ${line}.0/24 is blocked for a week by Fail2ban after ${count} attempts"
			fi
	done

exit 0


Т.е. сети IP класса C будут заблокированы на неделю целиком, если ранее другие фильтры Fail2ban срабатывали на адреса из них 30 или более раз.
Вот так выглядит результат:
# csf -t

A/D   IP address                               Port   Dir   Time To Live     Comment
DENY  193.176.147.0/24                           *    in    6d 21h 34m 18s   Subnet 193.176.147.0/24 is blocked for a week by Fail2ban after 641 attempts
DENY  46.148.30.0/24                             *    in    6d 21h 34m 19s   Subnet 46.148.30.0/24 is blocked for a week by Fail2ban after 332 attempts
DENY  46.148.31.0/24                             *    in    6d 21h 34m 19s   Subnet 46.148.31.0/24 is blocked for a week by Fail2ban after 334 attempts


При написании данной статьи были использованы наработки со следующих ресурсов:
https://extremeshok.com/5030/ubuntu-lts-fail2ban-with-csf-and-blocking-of-repeat-offenders-scan-log-files-to-ban-malicious-ips-and-prevent-brute-forcing-of-logins-with-configs/
http://tecadmin.net/add-custom-iptables-rules-with-csf/
https://rtcamp.com/tutorials/nginx/block-wp-login-php-bruteforce-attack/
https://rtcamp.com/tutorials/nginx/fail2ban/
https://www.xaker.name/forvb/showthread.php?t=28659
https://beeznest.wordpress.com/2012/06/08/anti-nginx-dos-filter-for-fail2ban-4/
https://debian.pro/1223
http://www.michelem.org/2014/03/02/stopblock-apachenginx-hack-attempts-with-fail2ban/
http://www.krazyworks.com/permanently-ban-ip-with-fail2ban/
http://www.shellhacks.com/ru/RegEx-Nayti-IP-Adresa-v-Fayle-s-Pomoshchyu-Grep
SIM-Networks
48,00
Professional hosting solutions — Hosted in Germany
Поделиться публикацией

Комментарии 14

    +7
    В последнее время участились случаи, когда злоумышленники осуществляют распределенный перебор паролей с разных адресов IP одной подсети класса C
    Не совсем правда, т.к. гораздо чаще это бот-сети с абсолютно разных IP адресов. Просто это не так очевидно (IP же разные).
    Алгоритм работы Fail2ban не способен распознать такое поведение
    Позвольте (как сотруднику fail2ban) не согласиться: пока IPv6 не допилен, атаки из подсети в IPv4 это действительно редкость и тогда это не совсем так — существуют как минимум две возможности сделать подобное средствами f2b:
    • используя jail «recidive» (не очень гибкое решение, подобное вашему cron, хотя и не для подсети);
    • используя эту версию ban-time-incr, к сожалению уже довольно долго валяющуюся pull-реквестом (более гибкое решение, позволяющее увеличивать время бана нелинейно, хотя тоже пока не для подсети); Я как-то писал об этом на хабре.
    • IPv6 уже в окончательной стадии разработки — там появится возможность определять ширину полосы (маску) подсетей (и возможно веса к ним). Подробнее можно почитать тут и тут.

    Ну а пока, изменив параметры «actionban» и «actionunban» например для «recidive» можно уже сейчас блокировать подсети. Хотя для IPv4 это имхо не нужно, т.к. действительно редкость. Тем более из-за одного двух нехороших адресов класть всю подсеть в бан на неделю — как-то через чур уж жестко.

    Бегло собрал статистику со всех своих серверов (и некоторых customer с большой посещаемостью) — из всех плохих адресов (из bips) свалившихся в бан с инкрементом:
    — 8 пар и 1 тройка из одной подсети /24 для IP с баном больше 1 дня;
    — 3 пары из одной подсети /24 в бане дольше недели;
    — и ни одного (subnet /24) с баном более месяца;
    Всего 17.4 тысяч уникальных IP с баном длиннее 1 дня, т.е. действительно плохих (banCount > 5).
      0
      Не совсем правда, т.к. гораздо чаще это бот-сети с абсолютно разных IP адресов. Просто это не так очевидно (IP же разные).
      lfd выявляет и блокирует подобного рода атаки, однако, только для поддерживаемых им сервисов. Это одна из причин, по которой я предпочел использовать Fail2ban как дополнение к CSF.

      используя jail «recidive» (не очень гибкое решение, подобное вашему cron, хотя и не для подсети);
      Эта методика описана в статье.

      используя эту версию ban-time-incr, к сожалению уже довольно долго валяющуюся pull-реквестом (более гибкое решение, позволяющее увеличивать время бана нелинейно, хотя тоже пока не для подсети); Я как-то писал об этом на хабре.
      Описанное в статье решение базируется на Fail2ban v0.8.6 из стандартного репозитория Debian Wheezy.

      IPv6 уже в окончательной стадии разработки — там появится возможность определять ширину полосы (маску) подсетей (и возможно веса к ним). Подробнее можно почитать тут и тут.
      Т.е. в итоге полноценной поддержки подсетей в Fail2ban пока нет. А вести полемику на тему того, чей костыль красивее :-) и насколько целесообразно его применение, я смысла не вижу.

      Ну а пока, изменив параметры «actionban» и «actionunban» например для «recidive» можно уже сейчас блокировать подсети.
      Такая методика может привести к тому, что заблокированной окажется вся подсеть буквально из-за одного адреса IP, проявляющего чрезмерную активность.

      Хотя для IPv4 это имхо не нужно, т.к. действительно редкость.
      В статье приведена выдержка из журнала, которая наглядно показывает, что идет целенаправленный подбор с разных IP одной подсети. Это не синтетический тест. Далее по тексту приведен результат работы скрипта из cron со статистикой попыток для трех заблокированных подсетей: 332-641. Идея написания скрипта родилась у меня, когда статья уже была по большей части готова. Я взглянул на журнал работы Fail2ban и обнаружил, что идет массовый перебор с разных IP одних и тех подсетей. Насколько такие случаи являются массовыми, судить не берусь.

      Тем более из-за одного двух нехороших адресов класть всю подсеть в бан на неделю — как-то через чур уж жестко.
      Для того, что бы снизить вероятность этого используется двухступенчатая фильтрация. jail «recidive» блокирует отдельные IP на неделю, если они проявляли чрезмерную активность в течение суток: 10 или более блокировок. А срипт из cron в связке с соответствующими настройками logrotate блокирует также на неделю те подсети, чьи адреса набрали за туже неделю 30 или более блокировок. Таким образом, для блокировки всей подсети необходимо как минимум три активных адреса :-)
        0
        Это одна из причин, по которой я предпочел использовать Fail2ban как дополнение к CSF...
        А вести полемику на тему того, чей костыль красивее...
        Дык я вам не про то что красивее, а про то что для IPv4 подсетей оно как бы и не нужно… Достаточно при повторах просто ложить в бан дольше чем это делает сама jail (пользуем либо recidive, либо ban-time-incr, либо и то и другое).
        Ну улетят все адресса из subnet чуть познее в бан чем у вас — в результате эти лишние 15 минут не идут ни в какое сравнение с неделей в бане (= 10080 минут).

        Про остальное же (wp-фильтр для f2b, nginx limit_req и т.д.) в интернетах материала уйма, было неоднократно и на хабре — например тут или тут.
        0
        Вы не в курсе, планирует ли fail2ban поддерживать nftables? Интересно, на что повлияет миграция на новый фреймворк.
          0
          Не слышал пока, но поспрашиваю…
          А так, ежели просто переписать actions использующие iptables на nftables — дело то не хитрое, но результат не будет уметь (использовать) такие вкусности как expressions в правилах (aka instructions) и т.д. Я так понимаю, что ваш вопрос про это?
        0
        [зануда]
        Например по C будут баниться 3г модемы полосатого оператора и прочий мобильный инет. У меня товарищ замучался постоянно либо переподключаться, либо через аномайзер/впн открывать. Далеко ходить не надо, хабрасторадж постоянно банит и картинки у него, соответственно, не открываются. А гугл капчу просит переодически, типа с вашей подсети много запросов. Хотя, возможно это зависит от региона.
        [/зануда]
        Хотя конечно не факт.
        • НЛО прилетело и опубликовало эту надпись здесь
            0
            С удовольствие ознакомлюсь со статьей на тему написания собственных «regex.custom.pm» :-) Конкретно в моем случае необходимо было спешно развернуть защиту от DDoS на базе имевшихся наработок под Fail2ban. Интегрировать последний с CSF оказалось быстрее, нежели переделывать все под RegExp.
            0
            Подскажите как будет вести себя сервер при добавлении в бан 100000 ip?
              +2
              Если на каждый ip создавать свое правило iptables, то будет вести себя плохо. Для подобных задач можно использовать ipset
              0
              intelligence CSF в зависимости от настроек может использовать ipset или создавать по отдельному правилу iptables на каждый заблокированный адрес IP. Но это неважно. Если на вас натравят сеть ботов в ~100000 уникальных адресов, то iptables никак не справится с такой атакой, что с ipset, что без оного. Тут потребуется уже профессиональная защита от DDoS. Описанное решение способно противостоять только атакам слабой и средней мощности.
                0
                100000 уникальных адресов раскидываются балансировщиком на нужное количество нод (10-50) и перестают быть проблемой. Тем более что они все обычно одновременно не используются — т.е. возможна ротация.
                0
                Проблема в том, что простого iptables достаточно для противодействия атакам малой и средней мощности (до 30-50 Гбит/с), но только в случае отсутствия slow-DDoS (когда идет по 10-20 запросов в минуту с разных IP адресов, что не попадает ни под какие из вышеперечисленных фильтров).
                Защита одного конкретно взятого сайта или даже семейства сайтов на одной CMS тоже большой проблемы не представляет: если известна инфраструктура, то быстрее руками дырки почистить. Но если инфраструктура неизвестна, и нужно «на лету» определять, какие запросы являются «вредными», решение будет посложнее.
                Единственное технологически отлаженное решение сейчас у QRator, но там много false positive, и цены высокие.
                  0
                  Попросили похожее сделать, дали ссылку на данную статью ;)
                  Обнаружил что на Debian не всегда заводится, причина даже в конфиге описана, но упомяну ее здесь. В файле /etc/fail2ban/jail.com нужно поставить параметр:
                  backend = polling
                  Т.к. auto чаще всего выбирает gamin и… это не работает, особенно если у вас relatime/noatime.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое