Системный журнал — практичная база знаний по VPS и Linux
Системный журнал Системный журнал
Fail2ban • SSH • Firewall • Linux • Безопасность

Fail2ban на Debian и Ubuntu: установка, настройка и проверка SSH-защиты

6 мин чтения Урок 4 из 6

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-адреса и при открытой консоли провайдера. Не проводите подбор пароля из единственной рабочей сети.

  1. Оставьте действующий административный сеанс открытым.
  2. Подключитесь с мобильного интернета или второго VPS.
  3. Несколько раз укажите заведомо неверного пользователя или пароль.
  4. Проверьте статус 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 по адресам там, где это возможно.

Итоговый чек-лист

  1. SSH работает по ключу, firewall разрешает правильный порт.
  2. Конфигурация хранится в jail.d/*.local.
  3. Для journald выбран backend = systemd.
  4. fail2ban-client -t проходит без ошибок.
  5. Jail sshd активен и видит события.
  6. Блокировка проверена с другого адреса и отображается в firewall.
  7. Есть инструкция аварийной разблокировки через консоль 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-адреса без необходимости.