SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Установка Fail2ban на Ubuntu 24.04: защита от SSH-ботов

Узнайте, как настроить Fail2ban в Ubuntu 24.04 для блокировки брутфорс-атак. Разбираем проверку статуса через fail2ban-client и решение проблемы, когда счетчик Total failed равен 0.

Что на самом деле делает Fail2ban

Fail2ban — это демон для чтения логов. Он отслеживает сообщения об аутентификации SSH и, после нескольких неудачных попыток с одного адреса за короткий промежуток времени, выполняет команду межсетевого экрана, которая блокирует этот адрес на определенный срок. В этом заключается основная идея. Настройка занимает около тридцати строк в одном файле, а в Ubuntu 24.04 установка выполняется одной командой apt, которая обеспечивает защиту еще до внесения каких-либо правок.

Четко понимайте, чем является этот инструмент, а чем нет. Fail2ban не выполняет аутентификацию пользователей, не занимается шифрованием и не останавливает целенаправленную попытку входа, он лишь ограничивает повторяющиеся попытки с одного источника. Это фильтр «шума» и ограничитель частоты запросов (rate limiter), а не замок. Его задача — избавить вас от постоянного фонового сканирования 22 порта, которое расходует ресурсы процессора, пропускную способность сети и место в логах, а также замедлить атакующего, который вынужден действовать с одного адреса.

Что не заменяет Fail2ban

Fail2ban — это третий уровень защиты, а не первый. Если ваш сервер по-прежнему принимает пароли для SSH, ботнет, распределенный по тысячам адресов, может продолжать попытки подбора, так как каждый отдельный адрес остается ниже порога блокировки и никогда не вызывает срабатывание правила. Настоящая защита от этого — аутентификация только по ключам, которая делает подбор пароля невозможным независимо от количества попыток. Fail2ban поверх аутентификации по ключам выполняет две полезные задачи: очищает логи от шума при попытках перебора и заблаговременно удаляет сканеры, чтобы они перестали нагружать порт. Рассматривайте это как эшелонированную оборону. Fail2ban находится позади аутентификации по ключам и позади межсетевого экрана, но никогда не перед ними.

Предварительные требования и реалии Ubuntu 24.04

Вам потребуется VPS с установленной Ubuntu 24.04, права root или sudo, а также настроенный SSH, желательно с аутентификацией по ключам. Fail2ban потребляет мало ресурсов: несколько десятков мегабайт оперативной памяти, настройка лимитов не требуется.

Теперь о моменте, в котором ошибаются многие старые руководства. Годами стандартным советом было «установите Fail2ban, затем добавьте backend = systemd, так как Ubuntu перестала записывать /var/log/auth.log». Этот совет актуален только для некоторых образов. Стандартный серверный или облачный образ Ubuntu 24.04 по-прежнему устанавливает rsyslog, правила по умолчанию которого записывают auth,authpriv.* в /var/log/auth.log, поэтому на большинстве VPS ошибки SSH попадают как в этот файл, так и в systemd journal. Минимальные образы (минимальный облачный образ Ubuntu 24.04 поставляется без rsyslog) и большинство контейнеров ведут логи SSH только в journal, и там текстовый файл действительно отсутствует. В любом случае, в Ubuntu 24.04 пакет Fail2ban уже учитывает это. Пакет добавляет /etc/fail2ban/jail.d/defaults-debian.conf, и именно этот файл, а не настройки по умолчанию от разработчиков, фактически использует ваш сервер:

[DEFAULT]
banaction = nftables
banaction_allports = nftables[type=allports]
backend = systemd

[sshd]
enabled = true

Изучите его внимательно, так как он снимает два вопроса до того, как вы начнете что-либо менять. backend = systemd означает, что SSH-jail считывает данные из journal, поэтому не имеет значения, записывает ли ваш образ auth.log или нет. banaction = nftables означает, что блокировки применяются через nftables — межсетевой экран, который фактически использует Ubuntu 24.04, вместо устаревшего iptables. А [sshd] enabled = true означает, что jail включен с момента первой загрузки. Итог: стандартный apt install fail2ban в Ubuntu 24.04 блокирует SSH brute-force «из коробки». Большая часть вашей работы заключается в проверке этого факта, настройке политики и обеспечении того, чтобы вы не заблокировали доступ самому себе.

Старая ловушка с auth.log по-прежнему актуальна в трех ситуациях, и их стоит знать: вы установили Fail2ban с помощью pip вместо apt, поэтому defaults-debian.conf отсутствует; вы находитесь внутри непривилегированного контейнера без systemd journal для чтения; или вы следовали старому руководству и вставили backend = auto в свой собственный jail.local, переопределив работающие настройки по умолчанию. Первый и третий случаи нарушают блокировку SSH только на образе без rsyslog, например, на минимальном образе, так как там, где работает rsyslog, файловый бэкенд находит /var/log/auth.log и функционирует корректно. В разделе режимов отказа показано, как именно выглядит каждый из них.

Шаг 1: Установка и проверка работы блокировок

sudo apt update
sudo apt install -y fail2ban

В Ubuntu 24.04 поставляется Fail2ban 1.0.2, а пакет автоматически подтягивает python3-systemd в качестве обязательной зависимости, поэтому в бэкенде journal есть всё необходимое. Сервис включается и запускается самостоятельно:

sudo systemctl status fail2ban

Вам потребуется active (running). Затем проверьте jail, который уже выполняет свою задачу:

sudo fail2ban-client status sshd

На публичном VPS, который был доступен из сети хотя бы несколько минут, вы часто увидите счетчик неудачных попыток и заблокированные адреса: интернет непрерывно сканирует порт 22. Это подтверждает, что стандартная конфигурация работает. С этого момента вы занимаетесь её доработкой, а не созданием с нуля.

Шаг 2: Редактирование jail.local, а не jail.conf

Fail2ban хранит настройки по умолчанию в /etc/fail2ban/jail.conf. Не редактируйте этот файл. Обновление пакета может заменить его, как и предупреждает заголовок файла, и ваши правки будут потеряны. Fail2ban считывает файлы в строго определенном порядке: сначала jail.conf, затем jail.d/*.conf в алфавитном порядке, после этого jail.local, затем jail.d/*.local в алфавитном порядке; последнее значение имеет приоритет. Таким образом, jail.local переопределяет настройки из defaults-debian.conf, но любой файл *.local, который вы поместите в jail.d/, будет прочитан позже и, в свою очередь, переопределит их. Храните свои переопределения в одном месте, чтобы знать, какое значение является активным. Файл .local предназначен для вас, и обновления пакетов его не затрагивают. То же правило применяется к фильтрам, где файл *.local переопределяет поставляемый в комплекте filter.d/*.conf.

Поэтому создайте небольшой файл jail.local, в котором переопределите только те несколько настроек, которые вам нужны, а jail.conf и поставляемый в комплекте jail.d/defaults-debian.conf оставьте нетронутыми в качестве справочных материалов.

Шаг 3: Создание файла /etc/fail2ban/jail.local

sudo nano /etc/fail2ban/jail.local

Добавьте следующее содержимое, заменив адрес в строке ignoreip на ваш публичный IP-адрес:

[DEFAULT]
# Ubuntu 24.04 already sets these two in jail.d/defaults-debian.conf.
# Pinning them here documents the dependency and survives if that
# file is ever removed or changed by an upgrade.
backend   = systemd
banaction = nftables

# Ban for one hour ...
bantime  = 1h
# ... if an address fails ...
maxretry = 5
# ... 5 times within 10 minutes.
findtime = 10m

# Never ban these. PUT YOUR OWN IP HERE.
ignoreip = 127.0.0.1/8 ::1 10.0.0.24

# Longer bans for repeat offenders: 1h, 2h, 4h ... up to a week.
bantime.increment = true
bantime.maxtime   = 1w

[sshd]
enabled = true

Каждая строка здесь важна:

  • bantime, findtime и maxretry определяют политику блокировки. Стандартное значение bantime составляет всего десять минут; один час — более разумный минимум. Пять неудачных попыток входа с одного адреса в течение десяти минут приводят к бану. Обычные пользователи могут ошибиться в пароле один или два раза; пять ошибок за десять минут — признак работы скрипта.
  • ignoreip — это ваша страховка. Укажите здесь публичный адрес, с которого вы подключаетесь, чтобы Fail2ban не заблокировал вам доступ к собственному серверу. Если у вас дома динамический IP, лучше воспользоваться VPN-подходом, описанным в конце, а не пропускать эту строку.
  • bantime.increment = true делает каждый последующий бан длиннее предыдущего: один час, затем два, четыре и так далее до bantime.maxtime. Адреса, которые продолжают попытки подключения, блокируются на всё более длительные сроки.

Узнайте адрес для белого списка на машине, с которой вы подключаетесь по SSH, а не на самом сервере:

curl -s ifconfig.me

Вы можете сгенерировать jail.local, настроенный под ваши порты и политику блокировки, а затем вставить его в файл:

ToolFail2ban jail generator

Шаг 4: Перезапуск и проверка чтения журнала

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

-t сначала выполняет проверку конфигурации, поэтому опечатка в jail.local приведет к ошибке на этом этапе, а не к нерабочему состоянию службы. Статус исправно работающего jail выглядит так:

Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     14
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 1
   |- Total banned:     3
   `- Banned IP list:   203.0.113.66

Число, подтверждающее, что Fail2ban действительно считывает ваши попытки входа, — это Total failed. Если оно больше нуля или увеличивается, когда вы намеренно вводите неверные данные с другого компьютера, значит, журнал считывается и настройка завершена. Если значение остается 0, несмотря на количество неудачных попыток, и вы уверены, что не используете для теста адрес из ignoreip, перейдите к описанию режимов сбоя ниже.

Обратите внимание, что в строке Journal matches по-прежнему указан sshd.service. В Ubuntu юнит SSH на самом деле называется ssh.service, но поставляемый в комплекте фильтр также соответствует _COMM=sshd, а OpenSSH в версии 24.04 регистрирует сбои от процесса с именем sshd, поэтому сопоставление работает. Эта деталь важна только в том случае, если вы используете более новую версию OpenSSH (9.8 или новее, где рабочим процессом для каждого соединения является sshd-session); режимы сбоя охватывают и этот случай.

Шаг 5: Наблюдение за реальной блокировкой или принудительное тестирование

Реальные блокировки на любом публичном VPS происходят автоматически в течение нескольких минут. Чтобы увидеть их в реальном времени, отслеживайте лог:

sudo tail -f /var/log/fail2ban.log

Запись о блокировке выглядит так:

2026-07-15 10:31:40,502 fail2ban.filter  [812]: INFO    [sshd] Found 203.0.113.66 - 2026-07-15 10:31:40
2026-07-15 10:31:44,118 fail2ban.actions [812]: NOTICE  [sshd] Ban 203.0.113.66

Чтобы проверить работу всей системы без ожидания, заблокируйте адрес, предназначенный для документации, но ни в коем случае не свой собственный. 203.0.113.66 находится в TEST-NET-3 — блоке адресов, зарезервированном для документации, поэтому он не может быть реальным хостом или частным адресом в сети вашего провайдера:

sudo fail2ban-client set sshd banip 203.0.113.66

Команда выведет 1, а адрес появится в списке Banned IP list в fail2ban-client status sshd. Теперь убедитесь, что блокировка действительно существует в межсетевом экране. В Ubuntu 24.04 используется nftables, а не iptables:

sudo nft list table inet f2b-table

Вы увидите набор (set) с именем addr-set-sshd, содержащий 203.0.113.66, и цепочку (chain) f2b-chain, которая отклоняет любой трафик от источников из этого набора. Если fail2ban-client сообщает, что адрес заблокирован, но в nft list ничего не отображается, значит, действие блокировки не соответствует настройкам вашего межсетевого экрана. См. примечание о nftables/iptables в разделе типичных ошибок.

Шаг 6: Разблокировка своего IP-адреса и восстановление доступа при блокировке

Если вы ошибочно заблокировали IP-адрес, включая свой собственный, удалите его из списка:

sudo fail2ban-client set sshd unbanip 203.0.113.66

В случае успеха команда вернет 1. Чтобы снять все блокировки во всех jail:

sudo fail2ban-client unban --all

Не рассчитывайте на то, что уже открытая SSH-сессия спасет вас: блокировка в nftables отклоняет все пакеты от заблокированного адреса на порт 22, включая уже установленные соединения, поэтому текущая сессия зависнет в момент применения блокировки. Если вы заблокировали себя и у вас нет записи ignoreip, вы потеряете доступ до истечения срока блокировки. Восстановите доступ через веб-консоль вашего провайдера (VNC или последовательный порт), которая не использует SSH, и либо дождитесь окончания bantime, либо выполните команду разблокировки там.

Шаг 7: Обеспечение постоянства блокировок и их эскалация

Fail2ban хранит активные блокировки в небольшой базе данных SQLite по пути /var/lib/fail2ban/fail2ban.sqlite3, поэтому они сохраняются после перезапуска службы или перезагрузки системы; вы их не теряете. Строки bantime.increment, которые вы уже добавили, превращают каждого злостного нарушителя в проблему для него самого, примерно удваивая время блокировки от одного часа до одной недели.

Для реализации общесистемной политики «трех предупреждений» поверх этого, Fail2ban поставляет джейл recidive, который отслеживает свой собственный файл /var/log/fail2ban.log и назначает длительные блокировки любому адресу, который был заблокирован повторно во всех джейлах. Поскольку ваш [DEFAULT] теперь использует бэкенд systemd, привяжите этот джейл обратно к файлу журнала, который он предназначен считывать:

[recidive]
enabled  = true
backend  = auto
logpath  = /var/log/fail2ban.log
bantime  = 1w
findtime = 1d
maxretry = 5

backend = auto с явным указанием logpath заставляет recidive считывать обычный файл fail2ban.log, где фактически появляются строки Ban, которые он подсчитывает. Глобальная настройка systemd, которую вы установили, направила бы его в journal, где этих строк нет.

Шаг 8: Используйте только SSH-ключи, а лучше — VPN

Fail2ban эффективен только в сочетании с аутентификацией по ключам. В файле конфигурации в /etc/ssh/sshd_config.d/, например /etc/ssh/sshd_config.d/00-hardening.conf, установите:

PasswordAuthentication no
KbdInteractiveAuthentication no

Затем выполните sudo systemctl restart ssh. При отключенных паролях брутфорс становится невозможен; Fail2ban в этом случае нужен лишь для уменьшения объема логов и ранней блокировки сканеров. Еще надежнее — полностью скрыть SSH от публичного интернета: разместите SSH за собственным VPN WireGuard и настройте файрвол так, чтобы порт 22 отвечал только внутри туннеля. Никто не сможет подобрать пароль к порту, к которому нет доступа, и Fail2ban станет лишь дополнительным уровнем защиты, а не основным.

Fail2ban подходит не только для SSH. Любой сервис, который логирует неудачные попытки входа, можно защитить с помощью jail: почтовый сервер, сайт на nginx или собственный менеджер паролей Vaultwarden, веб-интерфейс которого не стоит оставлять открытым для атак методом перебора учетных данных. Как только веб-приложение оказывается за nginx с сертификатом Let's Encrypt, настройте фильтр Fail2ban на его access log точно так же, как jail для SSH настроен на journal.

Типичные сбои и сообщения об ошибках

«Have not found any log file for sshd jail», Fail2ban не запускается. Это старая проблема auth.log. В Ubuntu 24.04 она возникает, если отсутствует /var/log/auth.log (например, в минимальном образе или контейнере без rsyslog) и не настроено чтение журнала: при установке pip без defaults-debian.conf, в контейнере без journald или из-за ошибочной строки backend = auto в jail.local. Если используется файловый бэкенд без /var/log/auth.log, jail для sshd не находит лог, и демон завершает работу. fail2ban.log показывает:

ERROR   Failed during configuration: Have not found any log file for sshd jail

Поскольку эта ошибка критическая, сервис не запускается, и fail2ban-client status сообщает о вторичном симптоме:

ERROR  Failed to access socket path: /var/run/fail2ban/fail2ban.sock. Is fail2ban running?

Строка про «socket path» не означает, что Fail2ban сломан. Она означает, что он не запустился, так как один из jail не нашел лог-файл. Установка backend = systemd в [DEFAULT] (что уже сделано в пакете для Ubuntu) устраняет обе ошибки сразу.

Jail активен, но Total failed не увеличивается. Демон запущен, журнал считывается, но реальные попытки входа накапливаются в journalctl -u ssh, а счетчик остается на 0. Сначала исключите очевидное: вы тестируете с адреса, указанного в ignoreip, поэтому ваши попытки игнорируются согласно настройкам. Если дело не в этом, вы используете сборку OpenSSH, где рабочий процесс для каждого соединения — sshd-session (версия 9.8 и новее), чей идентификатор в журнале _COMM имеет вид sshd-session, а не sshd, поэтому стандартное правило не срабатывает. Расширьте условие в блоке [sshd]:

[sshd]
enabled      = true
backend      = systemd
journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd + _COMM=sshd-session

Перезапустите сервис, намеренно введите неверный пароль с адреса, которого нет в ignoreip, и убедитесь, что Total failed начал расти.

Вы заблокировали сами себя: Connection refused. Вы не добавили свой адрес в ignoreip, выполнили несколько неудачных попыток входа, и теперь:

ssh: connect to host 10.0.0.10 port 22: Connection refused

Отказ в соединении вместо тайм-аута — это результат работы действия reject в nftables. Исправьте это, как описано в шаге 6: разблокируйте адрес из сессии с другого IP или через консоль провайдера (существующая сессия с заблокированного адреса также зависнет). Затем добавьте свой адрес в ignoreip, чтобы это не повторилось.

Fail2ban сообщает о блокировке адреса, но соединение все еще проходит. Счетчик в status sshd растет, но адрес все равно подключается к 22 порту. Это несоответствие между действием блокировки и брандмауэром. В Ubuntu 24.04 это почти всегда означает, что вы переопределили рабочее действие banaction = nftables на banaction = iptables-multiport из старого руководства на системе, где нет слоя iptables. fail2ban.log показывает:

fail2ban.actions [812]: ERROR  Failed to execute ban jail 'sshd' action 'iptables-multiport'

Удалите это переопределение и используйте стандартное действие nftables. Если вы управляете брандмауэром через ufw и хотите, чтобы блокировки отображались там, установите banaction = ufw в [DEFAULT]. Перезапустите сервис и убедитесь, что правило появилось с помощью sudo nft list ruleset | grep f2b.

Fail2ban не запускается после редактирования jail.local. Опечатка, лишний заголовок или неверное значение времени приводят к отказу в запуске. Попросите Fail2ban проверить конфигурацию перед запуском:

sudo fail2ban-client -t

Утилита укажет файл и jail, в которых возникла проблема (например, Errors in jail 'sshd'. Skipping...), что позволит исправить причину, а не гадать.

FAQ

Работает ли Fail2ban «из коробки» в Ubuntu 24.04 для защиты от SSH-атак?

Да. Пакет поставляет /etc/fail2ban/jail.d/defaults-debian.conf, который активирует джейл sshd, устанавливает backend = systemd для чтения системного журнала systemd (независимо от того, записывает ли ваш образ /var/log/auth.log), и настраивает banaction = nftables для применения банов через штатный межсетевой экран Ubuntu. Обычная установка apt install fail2ban защищает SSH с момента первой загрузки. Проверьте статус командой sudo fail2ban-client status sshd и убедитесь, что значение Total failed отлично от нуля.

Почему Fail2ban не блокирует попытки входа на моем сервере?

Исключите три наиболее вероятные причины в указанном порядке. Возможно, вы тестируете подключение с адреса, указанного в ignoreip, который исключен из проверок по умолчанию. Возможно, вы переопределили рабочие настройки по умолчанию, скопировав backend = auto в jail.local из устаревшего руководства, что нарушает работу блокировки SSH в образах без rsyslog и, следовательно, без auth.log. Либо вы находитесь внутри контейнера, где отсутствует журнал systemd. Проверьте Total failed в fail2ban-client status sshd: если значение не растет, в то время как journalctl -u ssh фиксирует реальные ошибки, значит, джейл считывает данные не из того источника.

Как разблокировать собственный IP-адрес?

Выполните sudo fail2ban-client set sshd unbanip YOUR.IP.HERE, которая вернет 1 в случае успеха, или sudo fail2ban-client unban --all для снятия всех блокировок. Если вы потеряли доступ по SSH, используйте веб-консоль или VNC-консоль вашего провайдера для выполнения этой команды. Блокировка отклоняет все пакеты с вашего адреса на 22 порт, поэтому даже уже открытая сессия перестанет работать. После этого добавьте свой адрес в ignoreip, чтобы ситуация не повторилась.

В чем разница между jail.conf и jail.local?

Файл jail.conf содержит настройки Fail2ban по умолчанию, которые могут быть перезаписаны при обновлении пакета, поэтому любые изменения в нем небезопасны. Пакет Debian/Ubuntu накладывает свои настройки через jail.d/defaults-debian.conf. Ваши изменения следует вносить в jail.local: этот файл считывается после остальных, имеет приоритет и не затрагивается при обновлениях. Файлы с расширением *.local внутри jail.d/ считываются еще позже, поэтому не оставляйте там лишних конфигураций. Оставьте jail.conf в режиме «только для чтения» в качестве справочного материала.

Заменяет ли Fail2ban аутентификацию по SSH-ключам?

Нет. Fail2ban ограничивает частоту повторных неудачных попыток с одного адреса; он неэффективен против медленного распределенного перебора, где каждый адрес остается ниже порога срабатывания. Аутентификация только по ключам (PasswordAuthentication no) делает подбор пароля невозможным в принципе, а Fail2ban в этом случае снижает объем «шума» в логах и оперативно отсекает сканеры. Используйте оба метода, а по возможности полностью скройте SSH от публичного доступа в Интернет.