Skip to content
EN
← Все статьи

fail2ban: установка, джейлы и защита от брутфорса SSH

Коротко. fail2ban читает логи сервисов, считает неудачные попытки входа с одного IP и на время добавляет этот адрес в правила firewall. Ставится через apt, настраивается в файле jail.local, а не в jail.conf. Ключевые параметры — maxretry, findtime, bantime и ignoreip. На современных Ubuntu логи sshd лежат в journald, поэтому джейлу нужен backend systemd, иначе он молча не сработает.

Что fail2ban делает и чего не делает

fail2ban — это демон, который следит за текстовыми логами (или журналом systemd), ищет в них строки, подходящие под регулярное выражение фильтра, и, если с одного IP-адреса за окно findtime набралось maxretry совпадений, вызывает действие: обычно добавление правила DROP или REJECT в firewall на время bantime. По истечении bantime правило снимается. Всё. Больше fail2ban ничего не делает.

Из этого следуют неприятные, но важные ограничения, которые стоит понимать до внедрения.

  • Это не firewall. fail2ban не закрывает порты и не задаёт политику доступа. Он лишь добавляет временные правила в уже существующий firewall (iptables, nftables, ufw, firewalld). Если у вас порт СУБД торчит наружу, fail2ban не поможет — нужен базовый фильтр пакетов и разбор открытых портов.
  • Это не защита от распределённого брутфорса. Современный ботнет делает 2–3 попытки с каждого из десятков тысяч адресов. Порог maxretry никогда не срабатывает, а если и срабатывает, вы забаните один адрес из пула. Против такого сценария работает не fail2ban, а отключение парольной аутентификации и лимиты на уровне приложения.
  • Это не WAF. fail2ban не разбирает тело запроса, не понимает SQL-инъекции и не проверяет payload. Он видит только то, что сервис сам записал в лог.
  • Это реактивная мера. Первые maxretry попыток всегда проходят. Если пароль подобрался с третьей попытки при maxretry = 5, бан бесполезен.
  • Он бессилен без логов. Если сервис не пишет неудачные входы или пишет их в формате, который не ловит фильтр, джейл будет висеть с нулевым счётчиком и создавать ложное ощущение защиты.

fail2ban — это способ убрать фоновый шум и снизить нагрузку на sshd, а не заменить нормальную аутентификацию. Ключи вместо паролей, PasswordAuthentication no и закрытые наружу служебные порты дают на порядок больше, чем любая настройка джейлов.

Монитор с размытым списком заблокированных IP-адресов в терминале на фоне серверной стойки

Установка fail2ban на Ubuntu и Debian

Пакет есть в основных репозиториях обоих дистрибутивов, отдельные репозитории подключать не нужно.

sudo apt update
sudo apt install fail2ban

# версия и статус демона
fail2ban-client version
systemctl status fail2ban

# что уже включено «из коробки»
sudo fail2ban-client status

В Debian и Ubuntu пакет кладёт файл /etc/fail2ban/jail.d/defaults-debian.conf, в котором джейл sshd уже включён. То есть после установки минимальная защита SSH обычно работает сразу — но проверить это надо руками, а не поверить на слово (см. раздел про backend ниже).

Если вы работаете с systemd-журналом, полезно доустановить биндинги Python к journald — без них backend systemd может не подняться:

sudo apt install python3-systemd
sudo systemctl restart fail2ban
sudo journalctl -u fail2ban -n 50 --no-pager

Раскладка файлов после установки:

  • /etc/fail2ban/fail2ban.conf — настройки самого демона: уровень логирования, сокет, база банов, dbpurgeage.
  • /etc/fail2ban/jail.conf — эталонное описание всех джейлов. Не трогать.
  • /etc/fail2ban/jail.d/*.conf — фрагменты конфигурации, подключаются после jail.conf.
  • /etc/fail2ban/filter.d/*.conf — фильтры, то есть регулярные выражения.
  • /etc/fail2ban/action.d/*.conf — действия: как именно банить (iptables, nftables, отправка письма, вызов API).
  • /var/lib/fail2ban/fail2ban.sqlite3 — база активных банов, благодаря ей баны переживают перезапуск демона.
  • /var/log/fail2ban.log — собственный лог; на него опирается джейл recidive.

jail.local, jail.d и ключевые параметры

Почему нельзя править jail.conf

jail.conf принадлежит пакету. При любом обновлении fail2ban через apt менеджер пакетов увидит изменённый conf-файл и либо перезапишет его, либо вывалит диалог о конфликте конфигурации, либо оставит .dpkg-dist рядом. В любом сценарии вы теряете либо свои правки, либо новые дефолты пакета.

fail2ban читает конфигурацию слоями: сначала jail.conf, затем jail.local, затем всё из jail.d/ в алфавитном порядке. Более поздний слой переопределяет более ранний, причём по отдельным параметрам, а не по секции целиком. Поэтому в jail.local достаточно перечислить только то, что вы меняете.

sudo tee /etc/fail2ban/jail.local > /dev/null <<'EOF'
[DEFAULT]
# ваши доверенные адреса: локалка, офис, VPN, чекеры мониторинга
ignoreip = 127.0.0.1/8 ::1 203.0.113.0/24
bantime  = 1h
findtime = 10m
maxretry = 5
# растущий бан: повторные нарушители сидят дольше
bantime.increment = true
bantime.factor    = 2
bantime.maxtime   = 7d
banaction = nftables-multiport

[sshd]
enabled  = true
mode     = aggressive
maxretry = 4
bantime  = 1d
EOF

sudo fail2ban-client -t          # проверка синтаксиса без применения
sudo systemctl reload fail2ban

Секция [DEFAULT] задаёт значения для всех джейлов; в секции конкретного джейла они переопределяются. Отдельные файлы в jail.d/ удобны, когда конфигурацию раскатывает Ansible или Puppet: один сервис — один файл, без конфликтов при слиянии.

Как подбирать bantime, findtime, maxretry и ignoreip

Смысл параметров простой: если с одного IP за findtime набралось maxretry совпадений фильтра, адрес блокируется на bantime.

  • maxretry. Для SSH с ключами — 3–4: легитимный пользователь с правильным ключом вообще не даёт неудачных попыток. Для веб-формы входа, где люди реально забывают пароль, — 5–10, иначе завалите поддержку заявками. Учитывайте, что один заход браузера может дать несколько строк в логе.
  • findtime. Окно наблюдения. Слишком маленькое (1–2 минуты) пропускает медленный перебор «по одной попытке в минуту». Разумный диапазон — 10–60 минут. Помните: чем шире окно, тем больше памяти и тем выше шанс поймать человека, который весь день путается в паролях.
  • bantime. Час — нормальный старт. Вечный бан (bantime = -1) выглядит соблазнительно, но раздувает таблицу правил firewall до десятков тысяч записей и рано или поздно ловит легитимный адрес, который вы забудете разбанить. Правильный ответ — не вечный бан, а bantime.increment: каждый следующий бан того же адреса длиннее предыдущего.
  • ignoreip. Список адресов и подсетей, которые не банятся никогда. Сюда обязательно попадают ваша рабочая сеть, VPN, адреса внутренних чекеров и балансировщиков. Формат — через пробел, поддерживаются CIDR и (в свежих версиях) DNS-имена. Параметр ignoreself = true, включённый по умолчанию, дополнительно защищает собственные адреса сервера.

Правило подбора: сначала ставьте мягкие пороги и смотрите статистику неделю. Агрессивный maxretry = 2 на публичном сайте — это не безопасность, а генератор инцидентов «клиент не может войти».

Backend: systemd, auto и подводный камень с journald

Параметр backend определяет, откуда джейл берёт события: из текстового файла или из журнала systemd.

  • auto — fail2ban сам выбирает механизм слежения за файлом: pyinotify, если доступен, иначе периодический опрос. Ключевое слово — файл. Значение auto не означает «сам найдёт логи где угодно».
  • polling — принудительный опрос файла по таймеру. Медленнее и прожорливее, но работает там, где inotify недоступен (некоторые контейнеры, сетевые ФС).
  • systemd — чтение journald напрямую через API. В этом режиме logpath игнорируется, а фильтрация записей задаётся директивой journalmatch.

Теперь самая частая причина «поставил fail2ban, а он не банит». Исторически sshd писал в /var/log/auth.log через rsyslog, и дефолтный джейл рассчитан именно на это. В свежих установках Ubuntu rsyslog может отсутствовать: журналирование целиком отдано systemd-journald, файл /var/log/auth.log не создаётся вовсе. Джейл при этом либо падает с ошибкой о недоступном логе, либо, если файл существует, но пуст (например, остался после апгрейда), тихо работает с нулевым счётчиком.

# есть ли вообще текстовый лог аутентификации
ls -l /var/log/auth.log 2>/dev/null || echo "нет auth.log — логи в journald"

# видит ли journald попытки входа
journalctl -u ssh.service --since "-1h" | grep -i "failed password" | tail

# что говорит сам fail2ban при старте
sudo journalctl -u fail2ban --since "-10m" --no-pager | grep -iE "error|warn|found"

Если логи в журнале — переводим джейл на backend systemd:

sudo tee /etc/fail2ban/jail.d/sshd-systemd.local > /dev/null <<'EOF'
[sshd]
enabled      = true
backend      = systemd
journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd
maxretry     = 4
bantime      = 1d
EOF

sudo fail2ban-client -t
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

Обратите внимание на имя юнита: в Debian и Ubuntu это ssh.service, во многих RPM-дистрибутивах — sshd.service. Ошибка в journalmatch не вызывает падения — джейл просто не увидит ни одной строки. Проверять надо через fail2ban-regex (см. ниже), а не по отсутствию ошибок в логе.

Признак молчащего джейла: в выводе fail2ban-client status sshd строка «Total failed» равна нулю, хотя journalctl показывает десятки «Failed password» за последний час. Это не «атаки прекратились», это неверный источник логов.

Джейл sshd и другие типовые джейлы

Джейл sshd — базовый и почти всегда достаточный минимум. У фильтра sshd есть режимы (mode), которые меняют набор регулярных выражений: normal ловит неудачные пароли и ошибки аутентификации, ddos — обрывы соединений и «пустые» коннекты без попытки логина, aggressive — оба набора сразу, включая обращения с невалидными пользователями и неподдерживаемыми методами. На публичном сервере aggressive обычно оправдан, на сервере с самописными скриптами, которые часто рвут SSH-сессии, — рискован.

ДжейлЧто ловитГде логmaxretrybantime
sshdподбор паролей, вход несуществующими пользователями, аномальные обрывы соединений/var/log/auth.log или journald (ssh.service)3–51 час — 1 сутки
nginx-http-authподбор логина и пароля в HTTP Basic Auth/var/log/nginx/error.log3–51–6 часов
nginx-botsearchперебор путей: админки, .env, бэкапы, чужие CMSerror.log, при желании access.log5–101 сутки
nginx-limit-reqсрабатывания limit_req, то есть превышение частоты запросов/var/log/nginx/error.log1010 минут — 1 час
postfix, postfix-saslподбор SMTP-пароля, попытки релея/var/log/mail.log или journald3–51 час — 1 сутки
recidiveадреса, которые уже банились несколькими джейлами/var/log/fail2ban.log3–51 неделя и больше

Джейл recidive заслуживает отдельного внимания: он читает не лог сервиса, а собственный лог fail2ban и банит тех, кто уже получал бан несколько раз за сутки. Это дешёвый способ отправить упорных ботов в долгую блокировку, не поднимая порог для обычных пользователей.

[recidive]
enabled  = true
logpath  = /var/log/fail2ban.log
banaction = %(banaction_allports)s
findtime = 1d
maxretry = 4
bantime  = 4w

Действие banaction_allports блокирует адрес не на конкретном порту, а целиком — для рецидивистов это разумно.

fail2ban и nginx: готовые джейлы и свой фильтр

С веб-сервером есть нюанс: большинство штатных nginx-фильтров читают error.log, потому что именно туда nginx пишет отказы Basic Auth и срабатывания limit_req. Коды ответа 401, 403 и 429 в чистом виде живут в access.log, и для них нужен свой фильтр.

[nginx-http-auth]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log
maxretry = 4
bantime  = 6h

[nginx-botsearch]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log
maxretry = 6
bantime  = 1d

[nginx-limit-req]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log
findtime = 5m
maxretry = 20
bantime  = 1h

Джейл nginx-limit-req имеет смысл только вместе с директивами limit_req_zone и limit_req в конфигурации nginx: без них в error.log нечего ловить. Связка «nginx ограничивает частоту, fail2ban банит самых упорных» — рабочая двухступенчатая схема, подробнее о её проектировании — в материале про стратегии ограничения частоты запросов и о методах защиты от DDoS.

Свой фильтр в filter.d и проверка через fail2ban-regex

Допустим, нужно банить адреса, которые массово получают 401 и 429 на API. Пишем фильтр под стандартный combined-формат access.log.

sudo tee /etc/fail2ban/filter.d/nginx-4xx-api.conf > /dev/null <<'EOF'
[Definition]
failregex = ^<HOST> \S+ \S+ \[[^]]+\] "(GET|POST|PUT|PATCH|DELETE) /api/[^"]*" (401|403|429)
ignoreregex =
datepattern = ^[^\[]*\[({DATE})
EOF

Ключевые правила написания фильтра:

  • <HOST> — обязательный маркер: именно из этой группы fail2ban достаёт IP-адрес. Ровно один на выражение.
  • Регулярка должна быть якорной (^) и максимально узкой. Широкое выражение вида .*401.* поймает строку, где 401 — это часть размера ответа или User-Agent, и забанит вам живого клиента.
  • ignoreregex — исключения, которые проверяются после failregex. Удобно, чтобы вывести из-под бана служебные пути вроде /api/health.
  • Все фильтры лежат в filter.d/, а джейл ссылается на них по имени файла без расширения.

Теперь главное — проверка. fail2ban-regex прогоняет фильтр по реальному логу и показывает, сколько строк совпало и как разобралась дата.

# фильтр против файла
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-4xx-api.conf

# штатный sshd-фильтр против системного журнала
fail2ban-regex systemd-journal /etc/fail2ban/filter.d/sshd.conf

# проверка одной строки (быстрая отладка регулярки)
fail2ban-regex '198.51.100.7 - - [12/Mar/2026:10:00:01 +0300] "POST /api/login HTTP/1.1" 401 12' \
  /etc/fail2ban/filter.d/nginx-4xx-api.conf

# подробный разбор: какие строки не подошли
fail2ban-regex --print-all-missed /var/log/nginx/access.log \
  /etc/fail2ban/filter.d/nginx-4xx-api.conf

В выводе смотрите на две цифры: Lines: ... matched и Missed lines. Ноль совпадений при заведомо наличии атак означает ошибку в регулярке или в формате даты. Отдельная частая проблема — datepattern: если fail2ban не распознал время строки, он либо считает событие устаревшим, либо игнорирует его. В выводе fail2ban-regex это видно по счётчику «ignored by ... date».

Подключаем фильтр джейлом:

[nginx-4xx-api]
enabled  = true
filter   = nginx-4xx-api
port     = http,https
logpath  = /var/log/nginx/access.log
findtime = 5m
maxretry = 25
bantime  = 2h

fail2ban-client: статус, разбан и как не забанить себя

Весь оперативный контроль — через fail2ban-client, который общается с демоном по unix-сокету.

# список активных джейлов
sudo fail2ban-client status

# детали одного джейла: счётчики и список забаненных
sudo fail2ban-client status sshd

# разбан конкретного адреса
sudo fail2ban-client set sshd unbanip 198.51.100.7

# разбан во всех джейлах сразу
sudo fail2ban-client unban 198.51.100.7
sudo fail2ban-client unban --all

# ручной бан (например, по данным из внешнего источника)
sudo fail2ban-client set sshd banip 198.51.100.7

# добавить адрес в исключения на лету, без перезапуска
sudo fail2ban-client set sshd addignoreip 203.0.113.10

# перечитать конфигурацию без потери активных банов
sudo fail2ban-client reload
sudo fail2ban-client reload sshd

Теперь про самую популярную аварию — самобан администратора. Сценарий типовой: вы правите джейл, ошибаетесь в фильтре, он начинает ловить обычные успешные подключения, и через минуту ваш IP оказывается в DROP. SSH-сессия при этом чаще всего сохраняется (established-соединение уже разрешено), но новая не установится.

  • Всегда добавляйте свой адрес в ignoreip до включения новых джейлов. Если адрес динамический — добавьте подсеть провайдера или адрес VPN.
  • Держите вторую открытую SSH-сессию на время экспериментов. Это бесплатная страховка: даже если новая аутентификация заблокирована, из старой сессии можно выполнить unban.
  • Имейте запасной канал доступа: консоль в панели хостинга, KVM или serial console. Если сервер живёт в облаке — например, в Selectel — веб-консоль работает в обход сети и firewall.
  • Проверяйте новый фильтр через fail2ban-regex до включения джейла, а не после.

Если доступ всё-таки потерян и есть только консоль, снимите бан вручную:

# посмотреть, где именно висит правило
sudo nft list ruleset | grep -A5 f2b
sudo iptables -S | grep f2b

# аварийно снять все баны
sudo fail2ban-client unban --all

# крайняя мера — остановить демон и почистить цепочки
sudo systemctl stop fail2ban

Подводные камни: firewall, reverse-proxy, logrotate и IPv6

iptables, nftables и ufw

fail2ban не заменяет firewall, а пишет в него. За способ записи отвечает banaction. Основные варианты: iptables-multiport (классика), nftables-multiport (для систем, где нативный firewall — nftables), ufw, firewallcmd-ipset. Смешивать наборы правил вслепую — плохая идея: если система работает на nftables, а fail2ban пишет через прослойку совместимости iptables-nft, правила попадут в отдельные таблицы, и порядок обработки может оказаться не тем, который вы ожидали.

С ufw есть отдельная тонкость: ufw создаёт собственные цепочки, и правила fail2ban должны вставляться перед разрешающими правилами ufw, иначе бан не сработает. Штатное действие ufw учитывает это, а вот самодельные комбинации — часто нет. После настройки всегда проверяйте фактическое состояние правил:

sudo nft list table inet f2b-table 2>/dev/null
sudo iptables -L -n --line-numbers | grep -i f2b
sudo ufw status numbered

Общие принципы укрепления фильтра пакетов и сервисов разобраны в материале про хардненинг веб-сервера.

Reverse-proxy и Cloudflare: банится не тот адрес

Если перед сервером стоит CDN, балансировщик или ещё один nginx, то в логах бэкенда виден IP прокси, а не клиента. fail2ban честно забанит его — и вы отрежете себе весь входящий трафик разом.

Лечится это не в fail2ban, а на веб-сервере: нужно, чтобы $remote_addr восстанавливался из заголовка, который проставляет прокси. Модуль realip подменяет адрес клиента и в access.log, и в записях error.log.

http {
    # подсети, которым доверяем проставление заголовка
    set_real_ip_from 192.0.2.0/24;      # ваш балансировщик
    # для CDN перечислите официальные диапазоны провайдера
    real_ip_header   X-Forwarded-For;
    real_ip_recursive on;
}

Доверять X-Forwarded-For можно только от явно перечисленных в set_real_ip_from подсетей. Если разрешить всем, любой клиент подставит чужой адрес в заголовок и заставит fail2ban забанить произвольный IP — от вашего собственного до адресов поисковых роботов. Механика заголовка и модель доверия разобраны отдельно: заголовок X-Forwarded-For.

Второй нюанс: даже с правильным realip бан на уровне firewall самого сервера бесполезен, если трафик всегда приходит от CDN. Блокировать нужно на стороне CDN — через её API. У fail2ban есть действия для внешних API, но их надёжность зависит от лимитов и доступности этого API.

Ротация логов и сброс счётчиков

logrotate переименовывает access.log в access.log.1 и создаёт пустой файл. fail2ban переоткрывает файл по смене inode и продолжает работу, но исторические строки уезжают в архив. Практические следствия:

  • Если fail2ban перезапускается (обновление пакета, reload сервиса, перезагрузка), он начинает читать актуальный файл. Сразу после ротации файл пустой, и контекст последних попыток теряется — атакующий получает свежие maxretry попыток.
  • Активные баны при этом не теряются: они лежат в sqlite-базе, а срок хранения записей задаёт dbpurgeage в fail2ban.conf.
  • Не ставьте findtime больше периода ротации: окно в сутки при ежедневной ротации будет наполовину «слепым».
  • Для journald проблема не стоит: журнал ротацию по файлам не использует, читается по курсору.

Ограничения при IPv6

Современные версии fail2ban умеют банить IPv6, но с оговорками. Во-первых, нужен banaction, поддерживающий обе версии протокола: nftables работает с inet-таблицей и покрывает оба стека, а классический iptables требует параллельных правил ip6tables. Во-вторых, у провайдера клиент обычно получает целую подсеть /64 и более — бан одного адреса ничего не даёт, атакующий возьмёт следующий из своего же префикса. Часть действий позволяет задать длину префикса для бана, но включать агрессивную блокировку по /64 на публичном сервисе стоит осознанно: под одним префиксом может сидеть много разных пользователей.

Проверить, что джейл вообще видит IPv6, проще всего по фактическому списку банов в fail2ban-client status и по правилам в nftables.

Как проверить настройку и защищённость сервера

Настройка fail2ban проверяется на двух уровнях: внутри сервера — командами выше, снаружи — тем, что реально видит атакующий.

  • Какие порты вообще торчат наружу. fail2ban защищает только те сервисы, которые вы включили в джейлы, а закрывать лишнее надо firewall'ом. Внешний скан покажет фактическую картину: проверка открытых портов. Если наружу смотрят СУБД, панель управления или отладочный порт — это важнее любых настроек джейлов.
  • Общий скоринг безопасности. Заголовки, TLS, утечки версий и типовые ошибки конфигурации собираются в один отчёт: проверка безопасности сайта. Полезно прогонять после каждого изменения конфигурации веб-сервера.
  • Всплеск отказов и падения. Слишком агрессивные джейлы проявляются как рост 4xx, обрывы и недоступность для части пользователей. Внешний мониторинг доступности с уведомлениями ловит и это, и обратную ситуацию — когда сервер лёг под перебором.
  • Реакция на срабатывания. Настройте действие с уведомлением (штатные action.d с отправкой письма) или заберите события из /var/log/fail2ban.log в вашу систему логов. Молчащий fail2ban — это fail2ban, о состоянии которого вы ничего не знаете.

Если по итогам проверки нашлись признаки уже состоявшейся компрометации, порядок действий описан отдельно: что делать, если сайт взломали.

Частые вопросы

Нужен ли fail2ban, если вход по SSH только по ключам?

Строгой необходимости нет: с PasswordAuthentication no подобрать пароль невозможно. Но джейл всё равно полезен — он убирает фоновый шум ботов, снижает число процессов sshd и объём логов. Ставьте мягкие пороги: задача не защита, а гигиена.

Почему fail2ban показывает Currently banned: 0, хотя атаки идут?

Три основные причины по частоте: джейл читает не тот источник (файл вместо journald), фильтр не совпадает с форматом строк, атакующие адреса попали в ignoreip. Диагностика — fail2ban-client status <jail> и fail2ban-regex по реальному логу.

Можно ли банить навсегда?

Технически да, bantime = -1. На практике лучше bantime.increment = true с ограничением bantime.maxtime: правила firewall не разрастаются бесконечно, а рецидивисты всё равно уходят в блокировку на недели. Вечные баны имеет смысл держать отдельным списком, который вы сознательно ревизуете.

Спасёт ли fail2ban от DDoS?

Нет. При объёмной атаке пакеты доходят до сервера и съедают канал и CPU ещё до того, как что-то попадёт в лог. fail2ban работает после записи в лог, то есть уже после обработки запроса. Против DDoS нужны фильтрация на уровне провайдера или CDN и лимиты на уровне nginx.

Как перенести настройки fail2ban на другой сервер?

Копируйте только свои файлы: jail.local, содержимое jail.d/, собственные фильтры из filter.d/ и действия из action.d/. Копировать jail.conf и базу банов не нужно: первый принадлежит пакету и придёт с ним, вторая специфична для конкретной машины.

Сильно ли fail2ban нагружает сервер?

На типовом VPS расход незаметен, пока джейлов немного и логи не гигантские. Проблемы появляются при широком findtime на очень активных access.log и при десятках тысяч правил в firewall. Лечится сужением окна, переходом на ipset/nftables-множества и джейлом recidive вместо вечных банов.

Чеклист внедрения

  • Пакет установлен, демон включён в автозапуск, fail2ban-client status отвечает.
  • Все правки — только в jail.local и jail.d/; jail.conf не тронут.
  • Свой адрес, VPN и адреса мониторинга внесены в ignoreip.
  • Проверено, откуда реально пишутся логи sshd; при journald выставлены backend = systemd и корректный journalmatch.
  • fail2ban-client status sshd показывает ненулевой счётчик Total failed на публичном сервере.
  • Каждый собственный фильтр прогнан через fail2ban-regex с проверкой совпадений и разбора даты.
  • banaction соответствует реально используемому firewall (iptables / nftables / ufw), правила видны в выводе firewall.
  • За reverse-proxy или CDN настроен realip с явным списком доверенных подсетей.
  • Включён bantime.increment или джейл recidive вместо вечных банов.
  • Есть запасной канал доступа к серверу на случай самобана.
  • Проведён внешний скан портов и проверка безопасности, настроен внешний мониторинг доступности.
  • Отключена парольная аутентификация SSH — главная мера, ради которой fail2ban становится второстепенным.

Проверьте ваш сайт прямо сейчас

Проверить безопасность сайта →
Другие статьи: Безопасность
Безопасность
Сайт или IP в чёрном списке: как проверить и выйти
21.07.2026 · 2 776 просм.
Безопасность
Как злоумышленники используют объекты групповой политики для вымогательства
28.09.2026 · 2 419 просм.
Безопасность
Как управлять доступом к вашим сайтам и сервисам: важные аспекты безопасности
19.09.2026 · 1 719 просм.
Безопасность
Как проверить сайт на вирусы: 4 уровня проверки и план лечения
01.04.2026 · 1 529 просм.