Fail2ban остаётся одним из самых практичных инструментов «быстрого реагирования» для Linux-сервера: он читает логи, распознаёт повторяющиеся ошибки авторизации и временно блокирует источник на уровне фаервола. В 2025 году подход не изменился, но детали важны: где брать логи при systemd-journald, как не забанить себя через прокси, как сделать блокировки устойчивыми и как быстро отладить, почему бан «не срабатывает».
Ниже — пошаговая инструкция под реальные кейсы: ssh brute force, basic auth в Nginx, настройка bantime, исключения через ignoreip и нормальная диагностика через fail2ban-regex.
Как работает Fail2ban и что важно в 2025
Fail2ban состоит из трёх частей:
jail — политика: какие логи читать, какой фильтр применять, сколько попыток считать атакой, на сколько банить (
bantime), за какое время считать попытки (findtime), сколько попыток допустимо (maxretry).filter — регулярные выражения, которые выдёргивают из строки лога IP и событие (например, “Failed password”).
action — что делать при срабатывании: добавить правило в nftables/iptables, отправить уведомление, записать в отдельный лог и т.д.
Типовой стек сейчас — Debian/Ubuntu с systemd, Nginx и nftables (или iptables-nft). Поэтому главные «грабли» — выбор backend (источника логов) и корректная работа action под ваш фаервол.
Быстрая проверка: Fail2ban вообще видит события?
Перед тюнингом убедитесь, что события попадают туда, откуда Fail2ban их читает:
Если SSH пишет в journald, а не в
/var/log/auth.log, jail должен использоватьbackend = systemd.Если access/error логи Nginx выключены или ведутся в нестандартный путь — фильтр будет «слепой».
Если перед Nginx стоит прокси/балансировщик и в логах не реальный клиентский IP, Fail2ban забанит прокси, а не атакующего.
Установка и базовые проверки (Debian/Ubuntu)
Установим пакет и проверим, что сервис запущен:
sudo apt update
sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban
Посмотреть активные jails:
sudo fail2ban-client status
Если fail2ban-client ругается на сокет, почти всегда причина одна из трёх: сервис не запущен, не хватает прав (нет sudo), или конфиг не парсится.
Где хранить настройки: jail.local и jail.d
Не правьте /etc/fail2ban/jail.conf напрямую: обновления могут перезаписать файл. Практика для продакшена:
общие дефолты — в
/etc/fail2ban/jail.d/00-defaults.local;сервисы — отдельными файлами:
/etc/fail2ban/jail.d/sshd.local,/etc/fail2ban/jail.d/nginx-httpauth.local;фильтры — в
/etc/fail2ban/filter.d/(с новым именем, чтобы не конфликтовать с пакетными).
Если вы поднимаете сервер с нуля и хотите сразу заложить адекватный базовый периметр (SSH, фаервол, минимальный hardening), пригодится отдельная заметка: безопасная настройка SSH и фаервола на VDS.
Защита SSH от brute force: jail для sshd
Для SSH важно не просто «банить всё подряд», а выбрать параметры так, чтобы не мешать себе и легитимным пользователям (особенно при нестабильном интернете или частых ошибках пароля).
Практичные параметры: findtime/maxretry/bantime
Создадим /etc/fail2ban/jail.d/sshd.local:
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
bantime.increment = true
bantime.factor = 1
bantime.maxtime = 24h
mode = normal
ignoreip = 127.0.0.1/8 ::1
Что здесь важно:
backend = systemd— актуально, когда SSH пишет в journald. Если у вас классический/var/log/auth.log, можно оставитьauto, но на systemd-системах явное указание обычно снимает вопросы «почему не ловит».maxretryиfindtime— мягкий, но полезный порог: перебор быстро упирается, а один случайный промах не банит пользователя.bantime.increment = true— хорошая «прививка» от упорных IP: повторные срабатывания увеличивают бан доbantime.maxtime.
Применяем изменения:
sudo systemctl restart fail2ban
Проверяем статус jail:
sudo fail2ban-client status sshd
ignoreip: как не забанить себя
ignoreip — белый список адресов, которые Fail2ban не банит даже при совпадении фильтра. Здесь важно избегать двух крайностей:
не добавлять слишком широкие сети (например, «весь офисный /16»), если вы не уверены в их чистоте;
не забывать про реальную точку входа: VPN-подсеть, IP бастиона, IP офисного NAT.
Практичный подход: держать в ignoreip только loopback и строго контролируемые адреса (VPN/bastion). Всё остальное — пусть банится, если действительно ломится.
Если Fail2ban ставите на боевой сервер, где важны ресурсы и предсказуемость (особенно при заметном шуме брутфорса), удобнее работать на VDS: проще контролировать фаервол, логи, доступы и поведение сетевого стека.

Nginx basic auth: jail под 401 и типовые ловушки
Кейс с basic auth чаще всего встречается в админках, приватных директориях, сервисах мониторинга и внутренних панелях. Брутфорс обычно простой: много ответов 401 на однотипные запросы.
Проверьте, что Nginx пишет то, что можно парсить
Для basic auth чаще удобнее access log: там стабильно видно HTTP-код (401). Но фильтр должен понимать ваш формат лога. В стандартном combined в строке обычно есть фрагмент 401 . Если формат кастомный или JSON — фильтр придётся подстроить.
Фильтр под access log: создаём свой
Создадим фильтр /etc/fail2ban/filter.d/nginx-http-auth-fastfox.conf:
[Definition]
failregex = ^<HOST> - .* \[.*\] ".*" 401 .*$
ignoreregex =
Это универсальная заготовка под типовой access log, где строка начинается с IP клиента. Если в начале строки адрес балансировщика, а реальный клиентский IP передаётся в заголовке — фильтр будет ловить «не того».
Jail для Nginx auth
Создадим /etc/fail2ban/jail.d/nginx-httpauth.local:
[nginx-http-auth-fastfox]
enabled = true
filter = nginx-http-auth-fastfox
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 10
findtime = 10m
bantime = 2h
ignoreip = 127.0.0.1/8 ::1
Почему параметры могут отличаться от SSH:
basic auth часто атакуют «мелкими сериями», поэтому
maxretryобычно выше, чтобы не банить живых пользователей, которые забыли пароль и пару раз обновили страницу.код 401 может появляться и в легитимных сценариях (например, первый запрос без заголовка Authorization). Поэтому не делайте
maxretryслишком маленьким.
Применяем:
sudo systemctl restart fail2ban
sudo fail2ban-client status nginx-http-auth-fastfox
Сайт за прокси/CDN: не баньте прокси вместо атакующего
Перед включением jails для веб-логов проверьте, что в access log в поле клиента действительно реальный IP, а не адрес балансировщика/Ingress. Иначе можно забанить прокси и устроить себе частичный даунтайм.
Технически это решается настройкой real IP в Nginx (доверенные адреса прокси и использование правильного заголовка) и корректным форматом логов. После этого фильтры с <HOST> начинают работать предсказуемо.
Тюнинг bantime: как выбрать время бана
Слишком короткий bantime почти бесполезен: атакующий переждёт и продолжит. Слишком длинный — риск заблокировать динамический IP, который завтра достанется обычному пользователю (актуально для публичных веб-сервисов; для SSH чаще терпимо, потому что доступ ограниченному кругу).
Рабочая схема на практике:
SSH:
bantime1–6 часов плюсbantime.increment.Админки/basic auth: 1–2 часа, но аккуратнее с
maxretry.Если видите «упорных» — включайте инкремент и задавайте
bantime.maxtime24–168 часов по критичности.
Ещё одна полезная настройка, когда в логах много «шума» от сканеров:
[DEFAULT]
bantime.increment = true
bantime.rndtime = 10m
bantime.rndtime добавляет случайность к длительности, усложняя атакующему подбор «окна».
Fail2ban debug: почему не банит (или банит лишнее)
Если что-то не работает, не крутите параметры наугад. Быстрее — пройти чек-лист: сервис, jail, лог, фильтр, извлечение IP, action (фаервол).
1) Логи самого Fail2ban
На systemd-системах чаще всего достаточно journalctl:
sudo journalctl -u fail2ban -n 200 --no-pager
Ошибки regex, отсутствующий logpath, проблемы с правами на чтение логов — обычно видны сразу.
2) fail2ban-client и сухая проверка regex
Статус и текущие баны:
sudo fail2ban-client status
sudo fail2ban-client status sshd
Проверить, совпадает ли фильтр с логом, удобнее всего через fail2ban-regex:
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-http-auth-fastfox.conf
Это база «debug»: вы увидите, сколько строк матчится, какие строки не матчатся, и не «теряется» ли IP при парсинге.
3) Убедиться, что backend читает нужный источник
Если jail настроен на systemd backend, а события лежат в файле (или наоборот) — матчей не будет. Для SSH на systemd-системах часто спасает явное backend = systemd. Для Nginx обычно проще читать файлы.
4) Проверить, что правила реально попали в фаервол
Fail2ban может «думать», что забанил, но правило не применилось (например, action не подходит под вашу систему фильтрации).
Посмотреть, что Fail2ban считает забаненным:
sudo fail2ban-client get sshd banip
Дальше проверяйте фаервол штатными средствами вашей системы (nftables или iptables-nft). Если банов «внутри Fail2ban» много, а на уровне фаервола пусто — проблема в action.
Практика эксплуатации: что сделать сразу
Разделяйте jails по риску
Не пытайтесь одной настройкой покрыть всё. SSH и веб-авторизация имеют разный профиль ошибок и разный риск ложных срабатываний. Лучше несколько jails с понятными именами и отдельными параметрами.
Whitelist должен быть минимальным
Чем шире ignoreip, тем легче атакующему спрятаться в «доверенной» сети (или случайно оказаться в ней через NAT/прокси). Белый список должен быть коротким и осознанным.
Документируйте нестандартные logpath и форматы
Fail2ban ломается не потому, что он «плохой», а потому что через полгода кто-то поменял формат access log, включил JSON-логи или перенёс логи в другой путь. Оставляйте комментарии в jail-файлах: откуда берутся логи и почему regex именно такой.

Мини-чеклист: когда Fail2ban включать, а когда лучше притормозить
Стоит включать: публичный SSH, админки с basic auth, сервисы с простыми логируемыми ошибками входа, когда нужна быстрая защита от массового перебора.
Осторожно: приложения за CDN/Ingress без реального IP в логах; нестандартные SSO-потоки, где 401/403 — часть нормального сценария; сервисы, где пароль вводят редко, но критична доступность для легитимных пользователей.
Итог
Fail2ban в 2025 году — всё ещё must-have на многих серверах, но он требует минимальной дисциплины: правильно выбрать источник логов, убедиться, что в логах есть реальный IP, аккуратно задать bantime, не переборщить с ignoreip и уметь быстро отлаживаться через логи и fail2ban-regex. Потратьте 30–60 минут на аккуратную настройку — и получите заметно более спокойные логи и меньше шума от перебора паролей.
Если вы защищаете публичный сайт и параллельно включаете строгие политики типа HSTS и принудительный HTTPS, проверьте цепочку миграции и сертификаты: пригодится материал про переезд домена, 301, HSTS и SSL.


