Fail2ban: настройка защиты SSH от перебора паролей
Fail2ban читает логи сервисов, находит повторяющиеся неудачные попытки входа и временно блокирует IP-адрес атакующего через firewall. Для защиты SSH достаточно установить пакет, создать /etc/fail2ban/jail.local с секцией [sshd] (enabled = true, maxretry, findtime, bantime) и перезапустить службу; состояние проверяется командой fail2ban-client status sshd.
Fail2ban — это демон, который следит за логами сервисов, замечает повторяющиеся неудачные попытки входа и на время блокирует IP-адрес, с которого они идут. Для SSH это самая простая защита от перебора паролей: боты перестают долбиться в сервер после нескольких ошибок. Ниже — fail2ban настройка от установки до проверки банов и типичных ошибок.
Зачем нужен fail2ban, если есть SSH-ключи
Любой сервер с открытым портом 22 через несколько минут после запуска начинает получать попытки входа от ботов. Посмотрите сами:
$ sudo journalctl -u ssh --since "1 hour ago" | grep -c "Failed password"
412
Если вход по паролю отключён и используются только ключи, подобрать доступ практически невозможно. Но fail2ban всё равно полезен: он убирает шум из логов, снижает нагрузку от тысяч соединений и защищает от ошибок конфигурации, когда парольный вход случайно остался включённым. Это второй слой защиты, а не замена ключам.
Как работает fail2ban
Логика состоит из трёх частей:
- Фильтр (filter) — набор регулярных выражений, которые находят в логе строки о неудачной попытке и вытаскивают из них IP. Фильтры лежат в
/etc/fail2ban/filter.d/. - Действие (action) — что делать с нарушителем: добавить правило в iptables, nftables, ufw или firewalld. Действия лежат в
/etc/fail2ban/action.d/. - Тюрьма (jail) — связка фильтра, действия, источника логов и порогов. Например, jail
sshdследит за логом SSH.
Если за время findtime с одного IP набралось maxretry совпадений, адрес блокируется на bantime. По истечении срока бан снимается автоматически.
Установка fail2ban
На Debian и Ubuntu:
sudo apt update
sudo apt install fail2ban
На RHEL, Rocky, AlmaLinux пакет находится в репозитории EPEL:
sudo dnf install epel-release
sudo dnf install fail2ban
Включите автозапуск и проверьте состояние службы:
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban
В Debian и Ubuntu jail для SSH уже включён по умолчанию через /etc/fail2ban/jail.d/defaults-debian.conf. В RHEL-семействе после установки не включено ничего — тюрьмы нужно активировать вручную.
Где хранятся настройки: jail.conf и jail.local
Главный файл — /etc/fail2ban/jail.conf, но редактировать его нельзя: при обновлении пакета он перезапишется. Свои настройки кладут в /etc/fail2ban/jail.local или в отдельные файлы /etc/fail2ban/jail.d/*.local. Fail2ban читает файлы в таком порядке, и каждый следующий переопределяет предыдущий:
jail.confjail.d/*.confjail.localjail.d/*.local
Не копируйте весь jail.conf в jail.local — так вы заморозите старые значения по умолчанию. В jail.local пишут только то, что меняете.
Fail2ban настройка для SSH: минимальный jail.local
Создайте файл:
sudo nano /etc/fail2ban/jail.local
И добавьте в него:
[DEFAULT]
# Свои адреса, которые никогда не банить
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
bantime = 1h
findtime = 10m
maxretry = 5
# Откуда брать логи: systemd-журнал или файлы
backend = systemd
[sshd]
enabled = true
port = ssh
maxretry = 3
Перезапустите службу и убедитесь, что тюрьма поднялась:
$ sudo systemctl restart fail2ban
$ sudo fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd
Что означают параметры
| Параметр | Смысл | Пример |
|---|---|---|
enabled | включена ли тюрьма | true |
port | порт(ы), которые блокировать для нарушителя | ssh, 2222, ssh,2222 |
maxretry | сколько ошибок допускается до бана | 3 |
findtime | окно, в котором считаются ошибки | 10m |
bantime | длительность бана; -1 — навсегда | 1h, 1d |
ignoreip | адреса и подсети без бана | 10.0.0.0/8 |
backend | источник логов | systemd, auto |
logpath | путь к лог-файлу при файловом backend | /var/log/auth.log |
banaction | каким firewall банить | nftables-multiport, ufw |
Время можно писать с суффиксами: s, m, h, d, w. Числа без суффикса считаются секундами.
backend: systemd или файл
На современных Debian 12 и Ubuntu 24.04 файла /var/log/auth.log может не быть, если rsyslog не установлен: логи SSH живут только в журнале systemd. Тогда нужен backend = systemd, иначе fail2ban не запустится с ошибкой о том, что не найден лог-файл. Если же rsyslog есть, можно оставить файловый вариант:
[sshd]
enabled = true
backend = auto
logpath = /var/log/auth.log
На RHEL-системах аналогичный файл — /var/log/secure.
SSH на нестандартном порту
Если sshd слушает, например, порт 2222, укажите его в тюрьме — иначе fail2ban заблокирует порт 22, а атака продолжится на 2222:
[sshd]
enabled = true
port = 2222
Блокировать сразу все порты для нарушителя можно действием iptables-allports или nftables-allports через параметр banaction.
Выбор firewall: iptables, nftables, ufw, firewalld
По умолчанию в Debian используется banaction = nftables (в старых версиях — iptables), в RHEL — firewalld. Если на сервере настроен ufw, удобнее, чтобы баны были видны в нём:
[DEFAULT]
banaction = ufw
Для firewalld:
[DEFAULT]
banaction = firewallcmd-rich-rules
Проверить, что правила действительно появились, можно командой sudo nft list ruleset | grep f2b или sudo iptables -L -n | grep f2b: fail2ban создаёт цепочки с префиксом f2b-.
Как проверить работу: fail2ban-client status
Основной инструмент управления — fail2ban-client. Статус конкретной тюрьмы:
$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 147
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 4
|- Total banned: 38
`- Banned IP list: 45.148.10.12 92.118.39.7 185.224.128.40 218.92.0.112
Здесь видно, сколько ошибок сейчас в окне, сколько IP заблокировано и какие именно. Чтобы проверить защиту вживую, попробуйте несколько раз войти с неправильным паролем с другой машины (не с той, что в ignoreip) — после третьей попытки соединение перестанет устанавливаться.
Лог самого fail2ban находится в /var/log/fail2ban.log:
$ sudo tail -n 3 /var/log/fail2ban.log
2026-10-14 09:12:41,118 fail2ban.filter [812]: INFO [sshd] Found 218.92.0.112
2026-10-14 09:12:44,302 fail2ban.filter [812]: INFO [sshd] Found 218.92.0.112
2026-10-14 09:12:47,551 fail2ban.actions [812]: NOTICE [sshd] Ban 218.92.0.112
Как разбанить IP в fail2ban
Если вы заблокировали сами себя или коллегу, снимите бан с консоли сервера (через панель хостинга или другой IP):
sudo fail2ban-client set sshd unbanip 203.0.113.25
Снять все баны во всех тюрьмах:
sudo fail2ban-client unban --all
Заблокировать адрес вручную, не дожидаясь срабатывания фильтра:
sudo fail2ban-client set sshd banip 198.51.100.7
Чтобы история не повторилась, добавьте свои статические адреса или подсеть офиса в ignoreip.
Нарастающий бан для повторных нарушителей
Многие боты возвращаются сразу после разблокировки. С версии 0.11 в fail2ban есть увеличение срока бана для повторных нарушителей:
[DEFAULT]
bantime = 1h
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 4w
Каждый следующий бан того же IP будет длиннее предыдущего, но не больше четырёх недель. Альтернатива для старых версий — тюрьма recidive, которая читает лог самого fail2ban и надолго блокирует адреса, попавшиеся несколько раз:
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
bantime = 1w
findtime = 1d
maxretry = 5
Проверка фильтра: fail2ban-regex
Если тюрьма работает, но никого не банит, проверьте, что фильтр вообще находит строки в логе. Для файлового лога:
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
Для журнала systemd:
sudo fail2ban-regex systemd-journal sshd
В выводе смотрите на строку Lines: ... matched. Ноль совпадений означает, что фильтр не подходит к формату логов или указан не тот источник. Перед перезапуском полезно проверить синтаксис всей конфигурации:
sudo fail2ban-client -t
Применить изменения в конфигурации без полного перезапуска службы можно командой sudo fail2ban-client reload.
Свой фильтр для логов приложения
Fail2ban умеет защищать не только SSH, но и любое приложение, которое пишет неудачные входы в лог. Фильтр — это регулярное выражение failregex, в котором метка <HOST> ловит IP-адрес нарушителя:
# /etc/fail2ban/filter.d/myapp.conf
[Definition]
failregex = ^.*wrong password.*IP: "<HOST>".*$
# /etc/fail2ban/jail.local
[myapp]
enabled = true
filter = myapp
logpath = /var/log/myapp/app.log
maxretry = 3
bantime = 1h
Перед включением проверьте выражение на реальном логе: sudo fail2ban-regex /var/log/myapp/app.log /etc/fail2ban/filter.d/myapp.conf.
Типичные ошибки
- Служба не стартует: «Have not found any log file for sshd jail». Нет
/var/log/auth.log. Поставьтеbackend = systemdили установите rsyslog. - Баны есть в статусе, но атака продолжается. Указан не тот порт (SSH перенесён) или правила firewall перекрываются более ранним разрешающим правилом. Проверьте
portи выводnft list ruleset. - Изменения не применились. Правили
jail.conf, а вjail.localилиjail.d/*.localстоит другое значение. Посмотрите итоговое значение:sudo fail2ban-client get sshd maxretry. - Заблокировали себя. Разбаньте через консоль и добавьте IP в
ignoreip. - Fail2ban в Docker не видит атаки. Контейнерные порты публикуются через цепочку DOCKER, которая обходит INPUT. Для таких сервисов используют
chain = DOCKER-USERв действии.
Что ещё сделать для защиты SSH
Fail2ban хорошо работает в паре с базовыми мерами в /etc/ssh/sshd_config:
PasswordAuthentication no
PermitRootLogin no
MaxAuthTries 3
После правки проверьте конфиг командой sudo sshd -t и перезапустите службу. Не закрывайте текущую сессию, пока не убедитесь в новой, что вход по ключу работает. Дополнительно можно ограничить доступ к SSH на уровне firewall только нужными адресами.
Итог
Fail2ban настройка сводится к нескольким шагам: установить пакет, создать jail.local с секцией [sshd], выбрать правильный backend и порт, задать maxretry, findtime и bantime, добавить свои адреса в ignoreip и проверить работу через fail2ban-client status sshd. Вместе с входом только по ключам это надёжно закрывает SSH от перебора паролей. Защита сервера и fail2ban разбираются на практике в курсе по Linux.
Частые вопросы
Нужен ли fail2ban, если вход по паролю отключён?
Не обязателен, но полезен: он убирает тысячи мусорных попыток из логов, снижает нагрузку и подстрахует, если парольный вход случайно включат обратно.
Как посмотреть все заблокированные IP во всех тюрьмах?
Выполните sudo fail2ban-client banned — команда выводит списки заблокированных адресов по каждой тюрьме. Для одной тюрьмы используйте fail2ban-client status sshd.
Сохраняются ли баны после перезагрузки сервера?
Да, fail2ban хранит баны в своей базе SQLite (/var/lib/fail2ban/fail2ban.sqlite3) и восстанавливает действующие блокировки при старте, если параметр dbpurgeage не удалил их раньше.
Можно ли защитить fail2ban не только SSH?
Да, в комплекте есть фильтры для nginx, Apache, Postfix, Dovecot и других сервисов. Достаточно включить нужную тюрьму в jail.local, например [nginx-http-auth] с enabled = true.
Чем fail2ban отличается от ограничения в firewall?
Firewall статически разрешает или запрещает адреса, а fail2ban динамически банит тех, кто проявил себя в логах. Их часто комбинируют: whitelist в firewall и fail2ban для всего остального.
Эта тема подробно разобрана с практикой в курсе «Linux: с нуля до уверенного администрирования».
Перейти к курсу