Fail2Ban. Установка и настройка
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
ufw— добавляет правила блокировки напрямую в UFW (Uncomplicated Firewall) — стандартный и простой брандмауэр Ubuntuiptables-multiport— блокирует IP-адрес в классическомiptables, закрывая сразу несколько портов (например, 22, 80, 443)iptables-allports— блокирует нарушителя вiptablesпо всем портам сервера, независимо от того, где было нарушениеnftables— используетnftables(встроена во все новые ядра Linux, работает быстрее и эффективнееiptables)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>
- Dante. Установка и настройка прокси-сервера
- Установка WireGuard на Ubuntu 20.04 LTS. Часть вторая из двух
- Установка WireGuard на Ubuntu 20.04 LTS. Часть первая из двух
- Установка OpenVPN на Ubuntu 18.04 LTS. Часть 12 из 12
- Установка OpenVPN на Ubuntu 18.04 LTS. Часть 11 из 12
- Установка OpenVPN на Ubuntu 18.04 LTS. Часть 10 из 12
- Установка OpenVPN на Ubuntu 18.04 LTS. Часть 9 из 12
Поиск: Fail2Ban • Linux • Защита • Клиент • Конфигурация • Настройка • Сервер • Установка