Установка 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». Этот совет описывает реальные изменения: современные образы серверов и облачных систем поставляются без rsyslog, поэтому SSH ведет логи только в systemd 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 означает, что jail для SSH считывает данные из журнала, поэтому отсутствие 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, переопределив рабочие настройки по умолчанию. В разделе режимов отказа показано, как выглядит каждый из этих случаев.
Шаг 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. Не редактируйте этот файл. Любое apt upgrade пакета может заменить его, и ваши изменения исчезнут без предупреждения. Fail2ban считывает файлы в строго определенном порядке: сначала jail.conf, затем все файлы в jail.d/, после чего jail.local, при этом последнее значение имеет приоритет. Файл .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, настроенный под ваши порты и политику блокировки, а затем вставить его в файл:
Шаг 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: 10.0.0.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 10.0.0.66 - 2026-07-15 10:31:40
2026-07-15 10:31:44,118 fail2ban.actions [812]: NOTICE [sshd] Ban 10.0.0.66Чтобы проверить работу механизма целиком, не дожидаясь срабатывания, заблокируйте адрес документации вручную (никогда не блокируйте свой собственный адрес):
sudo fail2ban-client set sshd banip 10.0.0.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, содержащий 10.0.0.66, и цепочку (chain) f2b-chain, которая отклоняет любой трафик от источников из этого набора. Если fail2ban-client сообщает, что адрес заблокирован, но в nft list ничего не отображается, значит, действие блокировки не соответствует настройкам вашего межсетевого экрана. См. примечание о nftables/iptables в разделе типичных ошибок.
Шаг 6: Разблокировка своего IP-адреса и восстановление доступа при блокировке
Если вы ошибочно заблокировали свой IP-адрес, удалите его из списка:
sudo fail2ban-client set sshd unbanip 10.0.0.66В случае успеха команда возвращает 1. Чтобы снять все блокировки во всех jail:
sudo fail2ban-client unban --allНе рассчитывайте на то, что уже открытая SSH-сессия спасёт вас: блокировка через nftables отбрасывает все пакеты от заблокированного адреса на порт 22, включая уже установленные соединения, поэтому текущая сессия зависнет в момент применения правила. Если вы заблокировали себя и у вас нет записи ignoreip, вы потеряете доступ до истечения срока блокировки. Восстановите доступ через веб-консоль вашего провайдера (VNC или serial), которая не использует 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 = 5backend = 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 она возникает, только если кто-то переопределил настройки по умолчанию, выполнил установку pip без defaults-debian.conf, использует контейнер без journald или добавил лишний backend = auto в jail.local. При использовании файлового бэкенда без /var/log/auth.log джейл 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 сломан. Она означает, что он не запустился, так как один из джейлов не нашел лог-файл. Установка backend = systemd в [DEFAULT] (что уже сделано в пакете Ubuntu) исправляет обе ошибки сразу.
Джейл активен, но 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: разбаньте себя из сессии с другого, незабаненного адреса или через консоль провайдера (существующая сессия с забаненного адреса также зависнет). Затем добавьте свой адрес в 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Команда укажет файл и джейл, в котором возникла проблема, например Errors in jail 'sshd'. Skipping..., чтобы вы исправили источник ошибки, а не гадали.
FAQ
Работает ли Fail2ban из стандартного репозитория Ubuntu 24.04 для защиты от SSH-атак?
Да. Пакет содержит /etc/fail2ban/jail.d/defaults-debian.conf, который активирует jail 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 из устаревшего руководства, что нарушает чтение журнала в образах, где отсутствует auth.log. Либо вы находитесь внутри контейнера, где вообще нет журнала systemd. Проверьте Total failed в fail2ban-client status sshd: если счетчик не растет, в то время как journalctl -u ssh показывает реальные неудачные попытки входа, значит, jail считывает данные не из того источника.
Как разблокировать собственный 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: этот файл считывается последним, имеет приоритет над остальными, и обновления его не затрагивают. Оставьте jail.conf в режиме только для чтения в качестве справочного материала.
Заменяет ли Fail2ban аутентификацию по SSH-ключам?
Нет. Fail2ban ограничивает частоту повторных неудачных попыток с одного адреса; он неэффективен против медленного распределенного перебора, при котором каждый адрес остается ниже порога срабатывания. Аутентификация только по ключам (PasswordAuthentication no) делает подбор пароля невозможным в принципе, а Fail2ban в этом случае снижает объем мусора в логах и оперативно отсеивает сканеры. Используйте оба метода, а по возможности полностью закройте SSH от доступа из публичного Интернета.