ServerAID
Найти гайд, команду, тег… ⌘ K
Безопасность

fail2ban на Ubuntu: защита SSH от перебора пароля

fail2ban читает /var/log/auth.log, ловит N неудачных попыток входа с одного IP за окно времени и временно банит этот IP через UFW или nftables. После UFW это второй слой защиты SSH: фаервол режет порты, fail2ban — назойливых ботов, которые подобрались к разрешённому 22/tcp. В статье — установка fail2ban на Ubuntu 24.04, дисциплина jail.local вместо jail.conf, готовый jail для sshd, диагностика fail2ban-client status и что делать, если забанили самого себя.

fail2ban на Ubuntu: защита SSH от перебора пароля

fail2ban читает /var/log/auth.log, ловит N неудачных попыток входа с одного IP за окно времени и временно банит этот IP через UFW или nftables. После UFW это второй слой защиты SSH: фаервол режет порты, fail2ban — назойливых ботов, которые подобрались к разрешённому 22/tcp. В статье — установка fail2ban на Ubuntu 24.04, дисциплина jail.local вместо jail.conf, готовый jail для sshd, диагностика fail2ban-client status и что делать, если забанили самого себя.

Зачем fail2ban, если уже есть UFW

UFW и fail2ban решают разные задачи. UFW — статический фильтр на уровне порта: «кто угодно с любого IP может стучаться в 22/tcp». fail2ban — динамический: «если конкретный IP уронил пароль 5 раз за 10 минут, заблокируй его на час».

Чем это лучше ufw limit ssh:

  • ufw limit режет всех, кто превысил порог соединений, — не различает успешные и неудачные попытки. fail2ban смотрит именно на запись Failed password или Invalid user в логах.
  • ufw limit забывает поведение быстро (30 сек). fail2ban помнит часами и сутками — bantime настраивается.
  • fail2ban работает не только для SSH: тот же подход применим к nginx-botsearch, postfix-sasl, recidive и десяткам других готовых jail-ов.

Связка «UFW + fail2ban + SSH-ключи без пароля» — стандартный стек для серверного Ubuntu. fail2ban не заменяет ключи: он защищает от шумового брутфорса, чтобы логи и journalctl не тонули в Failed password from 198.51.100.X.

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

В репозиториях Ubuntu 24.04 LTS лежит fail2ban 1.0.x — это нормальный релиз, ничего из ppa или pip ставить не нужно:

sudo apt update
sudo apt install fail2ban

После установки демон уже запущен и enabled через systemd, но дефолтных jail-ов не активных: с заводскими настройками fail2ban читает jail.conf, в котором все jail помечены enabled = false. Включаем минимум осознанно — через jail.local.

Проверим, что демон жив:

sudo systemctl status fail2ban
sudo fail2ban-client ping
# должен ответить: Server replied: pong

Базовая настройка: jail.local вместо jail.conf

Главное правило fail2ban — не редактировать /etc/fail2ban/jail.conf. Это файл из пакета, при apt upgrade он перезаписывается, и ваши правки потеряются. Все локальные изменения кладутся в jail.local или в отдельные файлы /etc/fail2ban/jail.d/*.local.

Минимальный /etc/fail2ban/jail.local:

[DEFAULT]
# IP, которые никогда не банятся (LAN, ваш bastion-хост, мониторинг)
ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16

# Окно наблюдения и порог
findtime  = 10m
maxretry  = 5

# Длительность бана
bantime   = 1h

# Бан-механизм. На 24.04 UFW под капотом nftables — fail2ban знает оба.
banaction = ufw

# Куда писать события (помимо /var/log/fail2ban.log)
backend   = systemd

[sshd]
enabled = true
port    = ssh
# Если SSH перенесён на 2222 — раскомментируйте и закомментируйте строку выше
# port  = 2222

Что значит каждая строка:

  • findtime + maxretry — «5 фейлов за 10 минут → бан». На свежем сервере без ключей это может оказаться слишком жёстко (вы сами успеете 5 раз промахнуться); поднимите до 10. Когда настроена авторизация по ключу — 5 нормально.
  • bantime — час разумный дефолт. Для адресов, которые попадаются повторно, есть отдельный jail recidive, но это уже надстройка.
  • banaction = ufw — fail2ban будет добавлять правила в UFW (ufw insert 1 deny from <ip>) вместо прямой работы с iptables/nftables. Так бан виден в sudo ufw status numbered и не конфликтует с вашими правилами фаервола.
  • backend = systemd — на 24.04 sshd пишет в systemd journal через journalctl, а не в plain-файл. С backend = systemd fail2ban читает journal напрямую — это надёжнее, чем парсить /var/log/auth.log (на минимальных образах его может не быть).
  • [sshd] — встроенный jail из пакета. Включается одной строчкой enabled = true.

После правки — рестарт:

sudo systemctl restart fail2ban
sudo fail2ban-client status
# должен показать: Jail list: sshd

Правила fail2ban: filter, action, jail

Внутри fail2ban три понятия:

  • filter — регулярка, которая ловит «плохое» событие в логе. Лежат в /etc/fail2ban/filter.d/*.conf. Для SSH — sshd.conf, ловит Failed password, Invalid user, Connection closed by authenticating user.
  • action — что делать, когда фильтр сработал N раз. /etc/fail2ban/action.d/*.conf. Для UFW — ufw.conf (actionban = ufw insert 1 deny from <ip>). Возможны и другие: отправить письмо, дёрнуть webhook, вызвать sshd-route-tarpit.
  • jail — связка фильтра, action и параметров (maxretry, bantime, port, logpath). Описывается в [имя]-секциях jail.conf/jail.local/jail.d/*.local.

Чтобы посмотреть, какие правила fail2ban доступны из коробки:

ls /etc/fail2ban/filter.d/   # фильтры
ls /etc/fail2ban/action.d/   # actions
sudo fail2ban-client get sshd logpath

Свои фильтры пишутся редко — для типовых сервисов (sshd, nginx, postfix, dovecot, vsftpd, recidive) уже всё готово. Своя дисциплина обычно сводится к включению нужных jail в jail.d/*.local и подкрутке maxretry/bantime.

Проверка: fail2ban-client status

Главная команда диагностики — fail2ban-client status. Без аргументов она показывает все активные jail, с именем jail — детали по конкретному:

sudo fail2ban-client status
# Status
# |- Number of jail:  1
# `- Jail list:       sshd

sudo fail2ban-client status sshd
# Status for the jail: sshd
# |- Filter
# |  |- Currently failed: 3
# |  |- Total failed:     127
# |  `- File list:        /var/log/auth.log
# `- Actions
#    |- Currently banned: 2
#    |- Total banned:     38
#    `- Banned IP list:   45.227.X.Y 185.220.X.Z

Total banned — сколько IP побывали в бане за всё время работы. На свежем сервере с открытым 22/tcp эта цифра растёт сама. Currently banned — кто сидит в бане прямо сейчас.

Полезные команды-однострочники:

# IP, которые сейчас под баном в sshd-jail
sudo fail2ban-client get sshd banip

# Снять бан с конкретного IP
sudo fail2ban-client unban 198.51.100.42

# Снять все баны
sudo fail2ban-client unban --all

# Перечитать конфиги без рестарта демона
sudo fail2ban-client reload

Когда забанили самого себя

Промахнулись паролем 5 раз в SSH с офиса — теперь не пускает. Варианты:

  1. Через консоль провайдера / VNC. Заходим напрямую и снимаем бан: sudo fail2ban-client unban <ваш_внешний_ip>. Внешний IP можно посмотреть на любом ifconfig.me.
  2. С другого IP. Если есть второй сервер, мобильный интернет, VPS — заходим оттуда, снимаем бан с офисного IP.
  3. Профилактика. Внести свой постоянный IP в ignoreip в [DEFAULT] секции jail.local. После reload fail2ban не будет отслеживать его вообще:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.10

Не забывайте: ignoreip — это «полное игнорирование», ваши собственные опечатки тоже не будут считаться. Это нормально для выделенных IP; для динамических лучше использовать ignorecommand или просто включить ключевую авторизацию и убрать пароль.

Тестирование фильтра без боевых банов

Перед заливкой кастомного фильтра в прод полезно прогнать его на реальных логах через fail2ban-regex — он покажет, какие строки matched и сколько было бы банов, не трогая реальный jail:

sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# или с journald (24.04+):
sudo fail2ban-regex \
  systemd-journal \
  /etc/fail2ban/filter.d/sshd.conf

Вывод: количество matched / not-matched, примеры строк, регулярки. Если matched = 0 — фильтр не ловит ваш формат логов; типовая причина на 24.04 — пытаетесь читать /var/log/auth.log, которого нет (logging-механизм через journal, файл не создаётся). Решение — backend = systemd в jail.local, как в примере выше.

Логи самого fail2ban

Демон пишет всё, что банит и разбанивает, в /var/log/fail2ban.log. Полезно во время отладки:

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

# Все баны за сегодня
sudo grep "$(date +%Y-%m-%d).*Ban" /var/log/fail2ban.log | wc -l

Если по какой-то причине /var/log/fail2ban.log пустой — смотрите journalctl: sudo journalctl -u fail2ban -n 200.

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

Какой backend ставить на Ubuntu 24.04 — auto или systemd?

systemd. На 24.04 sshd пишет в journald, а файл /var/log/auth.log создаётся только если установлен rsyslog. С backend = auto fail2ban в half-cases пытается читать несуществующий файл и тихо ничего не банит. backend = systemd забирает события напрямую из journal — надёжнее.

Что если SSH у меня на нестандартном порту?

В секции [sshd] поменяйте port = ssh на port = 2222 (или ваш номер). Фильтр — тот же, sshd пишет в журнал одинаково независимо от порта. Если параллельно правите Port в /etc/ssh/sshd_config — не забудьте sudo ufw allow 2222/tcp до рестарта sshd.

fail2ban или ufw limit ssh — что выбрать?

Дополняют, а не заменяют. ufw limit работает на уровне TCP-соединений и режет любые всплески (включая ваши собственные rsync-сессии). fail2ban работает по факту неудачной аутентификации — точнее, но требует, чтобы попытка дошла до sshd и попала в журнал. На проде ставьте оба: ufw limit рубит флуд соединений, fail2ban — реальный брутфорс пароля.

Можно ли защитить fail2ban-ом nginx или postgres?

Да. В /etc/fail2ban/filter.d/ уже есть фильтры nginx-http-auth, nginx-botsearch, postfix-sasl и другие. Включаются они теми же блоками [nginx-botsearch]\nenabled = true в jail.local. Для своих сервисов пишется кастомный фильтр — регулярка по строкам лога. Но это уже отдельная тема.

Куда смотреть логи самого fail2ban?

Файл /var/log/fail2ban.log (старая schoo) или journalctl -u fail2ban (рекомендуемый способ на 24.04). Там видны строки [sshd] Ban 198.51.100.X и [sshd] Unban 198.51.100.X — каждое действие фиксируется.

Что запомнить

  • Не править /etc/fail2ban/jail.conf — все изменения только в jail.local или /etc/fail2ban/jail.d/*.local.
  • На 24.04 ставить backend = systemd в [DEFAULT] — иначе fail2ban будет читать несуществующий auth.log.
  • banaction = ufw — баны видны в ufw status и не конфликтуют с вашими правилами фаервола.
  • Свой постоянный IP — в ignoreip, чтобы не забанить себя случайно во время отладки.
  • fail2ban-client status sshd — проверка после каждой правки. Total banned растёт сам, это нормально.
  • Перед прод-заливкой кастомного фильтра — прогнать через fail2ban-regex на реальных логах.

Похожие материалы

SSH-ключи на Ubuntu: вход без пароля, отключение паролей и смена порта
Безопасность

SSH-ключи на Ubuntu: вход без пароля, отключение паролей и смена порта

Заходить на сервер по SSH без пароля и при этом безопаснее, чем с паролем — главная польза от ключей. Разбираем `ssh-keygen ed25519`, `ssh-copy-id`, отключение парольного входа в `sshd_config`, смену SSH-порта, настройку `~/.ssh/config` на клиенте и генерацию ключей из Windows. Всё на Ubuntu 24.04 LTS.

Редакция
UFW на Ubuntu: настройка фаервола за пять команд
Безопасность

UFW на Ubuntu: настройка фаервола за пять команд

UFW — обёртка над nftables, которая закрывает всю входящую сеть и оставляет открытыми только те порты, которые вам реально нужны. Пять команд — и сервер не отвечает на сканеры. Разбираем настройку UFW в Ubuntu Server и Desktop 24.04 LTS: как включить, как разрешить порт, как лимитировать SSH и как проверить статус, не закрыв сами себе доступ.

Редакция
chmod — что это и зачем
Глоссарий

chmod — что это и зачем

chmod (change mode) — команда Linux для изменения прав доступа к файлу или каталогу. Управляет тем, кто может читать, писать и выполнять файл — владелец, группа, остальные. Понимание chmod нужно для SSH-ключей, веб-серверов и любой работы с правами доступа в Ubuntu.

Редакция
iptables — что это и зачем
Глоссарий

iptables — что это и зачем

iptables — классический брандмауэр Linux: набор правил, по которым ядро пропускает или блокирует сетевые пакеты. На современной Ubuntu заменён на nftables и обычно скрыт за UFW; саму команду `iptables` напрямую трогают редко, но понимать её стоит — на ней построена вся сетевая безопасность.

Редакция