Fail2Ban. Установка и настройка

12.04.2026

Теги: LinuxЗащитаКлиентКонфигурацияНастройкаСерверУстановка

Fail2Ban — инструмент для защиты серверов Linux и Unix-подобных систем от автоматизированных атак, в частности от брутфорс (попыток подбора паролей) и других видов несанкционированного доступа. Он анализирует логи сервисов и автоматически блокирует IP-адреса при обнаружении подозрительной активности.

1. Установка

Обновляем индексы пакетов и устанавливаем утилиту

$ sudo apt update && sudo apt install fail2ban -y

Служба запустится автоматически, проверим её статус

$ sudo systemctl status fail2ban.service

2. Базовая настройка

Нельзя редактировать файл файл конфигурации /etc/fail2ban/jail.conf — при обновлении он может быть перезаписан.

$ sudo nano /etc/fail2ban/jail.local
[DEFAULT]
# Игнорировать эти IP-адреса (домашний или рабочий IP, чтобы случайно себя не заблокировать)
ignoreip = 127.0.0.1/8 ::1 123.123.123.123
# Окно времени, за которое учитываются неудачные попытки
findtime = 10m
# Количество разрешенных неудачных попыток до блокировки
maxretry = 5
# Время блокировки (в секундах, минутах или часах. Например — 10m = 10 минут, 10d = 10 дней)
bantime = 10m
# Использовать ufw (если установлен) или iptables для банов
banaction = iptables-multiport

3. Ротация логов

Отдельно настраивать не нужно — все уже было сделано при установке.

$ sudo cat /etc/logrotate.d/fail2ban
/var/log/fail2ban.log {
    weekly
    rotate 4
    compress
    # Do not rotate if empty
    notifempty

    delaycompress
    missingok
    postrotate
        fail2ban-client flushlogs 1>/dev/null
    endscript

    # If fail2ban runs as non-root it still needs
    # to have write access to logfiles.
    # create 640 fail2ban adm
    create 640 root adm
}

3. Примеры защиты

Чтобы включить защиту (jail) для конкретного сервиса — добавляем соответствующую секцию в файл jail.local.

Защита SSH (sshd)

Обычно включена по умолчанию, но полезно проверить параметры.

[sshd]
enabled  = true
port     = 22
filter   = sshd
logpath  = /var/log/auth.log
findtime = 10m
maxretry = 5
bantime  = 1h

Защита Nginx

Блокирует ботов, которые сканируют сайт на наличие скрытых файлов и панели администрирования.

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

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

Защита Apache

Аналогично — защищает от подбора паролей к закрытым директориям и сканирования скриптов.

[apache-auth]
enabled = true
filter  = apache-auth
port    = http,https
logpath = %(apache_error_log)s

[apache-noscript]
enabled  = true
filter   = apache-noscript
port     = http,https
logpath  = %(apache_error_log)s
maxretry = 3

Защита MySQL / MariaDB

Блокирует попытки подобрать пароль к базе данных, если её порт открыт наружу.

[mysqld-auth]
enabled = true
filter  = mysqld-auth
port    = 3306
logpath = /var/log/mysql/error.log

4. Применение настроек

После редактирования jail.local — применяем новые настройки

sudo systemctl reload fail2ban.service
Команда reload позволяет перечитать файлы конфигурации без перезагрузки (стоп-старт) службы.

5. Директива filter

Директива filter указывает, какое именно правило (регулярное выражение) использовать для поиска подозрительной активности в лог-файлах. Fail2Ban не знает сам, как выглядят строки об ошибках в разных службах. Для этого существуют фильтры — готовые конфигурационные файлы в директории /etc/fail2ban/filter.d/.

Например, директива filter = nginx-botsearch заставляет Fail2Ban открыть файл /etc/fail2ban/filter.d/nginx-botsearch.conf. Внутри этого файла прописаны регулярные выражения (regex), которые ищут в логах Nginx попытки ботов запросить несуществующие файлы вроде wp-login.php, setup.php и т.д.

Если имя фильтра совпадает с названием секции в квадратных скобках (например, [nginx-botsearch]), директиву filter можно вообще не использовать — Fail2Ban использует фильтр из названия секции.

6. Как создать фильтр

Допустим, мы установили FTP-сервер vsftpd, которые записывает свои логи в файл /var/log/vsftpd/vsftpd.log.

$ sudo cat /var/log/vsftpd/vsftpd.log | grep -i "fail login"
Wed May 20 20:58:55 2026 [pid 9541] [anonymous] FAIL LOGIN: Client "20.127.111.87"
Wed May 20 20:59:03 2026 [pid 9549] [admin] FAIL LOGIN: Client "20.127.111.87"
Wed May 20 20:59:09 2026 [pid 9551] [user] FAIL LOGIN: Client "20.127.111.87"
Wed May 20 20:59:17 2026 [pid 9555] [admin] FAIL LOGIN: Client "20.127.111.87"
Wed May 20 20:59:23 2026 [pid 9559] [root] FAIL LOGIN: Client "20.127.111.87"
Wed May 20 20:59:28 2026 [pid 9561] [guest] FAIL LOGIN: Client "20.127.111.87"
$ sudo nano /etc/fail2ban/filter.d/vsftpd-custom.conf
[Definition]
# Для работы fail2ban нужно сначала найти дату/время
datepattern = ^%%a %%b %%d %%H:%%M:%%S %%Y
# Описываем строку файла лога после вырезанной даты
failregex = ^\s*\[pid \d+\] \[.+\] FAIL LOGIN: Client "<HOST>"
ignoreregex =
^\s*                →  начало строки, возможные пробелы
\[pid \d+\]         →  [pid 12289]
\[.+\]              →  [anonymous] (любое имя)
FAIL LOGIN: Client  →  буквальный текст
"<HOST>"            →  "35.216.201.9" — IP для бана

Проверка регулярного выражения — нужна обязательно, легко допустить ошибку.

$ sudo fail2ban-regex /var/log/vsftpd.log /etc/fail2ban/filter.d/vsftpd.conf

Фильтр готов — добавляем секцию в файл конфигурации

$ sudo nano /etc/fail2ban/jail.local
[vsftpd]
enabled  = true
port     = 21
filter   = vsftpd-custom
logpath  = /var/log/vsftpd/vsftpd.log
findtime = 600
maxretry = 10
bantime  = 3600
$ sudo systemctl reload fail2ban.service

7. Директива banaction

Директива banaction указывает Fail2Ban, какую системную утилиту (брандмауэр) использовать для технической блокировки IP-адресов. Все доступные действия (экшены) хранятся в виде файлов в директории /etc/fail2ban/action.d/.

Основные и самые популярные варианты значений banactio для систем Ubuntu/Debian

  1. ufw — добавляет правила блокировки напрямую в UFW (Uncomplicated Firewall) — стандартный и простой брандмауэр Ubuntu
  2. iptables-multiport — блокирует IP-адрес в классическом iptables, закрывая сразу несколько портов (например, 22, 80, 443)
  3. iptables-allports — блокирует нарушителя в iptables по всем портам сервера, независимо от того, где было нарушение
  4. nftables — использует nftables (встроена во все новые ядра Linux, работает быстрее и эффективнее iptables)
  5. iptables-ipset — использует хэш-таблицы в оперативной памяти (ipset), iptables просто сверяется с этим списком
Есть еще кастомные экшены (например, mail или telegram) — можно комбинировать блокировку с отправкой уведомлений. Например, значение iptables-multiport[actname=telegram] может одновременно и банить, и отправлять сообщение в чат.

Если использовать banaction = ufw, то через пару недель sudo ufw status превратится в бесконечную простыню из сотен забаненных IP-адресов, в которой будет невозможно найти свои правила (например, открытый порт для FTP или веб-сервера).

Чтобы полностью изолировать Fail2Ban и скрыть его работу из интерфейса UFW — можно установить значение iptables-multiport. В этом случае Fail2Ban создаст свои скрытые «подтаблицы» в ядре Linux. Правила UFW останутся аккуратными и легко читаемыми.

8. Команды для управления

Fail2Ban управляется через встроенную утилиту fail2ban-client.

Посмотреть список активных защит (jail)

$ sudo fail2ban-client status
Status
|- Number of jail:      3
`- Jail list:   sshd, vsftpd, mysqld-auth

Посмотреть статус конкретной защиты и список забаненных IP-адресов (например, sshd)

$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     613
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 5
   |- Total banned:     99
   `- Banned IP list:   96.78.175.41 78.83.249.54 139.59.59.165 36.103.204.54 14.103.127.242

Разблокировать (разбанить) IP-адрес вручную

$ sudo fail2ban-client set sshd unbanip 101.101.101.101

Заблокировать (забанить) IP-адрес вручную

$ sudo fail2ban-client set sshd banip 202.202.202.202

9. Бан надолго (recidive jail)

Если какой-то IP-адрес получает несколько обычных банов за короткое время — можно заблокировать его на долгий срок (например, на неделю или месяц). Для этого в Fail2Ban есть специальный инструмент — recidive (рецидивист).

[recidive]
enabled   = true
logpath   = /var/log/fail2ban.log
filter    = recidive
banaction = iptables-multiport
# Окно времени, за которое считаем обычные баны (например, за последние 24 часа)
findtime  = 1d
# Сколько раз IP должен быть забанен обычными правилами, чтобы стать рецидивистом
maxretry  = 3
# Время продолжительного бана (1w = 1 неделя, 4w = 4 недели/месяц)
bantime   = 1w

Вместо сканирования логов Nginx или SSH — этот jail читает лог самого Fail2Ban. Если какой-то IP-адрес получает несколько обычных банов за короткое время — recidive распознает в нём злостного нарушителя и блокирует надолго.

10. Отдельный лог для Fail2Ban

По умолчанию Nginx записывает в access.log вообще всё — каждый запрос картинки, скрипта, стилей и страниц от обычных пользователей. Fail2Ban приходится читать каждую строчку этого огромного файла и прогонять её через тяжелые регулярные выражения. Это создает сильную нагрузку на процессор.

Если настроить Nginx так, чтобы он записывал в отдельный файл только подозрительные запросы (например, ошибки 401 или 404) — этот лог будет весить копейки. Fail2Ban будет читать всего пару сотен строк вместо миллионов, снизив нагрузку почти до нуля.

Когда Fail2Ban перегружен чтением гигабайтного access.log, в обработке логов возникает задержка (лаг). Бот может успеть сделать 1000 запросов в секунду до того, как Fail2Ban доберется до строки с его первой ошибкой и заблокирует его.

Можно настроить формат основного лога как угодно (для систем аналитики, стэка ELK, графиков) — не боясь, что Fail2Ban перестанет распознавать строки. А для Fail2Ban оставить стандартный, жестко заданный формат.

# В секцию http (или выше блока server) добавляем условие
map $status $is_bad_request {
    ~^[45]  1; # Если код ответа 401, 403, 404, 500 — присвоить 1
    default 0; # В остальных случаях (код 200, 301) — присвоить 0
}

server {
    listen 80;
    server_name mysite.com;

    # Основной лог для аналитики (пишется всё подряд, без исключений)
    access_log /var/log/nginx/access.log;

    # Лог специального назначения (пишутся только ошибки 4xx и 5xx)
    access_log /var/log/nginx/nginx-errors-for-fail2ban.log combined if=$is_bad_request;

    # ... остальная часть конфига ...
}

Аналогично можно настроить Apache

<VirtualHost *:80>
    ServerName mysite.com
    
    # 1. Основной лог (сюда пишется абсолютно всё для аналитики)
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    # 2. Если код ответа начинается на 4 или 5, задаем переменную bad_req
    # Для этого используем встроенное поле выражения %{REQUEST_STATUS}
    SetEnvIfExpr "%{REQUEST_STATUS} >= 400" bad_req

    # 3. Специальный лог для Fail2Ban (пишется только если сработал триггер bad_req)
    CustomLog ${APACHE_LOG_DIR}/apache-errors-for-fail2ban.log combined env=bad_req
</VirtualHost>

Поиск: Fail2Ban • Linux • Защита • Клиент • Конфигурация • Настройка • Сервер • Установка

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.