InquirerOccidental Mindoro rations irrigation water amid El NiñoPunchVIDEO: How Kobe, LeBron, Giannis sought my guidance — Hakeem OlajuwonCNN TürkEski Trabzonsporlu Galatasaray'ın radarında: İşte masadaki teklifThe Jerusalem PostThe drone age for all: The real challenge is only beginning - opinionInquirer EntertainmentMaki renews ABS-CBN deal with Diamond Award, 2027 tour plansDaily MaverickSHARE WITH US: Tatjana Smith’s switch to the Netherlands: what do you think?ZDF heuteAktuelle Pressemitteilungen des ZDFObservador DesportoClima. Mau tempo veio para ficar?NHK 社会司法試験 ことしの合格者1595人 政府の目標を4年連続で超える20 Minuten«Mit zwölf musste ich schauen, dass mein Mami morgens aufsteht»Capital FMErratic Museveni son deactivates X handle after threats against Uganda VPRapplerLIVE UPDATES: Impeachment trial of Vice President Sara Duterte
The Daily Newsstand · Free, Always
Wednesday, November 11, 2026

Fail2ban: ошибки настройки, из-за которых защита не работает

Translate

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 натыкались вы, и случался ли у вас самобан. Что делали в этих случаях?

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.