psj-notes
~/home ~/series ~/archive

05. Fail2ban: защита от брутфорса

15.07.2026 Серия: Настройка VDS сервера с VPN "fail2ban" "безопасность" "брутфорс"

UFW — это ещё не всё

UFW ограничивает количество попыток в минуту, но этого недостаточно. Злоумышленники используют ботнеты — тысячи IP-адресов, каждый из которых делает по 1–2 попытки в минуту. Rate limit UFW тут не поможет.

Fail2ban анализирует логи системы и временно банит IP-адреса, с которых происходит подозрительная активность: слишком много неудачных попыток входа, подбор паролей, сканирование портов.

Как это работает

[SSH Log] → [Fail2ban] → [Обнаружил 5 неудачных попыток] → [Добавил IP в ban-лист UFW]
                                         ↓
                              [Через 10 минут — разбан]

Fail2ban использует «тюрьмы» (jails) — наборы правил для разных сервисов. Каждая тюрьма:

  • Следит за своим лог-файлом
  • Ищет в нём заданные паттерны (неудачный логин, сканирование и т.д.)
  • При превышении порога — банит IP через iptables/UFW
  • Через заданное время снимает бан

Установка

sudo apt install -y fail2ban

После установки сервис запустится автоматически:

sudo systemctl status fail2ban

Настройка SSH jail

Файлы конфигурации:

Файл Назначение
/etc/fail2ban/jail.conf Основной конфиг (не редактировать!)
/etc/fail2ban/jail.local Ваши локальные переопределения
/etc/fail2ban/filter.d/ Готовые фильтры для разных сервисов

Главное правило: никогда не редактируйте jail.conf — он перезаписывается при обновлении пакета. Все изменения — в jail.local.

Создаём локальный конфиг:

sudo nano /etc/fail2ban/jail.local
[DEFAULT]
# Время бана: 10 минут (в секундах)
bantime = 600
# Время окна подсчёта попыток: 10 минут
findtime = 600
# Количество попыток до бана
maxretry = 5

# Уведомление на email (можно отключить)
destemail = root@localhost
action = %(action_mwl)s

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600

Что здесь происходит:

  • В секции [DEFAULT] заданы глобальные параметры для всех тюрем
  • В секции [sshd] переопределены параметры для SSH: достаточно 3 неудачных попыток — и бан на час
  • Фильтр sshd уже встроен в Fail2ban и ищет паттерны Failed password и Connection closed by authenticating user

Проверка фильтра

Перед перезапуском убедимся, что фильтр корректен:

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

Команда покажет, сколько строк в логе соответствуют паттерну и сколько Fail2ban посчитает как неудачные попытки.

Перезапускаем Fail2ban:

sudo systemctl restart fail2ban

Статус и мониторинг

Проверяем состояние всех тюрем:

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:	2
|  |- Total failed:	47
|  `- Journal matches:	_SYSTEMD_UNIT=sshd.service
`- Actions
   |- Currently banned:	3
   |- Total banned:	12
   `- Banned IP list:	185.220.101.42 91.121.87.5 23.129.64.210

Видно, что уже 12 IP-адресов были забанены, 3 из них всё ещё в бане.

Кастомный фильтр для админки

У Fail2ban есть фильтры для nginx, apache, wordpress и сотен других сервисов. Но для примера создадим свой — для защиты админ-страницы (например, /admin/login.php).

Создаём фильтр:

sudo nano /etc/fail2ban/filter.d/nginx-admin-login.conf
[Definition]
failregex = ^<HOST> -.*"(GET|POST).*/admin.*" (401|404)
ignoreregex =

Добавляем тюрьму в jail.local:

[nginx-admin-login]
enabled = true
port = http,https
filter = nginx-admin-login
logpath = /var/log/nginx/access.log
maxretry = 5
bantime = 86400

Теперь при 5 попытках доступа к /admin с одного IP — бан на сутки.

Работа с забаненными IP

Команды для управления:

# Разбанить IP вручную
sudo fail2ban-client set sshd unbanip 185.220.101.42

# Разбанить все IP
sudo fail2ban-client set sshd unbanip --all

# Забанить IP вручную
sudo fail2ban-client set sshd banip 1.2.3.4

# Посмотреть логи Fail2ban
sudo tail -f /var/log/fail2ban.log

Полезные параметры

Параметр Значение Описание
bantime 600 Время бана в секундах (10 минут)
findtime 600 Окно анализа лога (10 минут)
maxretry 3 Кол-во неудачных попыток до бана
ignoreip 127.0.0.1 ::1 77.88.55.66 IP, которые никогда не банятся
banaction ufw Каким инструментом банить
action %(action_mwl)s Отправлять email с whois-данными

ignoreip особенно полезен — добавьте свой домашний IP, чтобы случайно не заблокировать самого себя:

[DEFAULT]
ignoreip = 127.0.0.1 ::1 77.88.55.66

Проверка работы

Чтобы убедиться, что Fail2ban работает, можно смоделировать атаку:

# С другой машины (не сервер!)
ssh nonexistent@95.216.42.187
# Повторить 4 раза с неверным паролем

После 3-й неудачной попытки Fail2ban заблокирует ваш IP. Четвёртая попытка приведёт к Connection refused ещё до того, как SSH получит ваш пакет.

# На сервере проверяем
sudo fail2ban-client status sshd

В списке забаненных IP появится ваш тестовый адрес.

Итог

Fail2ban — обязательный компонент безопасности для любого публичного сервера:

  • Установлен и настроен SSH-джейл
  • Создан кастомный фильтр для админки
  • Бан на 1 час после 3 неудачных SSH-попыток
  • Логирование всех событий в /var/log/fail2ban.log

На этом базовая настройка безопасности завершена. В следующей части установим Nginx и настроим SSL-сертификат.

Комментарии

Комментарии пока не подключены.