Fail2ban на Debian и Ubuntu: установка, настройка и проверка SSH-защиты
Fail2ban анализирует журналы служб и временно блокирует адреса, которые многократно вызывают события, похожие на подбор пароля. Он полезен как дополнительный слой для SSH, но не заменяет ключи, firewall, обновления и ограничение доступа. Fail2ban также не является защитой от объёмных DDoS-атак.
Что нужно настроить до Fail2ban
- Рабочий SSH-вход по ключу.
- Проверенный firewall, разрешающий текущий SSH-порт.
- Точное время на сервере.
- Доступ к консоли VPS на случай ошибочной блокировки.
Проверьте имя службы и порт:
systemctl status ssh --no-pager
sudo sshd -T | grep '^port'
ss -lntp | grep ssh
Установите пакет
sudo apt update
sudo apt install fail2ban
sudo systemctl enable fail2ban
Не начинайте с редактирования /etc/fail2ban/jail.conf. Этот файл принадлежит пакету и может измениться при обновлении. Локальные настройки размещают в jail.local или отдельных файлах jail.d/*.local.
Создайте минимальную SSH-конфигурацию
sudoedit /etc/fail2ban/jail.d/sshd.local
Содержимое:
[sshd]
enabled = true
backend = systemd
port = ssh
maxretry = 5
findtime = 10m
bantime = 1h
backend = systemd важен для современных минимальных Debian и Ubuntu, где события SSH могут находиться только в journald, а файла /var/log/auth.log нет.
Если SSH слушает нестандартный порт, укажите номер:
port = 57483
Не рассчитывайте, что имя сервиса ssh автоматически подставит кастомный порт из конфигурации.
Что означают параметры
maxretry = 5— число совпадений до блокировки.findtime = 10m— окно, внутри которого считаются попытки.bantime = 1h— продолжительность блокировки.backend = systemd— чтение событий из журнала systemd.
Не ставьте чрезмерно долгий bantime на первом этапе. Ошибка в фильтре или общий корпоративный NAT могут заблокировать законных пользователей.
Добавьте доверенные адреса осторожно
Глобальные параметры можно вынести в отдельный файл:
sudoedit /etc/fail2ban/jail.d/00-local.local
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 1d
Не добавляйте динамический домашний IP или крупную подсеть в ignoreip без необходимости. Доверенный адрес никогда не будет заблокирован, даже если ключ с него скомпрометирован.
Проверьте конфигурацию до запуска
sudo fail2ban-client -t
Команда должна завершиться сообщением об успешной проверке. Затем:
sudo systemctl restart fail2ban
sudo systemctl status fail2ban --no-pager
sudo fail2ban-client ping
sudo fail2ban-client status
В списке jail должен присутствовать sshd.
Проверьте SSH jail
sudo fail2ban-client status sshd
Вы увидите текущие и суммарные неудачные попытки, число заблокированных адресов и используемый журнал. Для systemd backend путь к файлу может не отображаться — это нормально.
Посмотрите журнал службы:
sudo journalctl -u fail2ban --since today --no-pager
Убедитесь, что Fail2ban видит события SSH
Сначала изучите реальные записи:
sudo journalctl -u ssh --since '-30 minutes' --no-pager
sudo journalctl _SYSTEMD_UNIT=ssh.service --since '-30 minutes' --no-pager
На некоторых системах unit называется sshd.service. Узнайте его:
systemctl list-units --type=service | grep -E 'ssh|sshd'
Если jail активен, но счётчик не меняется, проверьте backend, имя службы и фильтр:
sudo fail2ban-client get sshd backend
sudo fail2ban-client get sshd journalmatch
sudo fail2ban-client get sshd failregex
Безопасный функциональный тест
Тестируйте только с другого внешнего IP-адреса и при открытой консоли провайдера. Не проводите подбор пароля из единственной рабочей сети.
- Оставьте действующий административный сеанс открытым.
- Подключитесь с мобильного интернета или второго VPS.
- Несколько раз укажите заведомо неверного пользователя или пароль.
- Проверьте статус jail на сервере.
sudo fail2ban-client status sshd
Разблокировать адрес:
sudo fail2ban-client set sshd unbanip 203.0.113.10
Заблокировать вручную для теста:
sudo fail2ban-client set sshd banip 203.0.113.10
Проверьте правила firewall
Fail2ban создаёт динамические правила через выбранное действие. На nftables:
sudo nft list ruleset | grep -i -A5 -B2 f2b
На системах с iptables-совместимым интерфейсом:
sudo iptables -S | grep -i f2b
Не смешивайте ручные цепочки и Fail2ban без понимания порядка правил. Разрешающее правило, расположенное раньше цепочки Fail2ban, может сделать блокировку неэффективной.
Изменение параметров без перезапуска SSH
После редактирования jail:
sudo fail2ban-client -t
sudo fail2ban-client reload
sudo fail2ban-client status sshd
Перезапускать SSH для изменений Fail2ban не требуется.
Добавление защиты Nginx: сначала убедитесь в качестве логов
Fail2ban умеет использовать фильтры Nginx, но это имеет смысл только при включённых и достоверных access/error logs. Если сайт находится за Cloudflare или другим reverse proxy, журнал должен содержать реальный адрес клиента, настроенный через доверенные прокси. Иначе Fail2ban может заблокировать адрес самого прокси.
Начинайте с одного jail SSH. Добавляйте веб-фильтры только после анализа ложных срабатываний.
Fail2ban и IPv6
Современные версии Fail2ban умеют работать с IPv6, но итог зависит от версии пакета и firewall backend. Проверьте фактические правила и протестируйте подключение по AAAA-адресу. Наличие работающего IPv4-бана не доказывает защиту IPv6.
Типовые неисправности
Служба не запускается
sudo fail2ban-client -t
sudo journalctl -u fail2ban -b --no-pager
Частая причина — jail ожидает /var/log/auth.log, которого нет. Используйте backend = systemd.
Адрес заблокирован, но подключение проходит
Проверьте реальный порт, IPv4/IPv6, порядок nftables-правил и выбранное действие. Убедитесь, что подключение действительно идёт с заблокированного адреса.
Ложные блокировки
Увеличьте maxretry, расширьте findtime или сократите bantime. Не отключайте защиту целиком, пока не изучили журнал совпадений.
Что Fail2ban не решает
- Не защищает украденный приватный SSH-ключ.
- Не исправляет уязвимости сервисов.
- Не заменяет закрытие ненужных портов.
- Не выдерживает объёмный сетевой DDoS на уровне канала.
- Не отменяет MFA, VPN или ограничение SSH по адресам там, где это возможно.
Итоговый чек-лист
- SSH работает по ключу, firewall разрешает правильный порт.
- Конфигурация хранится в
jail.d/*.local. - Для journald выбран
backend = systemd. fail2ban-client -tпроходит без ошибок.- Jail
sshdактивен и видит события. - Блокировка проверена с другого адреса и отображается в firewall.
- Есть инструкция аварийной разблокировки через консоль VPS.
Наблюдение и обслуживание
Раз в неделю проверяйте не только число блокировок, но и причины:
sudo fail2ban-client status sshd
sudo journalctl -u fail2ban --since '-7 days' --no-pager
sudo journalctl -u ssh --since '-24 hours' --no-pager \
| grep -E 'Failed|Invalid user' | tail -100
Рост банов может означать обычное сканирование интернета, но резкое изменение также требует проверки открытых портов, географии адресов и успешных входов. Fail2ban фиксирует неудачные события; успешную компрометацию ищут отдельно:
last -a
lastlog
sudo journalctl -u ssh --since '-7 days' --no-pager \
| grep -E 'Accepted|session opened'
После обновления Fail2ban повторно выполните тест конфигурации и убедитесь, что firewall-правила создаются тем же backend. Храните локальные настройки в системе контроля версий или в резервной копии, но не публикуйте реальные доверенные IP-адреса без необходимости.