Fail2ban ставят на сервер, когда тот получает белый IP, но зачастую дальше установки дело не идёт. Получается, что сервис запущен и джейл sshd включен, но конфиг был дефолтный, бан длится по десять минут, логи читаются не из того места, а половина открытых сервисов вообще находится вне поля зрения. Под катом разберу ошибки и покажу настройки.
Для тех, кто с fail2ban дела не имел, — это демон, который читает логи сервисов, находит в них строки про неудачные попытки входа и после нескольких повторов с одного адреса добавляет этот адрес в файрвол на определённое время. На Debian и Ubuntu ставится стандартно:
sudo apt update
sudo apt install fail2ban
sudo systemctl enable --now fail2banПосле установки первым делом нужно проверить, что сервис вообще стартовал:
sudo systemctl status fail2ban
sudo fail2ban-client statusЕсли вторая команда показывает только Number of jail: 0, Fail2ban запущен, но пока ничего не защищает. Дьявол, как обычно, в настройках...
Ошибка 1. Дефолтный конфиг считается рабочим
Откройте свежий jail.conf и посмотрите на цифры по умолчанию — maxretry 5, findtime 10 минут, bantime 10 минут. Переведу, если в течение десяти минут ботнет совершил пять попыток подбора, то его отстраняют от входа на десять минут, а потом можно возвращаться (обратите на это внимание, ведь и тут бывают ошибки с maxretry).
Сейчас ботнеты и не думают долбиться в одну дверь, они перебирают данные по одной-две попытки с адреса в час, и дефолтный findtime раз в десять минут такую атаку может не заметить, ведь каждая попытка выглядит как первая. А если бан всё же случился, через десять минут бот начинает, всё начинается заново, и такая история может длиться вечно.
На основе этого, первое, что нужно сделать на новой машине — это унести параметры в разумные пределы и включить прогрессивный бан, который растит срок с каждым новым нарушением одного и того же адреса:
# /etc/fail2ban/jail.local
[DEFAULT]
maxretry = 3
findtime = 1d
bantime = 1h
bantime.increment = true
bantime.factor = 24
bantime.maxtime = 5w
Три ошибки за сутки дают первый бан на час. Если тот же адрес снова добирается до порога после разблокировки, следующий бан вырастет до суток, затем до двух, четырёх и дальше по экспоненте, пока не упрётся в пять недель.
Ошибка 2. Правки в jail.conf
Классика жанра — настроили все прямо в /etc/fail2ban/jail.conf, а потом получили конфликт с новой версией файла при обновлении пакета. Тут правило простое, jail.conf — файл поставщика, ваши настройки должны жить в jail.local или в отдельных файлах, ведь они перекрывают дефолт:
sudo nano /etc/fail2ban/jail.d/sshd.localТуда же можно добавить:
[sshd]
enabled = true
С помощью второй команды проще понять, что вы поменяли сами, а что приехало из пакета. Проверить, что реально применилось, можно командой:
sudo fail2ban-client -tОна проверит конфигурацию и поймает ошибки до перезапуска. Если нужно посмотреть итоговую конфигурацию после объединения файлов, используйте:
sudo fail2ban-client --dump-prettyПосле этого перезапускаем:
sudo systemctl restart fail2banОшибка 3. Демон смотрит не в те логи
Самая коварная ошибка — Fail2ban умеет читать события из текстовых файлов и из журнала systemd, и выбор определяется параметром backend.
На Debian и Ubuntu логи SSH пишутся в /var/log/auth.log, на RHEL-подобных в /var/log/secure, а на системах, где rsyslog не стоит вовсе, обоих файлов просто не существует, sshd пишет только в journald.
Джейл со стандартным logpath в такой системе либо показывает ошибку при старте, либо, что хуже, не видит ни одной попытки входа. Диагностируется командой:
sudo fail2ban-client status sshdОна покажет состояние джейла и статистику срабатываний. А источник событий лучше проверить отдельно:
sudo fail2ban-client get sshd logpath
sudo fail2ban-client get sshd journalmatchЕсли в выводе пустой список файлов или строчки про journal, которых нет, починить это можно явным указанием источника:
[sshd]
enabled = true
backend = systemd
Сами события SSH тоже проверьте отдельно:
journalctl -u ssh -u sshd --since "1 hour ago"Обратная ситуация симметрична — если в системе есть и файлы, и журнал, а бэкенд выставлен в systemd глобально, то джейл для приложения, пишущего в свой собственный файл, журнала также не увидит. Каждому джейлу нужен свой источник, универсальный бэкенд — это миф, в который некоторые до сих пор верят.
Ошибка 4. Docker сводит баны на нет
Если сервисы крутятся в контейнерах, стандартный fail2ban может промахиваться. Тут есть две ситуации.
Первая проблема в логах — контейнер пишет в stdout/stderr, а дальше место хранения зависит от logging driver Docker. При journald сообщения можно читать через backend = systemd и фильтровать по полям вроде CONTAINER_NAME. При стандартном json-file в systemd journal этих сообщений не будет. Проверяется через:
docker info --format '{{.LoggingDriver}}'
docker inspect --format '{{.HostConfig.LogConfig.Type}}' ИМЯ_КОНТЕЙНЕРАВторая в пути пакета — при бэкенде через iptables опубликованные контейнерные порты идут через forwarding и Docker-цепочки, а fail2ban по умолчанию банит в INPUT. В этом случае можно использовать DOCKER-USER вместе с iptables-action, который умеет работать с указанной цепочкой.
Ошибка 5. Под защитой один SSH или его поменяли
Зачастую в свежем сервере из коробки включен только джейл sshd. Но у fail2ban есть готовые фильтры для Nginx, Postfix, Dovecot и других сервисов, которые включаются с помощью:
[nginx-limit-req]
enabled = true
[postfix]
enabled = true
mode = aggressive
Режим aggressive у postfix-фильтра ловит не только ошибки аутентификации, но и мусорные сессии. Если на сервере живёт WordPress, стоит поднять джейл под него. Про базовую гигиену вокруг я, кстати, уже писал, fail2ban там один из многих.
Если SSH переехал с 22-го порта на 2222, Fail2ban может видеть неудачные логины, но будет блокировать стандартный 22. В этом случае в джейл укажите реальный порт:
[sshd]
enabled = true
backend = systemd
port = 2222
И после перезапуска проверьте:
sudo fail2ban-client status sshdЕсли используете nftables, посмотрите и правила:
sudo nft list rulesetУ штатного nftables action Fail2ban используется отдельная таблица f2b-table — цепочка f2b-chain и sets с заблокированными адресами. Точные имена можно переопределять, поэтому лучше смотреть фактический ruleset.
Ошибка 6. Рецидивисты гуляют свободно
Иногда забаненные ранее боты возвращаются и заново пытаются попасть в систему. Fail2ban умеет с такими работать через джейл recidive, который читает собственный лог fail2ban:
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = %(banaction_allports)s
bantime = 1w
findtime = 1d
maxretry = 3
Но есть правила — во-первых, увеличивая bantime свыше суток, увеличьте и dbpurgeage в fail2ban.local, иначе база забудет старые нарушения. Во-вторых, держите loglevel ниже DEBUG, иначе recidive будет учитывать собственный шум.
Ошибка 7. Fail2ban вместо ключей
Если на SSH открыт вход по паролю, против целевой атаки с подбором fail2ban бессилен. От брутфорса лучше использовать комплексную защиту:
вход только по ключам,
PermitRootLogin no,
PasswordAuthentication no.
Также держите у себя прописанный ignoreip со своим статическим адресом, иначе однажды вы сами забанитесь:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.15
Текущий список исключений проверяйте через сам Fail2ban:
sudo fail2ban-client get sshd ignoreipОшибка 8. Бан не в тот файрвол
Fail2ban сам пакеты не фильтрует, он вызывает выбранный banaction, поэтому выясните, соответствует ли он файрволу. В актуальной конфигурации для Debian он по умолчанию использует nftables, но лучше проверить:
iptables -V
sudo nft list rulesetПоддержку IPv6 тоже смотрите отдельно. Штатные actions Fail2ban для iptables и nftables умеют работать и с IPv6, но иногда сервер закрыт по IPv4 и при этом остаётся доступным по IPv6 из-за конфига файрвола.
Ошибка 9. Regex проверяется на проде
С кастомными сервисами всё ещё веселее. Если вы нашли в интернете failregex = .*Failed.*<HOST>.* и хотите перезапустить Fail2ban, то так делать не стоит. Первое — regex может не совпасть с вашим форматом лога. Второе — если пользователь способен подставить произвольный текст туда, откуда regex затем вытащит <HOST>, атакующий может заставить Fail2ban заблокировать чужой IP. В связи с этим сначала проверьте:
sudo fail2ban-regex /var/log/myapp/auth.log /etc/fail2ban/filter.d/myapp.confЕсли работаете через systemd journal:
sudo fail2ban-regex systemd-journal sshdСмотрите не только на количество Matched, но и Missed. Иногда фильтр идеально ловит один вид ошибки и полностью пропускает другой.
Ошибка 10. Fail2ban банит proxy
В случае, если nginx или приложение стоит за HAProxy, Cloudflare, ingress-контроллером или другим reverse proxy, в журнале может оказаться именно IP-адрес прокси. Fail2ban увидит пять неудачных попыток и заблокирует его. После этого доступ к сайту потеряют ваши пользователи.
Здесь сначала нужно понять, какой адрес реально попадает в лог:
tail -f /var/log/nginx/access.logили:
journalctl -f -u nginxИ если сервис всё-таки работает за прокси, настройте корректное получение реального IP-адреса устройства и убедитесь, что доверяете XFF или PROXY protocol-у.
Как проверить, что защита живая
Сначала настройте:
# /etc/fail2ban/jail.d/sshd.local
[DEFAULT]
bantime = 30m
findtime = 10m
maxretry = 5
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 1d
ignoreip = 127.0.0.1/8 ::1
[sshd]
enabled = true
backend = systemd
port = 22
Если SSH работает на другом порту, меняем его. После этого:
sudo fail2ban-client -t
sudo systemctl restart fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshdЗатем фильтр проверяйте на реальном логе, без запуска демона:
sudo fail2ban-regex systemd-journal sshdУтилита покажет, сколько строк лога поймал фильтр, и если там ноль при очевидных неудачных логинах, то проблема в регэкспе или в logpath. Дальше смотрите статус джейлов и список текущих банов:
sudo fail2ban-client status
sudo fail2ban-client status sshdФинальный тест проводите с другой машины или через мобильную сеть — сделайте столько неудачных попыток входа, сколько задано в maxretry, в пределах findtime, и проверьте появление адреса в списке банов и в правилах файрвола. Разбанить себя после эксперимента можно без перезапуска:
sudo fail2ban-client set sshd unbanip ВАШ_IPИ последнее, смотрим:
sudo nft list rulesetЕсли что-то из этой цепочки не сработало, возвращайтесь к разделам про бэкенд и action. Когда защита работает, раз в месяц всё равно прогоняйте сервер на предмет того, что она могла пропустить. Об этом рассказал тут.
Пишите в комментариях, на какие ошибки в Fail2ban натыкались вы, и случался ли у вас самобан. Что делали в этих случаях?
© 2026 ООО «МТ ФИНАНС»

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