Все системы работают Ваш IP: 216.73.217.36 info@cloudhosting.lv +371 66 66 29 69 Личный кабинет

← Все вопросы

Как защитить SSH, WordPress и почту с помощью fail2ban

fail2ban следит за журналами и временно блокирует IP-адреса, которые раз за разом проваливают аутентификацию. В этом руководстве разобрана практическая настройка на Linux-сервере: разумные значения по умолчанию для SSH, отдельный jail для флуда на форму входа WordPress, jail для Postfix и Dovecot, белый список собственных адресов и проверка банов. Руководство рассчитано на тех, кто сам администрирует VPS или выделенный сервер и заглядывает в логи время от времени, а не круглосуточно.

Как устроен jail: фильтр, действие, журнал

Всё в fail2ban строится вокруг jail, а jail состоит всего из трёх связанных частей:

  • Журнал: файл или журнал systemd, за которым наблюдает jail, например /var/log/auth.log.
  • Фильтр: набор регулярных выражений (failregex), которые определяют, какие строки журнала считать неудачной попыткой и какой IP её сделал.
  • Действие: что происходит, когда один IP набирает maxretry неудач за findtime, обычно это правило файрвола, отбрасывающее его трафик на время bantime.

Установка из стандартных репозиториев:

apt install fail2ban        # Debian, Ubuntu
dnf install fail2ban        # AlmaLinux, Rocky

Никогда не правьте /etc/fail2ban/jail.conf напрямую: обновления пакета его перезаписывают. Свои изменения кладите в /etc/fail2ban/jail.local или в отдельные файлы в /etc/fail2ban/jail.d/. Фильтры живут в /etc/fail2ban/filter.d/, по одному файлу на фильтр.

Разумные значения по умолчанию и jail для sshd

Вариант /etc/fail2ban/jail.local, который покрывает большинство одиночных серверов:

[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5
bantime.increment = true
bantime.maxtime   = 1w
ignoreip = 127.0.0.1/8 ::1 203.0.113.10

[sshd]
enabled  = true
maxretry = 3
bantime  = 2h

Параметр bantime.increment удваивает бан при каждом возвращении того же IP, вплоть до недели, и тихо убирает настойчивых ботов. В Debian 12 и других дистрибутивах без rsyslog файла auth.log нет, поэтому jail для sshd должен читать журнал systemd: добавьте backend = systemd в секцию [sshd]. Перезагрузите конфигурацию и убедитесь, что jail работает:

systemctl reload fail2ban
fail2ban-client status sshd

Jail для WordPress против флуда на wp-login.php

Боты долбят wp-login.php и xmlrpc.php POST-запросами. Журнал доступа веб-сервера не сообщает, был ли пароль верным, но это и не нужно: человек ошибается дважды, бот шлёт сотни POST. Создайте /etc/fail2ban/filter.d/wordpress-login.conf:

[Definition]
failregex = ^<HOST> .* "POST /wp-login\.php
            ^<HOST> .* "POST /xmlrpc\.php
ignoreregex =

Затем сам jail, в файле /etc/fail2ban/jail.d/wordpress.local:

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

Два предостережения. Во-первых, перед включением проверьте фильтр на реальном журнале и убедитесь, что совпадают только строки с POST:

fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress-login.conf

Во-вторых, если сайт стоит за обратным прокси или CDN, первым полем в журнале будет адрес прокси, и этот jail забанит ваш собственный прокси. Сначала настройте веб-сервер так, чтобы в журнал писался реальный IP клиента из X-Forwarded-For, и только потом включайте jail.

Почта: jail для postfix и dovecot

Для обоих fail2ban поставляется с готовыми фильтрами, свои регулярные выражения не нужны:

[postfix]
enabled = true
mode    = aggressive
logpath = /var/log/mail.log

[dovecot]
enabled = true
logpath = /var/log/mail.log

Jail postfix в режиме aggressive ловит ошибки SASL-аутентификации на порту 25 и портах submission, а также клиентов, ломающих протокол SMTP. Jail dovecot покрывает входы по IMAP и POP3. Почтовый перебор обычно медленный и распределённый, одна попытка в час с одного IP - обычное дело, поэтому для этих двух jail имеет смысл поднять findtime до 1h; бюджет попыток остаётся тем же, но под бан попадают и медленные сканеры.

Белый список и проверка банов

Классическая авария с fail2ban: заблокировать самого себя. Внесите каждый адрес, с которого администрируете сервер, в ignoreip в секции [DEFAULT], через пробел, нотация CIDR допустима. Добавьте IP офиса и дома, а также системы мониторинга, которые регулярно опрашивают сервисы.

Повседневная проверка:

fail2ban-client status                     # список jail
fail2ban-client status sshd                # счётчики и забаненные IP
fail2ban-client set sshd unbanip 198.51.100.7
fail2ban-client set sshd banip 203.0.113.99
grep Ban /var/log/fail2ban.log             # история банов

После любого изменения конфигурации выполните fail2ban-client reload и снова посмотрите статус jail: опечатка в фильтре молча даёт jail, который не совпадает ни с одной строкой.

Почему fail2ban не заменяет SSH только по ключам

fail2ban реактивен. Каждый атакующий IP всё равно получает maxretry минус одну бесплатную попытку за каждое окно findtime, а реальные атаки распределённые: ботнет из десяти тысяч адресов получает десятки тысяч попыток подбора пароля в день, не нарушая ни одного лимита. Если парольная аутентификация включена, а пароль слабый, fail2ban лишь замедляет атакующего.

Поэтому относитесь к этим уровням защиты как к взаимодополняющим. SSH только по ключам убирает сам угадываемый секрет; fail2ban после этого убирает шум, лишние затраты CPU на рукопожатия TLS и SSH и закрывает сервисы, где ключи невозможны, например почту и вход в WordPress. В /etc/ssh/sshd_config:

PasswordAuthentication no
KbdInteractiveAuthentication no

Вся описанная настройка занимает около получаса на свежем сервере и дальше не требует обслуживания. Если хотите сначала потренироваться на чистой машине, достаточно небольшого VPS: всё описанное спокойно работает в 1 GB RAM, а конфигурацию можно ломать и собирать заново, не трогая продакшен.

Хотите, чтобы это делали мы?
Сертификат на один домен. Один хост, один доверенный сертификат.
Подробнее

Готовы начать?

Запустите за минуты или обсудите с инженером, что подходит вашему проекту.