Fail2Ban: установка и настройка инструмента для защиты от брутфорса

Брутфорс (перебор паролей) – одна из самых частых атак на серверы. Боты круглосуточно сканируют интернет и подбирают логины и пароли к SSH, панелям управления, почте и сайтам. При помощи Fail2Ban сервер можно защитить от брутфорса – эта служба-демон анализирует логи сервисов, ловит подозрительную активность и автоматически блокирует IP-адреса нарушителей через файрвол. 

В этой статье разберем, как установить Fail2Ban и выполнить его тонкую настройку: подобрать пороги блокировок, защитить нужные сервисы, написать собственный фильтр (failregex) и проверить его утилитой fail2ban-regex, настроить email-уведомления, а также включить прогрессивные блокировки.

Обратите внимание!
Fail2Ban управляет правилами файрвола (iptables/nftables) и требует root-доступа. Поэтому он применим на VPS и выделенных серверах. На виртуальном хостинге настроить его нельзя.

Что такое Fail2Ban и как он работает

Fail2Ban – это служба-демон, написанная на Python, которая работает по простой схеме:

  1. Читает логи сервисов (например, /var/log/auth.log или журнал systemd для SSH).
  2. Сравнивает строки с шаблонами – регулярными выражениями (фильтрами), которые описывают неудачные попытки входа.
  3. Считает совпадения для каждого IP за заданный промежуток времени.
  4. Если число попыток превысило лимит – выполняет действие (action), как правило, добавляет правило блокировки в файрвол.
  5. По истечении времени бана IP автоматически разблокируется.

Три ключевых понятия Fail2Ban:

  • Jail (тюрьма) – связка «лог + фильтр + действие + пороги» для конкретного сервиса. Например, jail sshd защищает SSH.
  • Filter (фильтр) – набор регулярных выражений (failregex), по которым находятся подозрительные строки в логе.
  • Action (действие) – что делать с нарушителем: заблокировать в iptables, отправить письмо администратору и т. д.

Установка Fail2Ban

Debian / Ubuntu

apt update
apt install fail2ban -y

CentOS / RHEL / AlmaLinux / Rocky Linux

Пакет находится в репозитории EPEL:

dnf install epel-release -y
dnf install fail2ban -y

После установки включите автозапуск и стартуйте службу:

systemctl enable --now fail2ban
systemctl status fail2ban

Проверить работу можно командой:

fail2ban-client ping

В ответ должно прийти Server replied: pong.

Конфигурация Fail2Ban хранится в каталоге /etc/fail2ban/. Основные файлы:

  • jail.conf – конфигурация по умолчанию. Редактировать ее не нужно: при обновлении пакета файл перезапишется, а ваши изменения пропадут.
  • jail.local – ваш собственный файл с настройками. Параметры из него переопределяют значения из jail.conf.
  • jail.d/*.conf – отдельные файлы для конфигурации конкретных jail (альтернатива jail.local).
  • filter.d/ – фильтры (регулярные выражения).
  • action.d/ – действия (способы блокировки и уведомлений).

Всю тонкую настройку рекомендуется выполнять в jail.local. Создать его можно следующим образом:

nano /etc/fail2ban/jail.local

Базовые параметры в секции [DEFAULT]

Секция [DEFAULT] задает значения для всех jail. Их можно переопределять внутри каждой отдельной «тюрьмы». Пример jail.local:

[DEFAULT]
# IP-адреса и подсети, которые никогда не блокируются
ignoreip = 127.0.0.1/8 ::1 203.0.113.10

# Время блокировки (в секундах). 1h = 1 час
bantime = 1h

# Окно наблюдения: за какой период считаем попытки
findtime = 10m

# Сколько неудачных попыток разрешено до блокировки
maxretry = 5

# Способ блокировки
banaction = iptables-multiport

Разберем каждый параметр.

  • ignoreip – белый список

Список IP-адресов и подсетей, которые Fail2Ban не будет блокировать никогда. Рекомендуется добавить сюда свой постоянный IP (например, рабочий или домашний с фиксированным адресом), чтобы случайно не заблокировать самого себя. Поддерживаются отдельные адреса, CIDR-подсети и доменные имена.

ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16 203.0.113.10
  • bantime – длительность блокировки

Время бана в секундах. Можно использовать суффиксы: m (минуты), h (часы), d (дни), w (недели).

  • bantime = 600 – 10 минут;
  • bantime = 1d – сутки;
  • bantime = -1 – бессрочная блокировка.

Слишком короткий бан легко обходится ботами, слишком длинный – рискует надолго заблокировать легитимного пользователя, допустившего ошибку в пароле. Ниже, в разделе про прогрессивные баны, мы покажем, как автоматически увеличивать срок за повторные нарушения. 

  • findtime – окно подсчета попыток

Промежуток времени, за который считаются неудачные попытки. Если за findtime с одного IP накопилось maxretry ошибок, IP блокируется. Пример: при findtime = 10m и maxretry = 5 блокировка наступит после 5 неудачных входов в течение 10 минут.

  • maxretry – порог срабатывания

Допустимое число неудачных попыток до блокировки. Чем меньше значение, тем строже защита, но тем выше риск заблокировать пользователя, который просто ошибся при вводе пароля. 

Откуда Fail2Ban читает логи: backend и logpath

У Fail2Ban есть два принципиально разных способа получать записи логов, и они не комбинируются в рамках одного jail:

  • backend = systemd – чтение из журнала systemd (journald). Параметр logpath при этом игнорируется; источник при необходимости уточняется через journalmatch. Это рекомендуемый вариант получения записи логов Fail2Ban для современных Ubuntu (22.04/24.04) и Debian 12+, где многие сервисы (включая SSH) больше не пишут в текстовые файлы.
  • backend = auto / polling / pyinotify – отслеживание текстовых лог-файлов. Здесь обязательно нужен корректный logpath.

Из-за этого важно не задавать глобально backend = systemd в [DEFAULT], а потом во всех jail указывать logpath на файлы – для journald-бэкенда эти пути просто не работают. Правильный подход – выбирать backend для каждого сервиса по тому, куда он реально пишет логи:

  • SSH в последней Ubuntu/Debian – backend = systemd (без logpath);
  • Nginx, Apache, FTP и большинство веб-приложений – они по умолчанию ведут собственные текстовые логи, поэтому backend = auto + logpath.

Поэтому в примерах ниже backend указан в каждой «тюрьме» отдельно, а в [DEFAULT] мы его жестко не фиксируем.

Тонкая настройка защиты SSH с Fail2Ban

SSH – главная цель брутфорс-программы. Вариант настройки зависит от того, куда система пишет SSH-логи.

Современные Ubuntu 24.04 / Debian 12 (логи в journald)

На Ubuntu 24.04 в облачных и минимальных образах rsyslog по умолчанию не установлен – файла /var/log/auth.log попросту нет, всё попадает в journald. В этом случае нужен systemd-бэкенд без logpath:

[sshd]
enabled = true
port = 22
filter = sshd
backend = systemd
maxretry = 3
findtime = 10m
bantime = 2h
# По умолчанию фильтр sshd уже содержит подходящий journalmatch.
# Уточнить источник можно вручную (на Ubuntu/Debian unit называется ssh.service):
# journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd

Системы с текстовыми логами (CentOS/RHEL либо установленный rsyslog)

Если сервис пишет в файл, используйте файловый бэкенд и укажите путь к логу:

[sshd]
enabled = true
port = 22
filter = sshd
backend = auto
logpath = /var/log/auth.log   # на CentOS/RHEL: /var/log/secure
maxretry = 3
findtime = 10m
bantime = 2h

Если был изменен стандартный SSH-порт, обязательно укажите актуальный в параметре port.

После правок перезапустите службу и проверьте статус jail:

systemctl restart fail2ban
fail2ban-client status sshd

В выводе вы увидите число найденных и заблокированных IP, а также список текущих банов.

Защита других сервисов

Fail2Ban поставляется с готовыми фильтрами для популярных сервисов. Достаточно включить нужный jail в jail.local. Перечисленные ниже сервисы по умолчанию ведут собственные текстовые логи, поэтому для них используется файловый бэкенд и logpath.

Веб-сервер Nginx

Блокировка перебора HTTP-авторизации:

[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
backend = auto
logpath = /var/log/nginx/error.log
maxretry = 5

Защита от ботов, перебирающих несуществующие страницы и скрипты:

[nginx-botsearch]
enabled = true
filter = nginx-botsearch
port = http,https
backend = auto
logpath = /var/log/nginx/access.log
maxretry = 10

Веб-сервер Apache

[apache-auth]
enabled = true
filter = apache-auth
port = http,https
backend = auto
logpath = /var/log/apache2/error.log
maxretry = 5

FTP (vsftpd / proftpd)

[vsftpd]
enabled = true
filter = vsftpd
port = ftp,ftp-data,ftps,ftps-data
backend = auto
logpath = /var/log/vsftpd.log

После включения любого jail проверяйте его статус и наличие нужного лог-файла. Fail2Ban не запустит «тюрьму», если путь к логу указан неверно.

Собственный фильтр: пишем и проверяем failregex

Если сервис нестандартный (например, самописное приложение или панель), готового фильтра может не быть – придется написать свой. 

Фильтр – это файл в каталоге filter.d/ с регулярными выражениями. Ключевой элемент – токен <HOST>, которым обозначается место, где в строке лога стоит IP-адрес нарушителя.

Допустим, приложение пишет в /var/log/myapp/app.log строки вида:

2026-06-28 12:00:01 WARNING Failed login for user admin from 203.0.113.77

Создаем фильтр /etc/fail2ban/filter.d/myapp.conf:

[Definition]
failregex = ^.*Failed login for user .* from <HOST>\s*$
ignoreregex =

failregex ловит подозрительные строки, ignoreregex – исключения, которые нужно игнорировать даже при совпадении с failregex.

Проверка фильтра утилитой fail2ban-regex

Перед тем как включать jail рекомендуется проверить фильтр на реальном логе – это избавляет от нерабочих или слишком «жадных» правил:

bashfail2ban-regex /var/log/myapp/app.log /etc/fail2ban/filter.d/myapp.conf

Утилита покажет, сколько строк совпало (matched) и сколько проигнорировано (missed). Можно проверить и одну конкретную строку, не трогая файл:

bashfail2ban-regex "2026-06-28 12:00:01 Failed login for user admin from 203.0.113.77" \
  "^.*Failed login for user .* from <HOST>\s*$"

Если совпадений нет, обычно проблема в формате даты – добавьте в фильтр свой datepattern или используйте флаг --print-all-matched для отладки.

Когда фильтр отлажен, подключаем его в jail.local:

[myapp]
enabled = true
filter = myapp
backend = auto
logpath = /var/log/myapp/app.log
maxretry = 5
findtime = 10m
bantime = 1h

Email-уведомления о банах

По умолчанию Fail2Ban не отправляет писем о блокировках IP. Чтобы получать уведомления, нужен настроенный MTA на сервере (например, postfix или sendmail) и несколько параметров в [DEFAULT]:

[DEFAULT]
# Кому отправлять письма
destemail = admin@example.com

# От кого
sender = fail2ban@example.com

# Программа отправки почты
mta = sendmail

# Действие: бан + письмо
action = %(action_mw)s

Доступные варианты действий с уведомлением:

  • %(action_)s – только бан (по умолчанию);
  • %(action_mw)s – бан + письмо с краткой информацией и результатом whois по IP;
  • %(action_mwl)s – то же, что action_mw, плюс относящиеся к инциденту строки из лога.

Уведомления можно включить и точечно – указав action внутри конкретного jail, а не глобально.

Прогрессивные баны (bantime.increment)

Это одна из тех настроек, которые делают защиту по-настоящему «тонкой». По умолчанию все нарушители получают одинаковый срок бана. С bantime.increment срок автоматически растет при каждом повторном попадании одного и того же IP в баны:

[DEFAULT]
# Включить прогрессивное увеличение времени бана
bantime.increment = true

# Базовый срок
bantime = 1h

# Множитель: каждый следующий бан длиннее предыдущего
bantime.factor = 2

# Потолок: дольше этого срока бан не вырастет
bantime.maxtime = 1w

При таких настройках первый бан длится час, второй – дольше, и так далее, пока не упрется в bantime.maxtime (неделя). Настойчивые боты в итоге блокируются надолго, а случайно ошибившийся пользователь отделывается коротким первым баном.

Jail recidive: ловим рецидивистов

recidive – отдельная «тюрьма», которая следит не за логами сервисов, а за собственным логом Fail2Ban (/var/log/fail2ban.log) и блокирует надолго тех, кто уже неоднократно попадал в баны других jail. Это второй рубеж: даже если бот после короткого бана возвращается снова и снова, recidive отправит его в долгую блокировку.

[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
banaction = iptables-allports
# 5 банов за сутки -> длительная блокировка
findtime = 1d
bantime = 1w
maxretry = 5

Для работы recidive Fail2Ban должен вести лог в файл – убедитесь, что в fail2ban.conf (или fail2ban.local) задан logtarget = /var/log/fail2ban.log, а не только syslog/systemd.

Управление через fail2ban-client

Основные команды для повседневной работы:

# Общий статус: список активных jail
fail2ban-client status

# Подробный статус конкретной тюрьмы
fail2ban-client status sshd

# Вручную заблокировать IP
fail2ban-client set sshd banip 203.0.113.50

# Разблокировать IP
fail2ban-client set sshd unbanip 203.0.113.50

# Перезагрузить конфигурацию без полной остановки
fail2ban-client reload

Если вы случайно заблокировали себя и потеряли доступ по SSH – войдите на сервер через терминал в панели управления Beget и выполните команду разблокировки своего IP.

FAQ

Можно ли установить Fail2Ban на виртуальном хостинге Beget?

Нет. Fail2Ban управляет правилами файрвола и требует прав root, которых на виртуальном хостинге нет. Используйте его на VPS или выделенном сервере. На виртуальном хостинге защита от перебора уже реализована платформой.

Как проверить, что Fail2Ban действительно блокирует атаки?

Выполните fail2ban-client status sshd – в строке Banned IP list будут видны заблокированные адреса. Также можно изучить лог /var/log/fail2ban.log.

Что делать, если я сам попал в бан?

Зайдите на сервер через терминал в панели управления Beget (минуя SSH) и выполните fail2ban-client set sshd unbanip ВАШ_IP, после чего добавьте свой адрес в ignoreip.

Заменяет ли Fail2Ban файрвол?

Нет. Fail2Ban работает поверх файрвола (iptables/nftables) и лишь динамически добавляет правила блокировки. Базовую настройку файрвола нужно выполнять отдельно.

Чем брутфорс отличается от DDoS, спасет ли Fail2Ban от DDoS?

Брутфорс-атака – это перебор паролей с относительно небольшого числа адресов, с ним Fail2Ban справляется хорошо. От массированных распределенных DDoS-атак он малоэффективен – для этого нужны специализированные средства защиты.

Если возникнут вопросы, напишите нам, пожалуйста, тикет из панели управления аккаунта (раздел «Помощь и поддержка»), а если вы захотите обсудить наши продукты с коллегами по цеху и сотрудниками Beget – ждем вас в нашем сообществе в Telegram.