Каждый публичный VPS ежедневно подвергается тысячам попыток подбора паролей SSH. Fail2ban анализирует логи и автоматически блокирует атакующие IP-адреса.
Установка Fail2ban
sudo apt update
sudo apt install -y fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Настройка защиты SSH
Создайте локальный конфиг (не редактируйте jail.conf — он перезатирается при обновлениях):
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
ignoreip = 127.0.0.1/8 ВАШ_ДОМАШНИЙ_IP
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
sudo systemctl restart fail2ban
Что означает каждый параметр
| Параметр | Значение в примере | Смысл |
|---|---|---|
| bantime | 3600 (для sshd — 86400) | На сколько секунд блокируется IP после превышения лимита |
| findtime | 600 | Окно времени в секундах, за которое считаются неудачные попытки |
| maxretry | 5 (для sshd — 3) | Сколько неудачных попыток допустимо в пределах findtime |
| ignoreip | 127.0.0.1/8 и ваш IP | Адреса, которые никогда не блокируются |
Секция [sshd] переопределяет maxretry и bantime из [DEFAULT] — для SSH их обычно делают строже (меньше попыток, дольше бан), чем общее значение по умолчанию для остальных сервисов.
Типичные ошибки настройки
Неверный logpath для дистрибутива
Путь /var/log/auth.log верен для Debian и Ubuntu. На CentOS, AlmaLinux и других RHEL-подобных дистрибутивах журнал аутентификации лежит в /var/log/secure — с неверным путём Fail2ban запускается без ошибки, но jail никогда не сработает, потому что просто не находит файл для чтения.
# Проверка, что jail реально читает файл логов:
sudo fail2ban-client status sshd
# Строка "File list" должна содержать реальный путь к логу с данными,
# а не путь к пустому или несуществующему файлу
ignoreip без собственного IP
Если не добавить свой рабочий IP в ignoreip, а порог maxretry стоит низким, случайные опечатки в пароле при обычном входе могут забанить вас самих на срок bantime. Особенно опасно при динамическом IP дома — стоит проверять текущий адрес после каждого переподключения провайдера.
На системах, где журнал аутентификации ведётся только через systemd journal без файла /var/log/auth.log или /var/log/secure (некоторые минимальные образы и контейнерные окружения), обычный logpath не сработает вовсе. Для этого случая в jail есть отдельный параметр backend, который читает записи напрямую из journal, а не из файла на диске:
[sshd]
enabled = true
backend = systemd
maxretry = 3
Основные команды
# Статус всех тюрем
sudo fail2ban-client status
# Статус SSH-тюрьмы
sudo fail2ban-client status sshd
# Разблокировать IP вручную
sudo fail2ban-client set sshd unbanip 203.0.113.42
# Посмотреть заблокированные IP
sudo iptables -L f2b-sshd -n --line-numbers
Защита Nginx от DDoS и сканирования
# Добавить в jail.local:
[nginx-http-auth]
enabled = true
logpath = /var/log/nginx/error.log
[nginx-botsearch]
enabled = true
logpath = /var/log/nginx/access.log
maxretry = 2
/etc/ssh/sshd_config — это снизит количество атак на 95%.sudo ufw allow 2222/tcpКогда Fail2ban не спасёт
- Распределённый перебор с тысяч разных IP по одной-две попытки с каждого — порог
maxretryдля отдельного адреса не срабатывает, потому что ни один IP его не превышает. - Атака через уязвимость в самом приложении, а не подбор пароля — Fail2ban реагирует на паттерны в логах неудачной аутентификации, а не на произвольные HTTP-запросы без совпадающей сигнатуры фильтра.
- Вход по скомпрометированному, но действительному паролю или ключу с первой попытки — здесь нечего блокировать по признаку повторных неудач, нужны двухфакторная аутентификация и мониторинг подозрительных входов.
Проверка, что защита работает
- Выполните
sudo fail2ban-client status sshd— в выводе должен быть корректный путь к логу и растущий счётчикCurrently failedпосле неудачных попыток входа. - С другого IP (не из
ignoreip) намеренно введите неверный пароль SSH большеmaxretryраз подряд — следующая попытка должна быть отклонена файрволом, а не формой входа. - Проверьте бан в списке:
sudo fail2ban-client status sshdдолжен показать этот IP вBanned IP list. - Разбаньте тестовый IP командой
fail2ban-client set sshd unbanipи убедитесь, что подключение снова проходит — это подтверждает, что бан снимается штатно, а не только руками через iptables.
Настройка файрвола, на котором Fail2ban расставляет правила блокировки, разобрана в статье UFW для Ubuntu и Debian, а вход по ключам вместо пароля вовсе убирает необходимость подбора — хардненинг SSH на сервере.
Установка
sudo apt update
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
Создание конфига jail.local
Никогда не редактируйте jail.conf — он перезаписывается при обновлении. Создайте jail.local:
># /etc/fail2ban/jail.local
[DEFAULT]
# Время бана в секундах (3600 = 1 час, -1 = навсегда)
bantime = 3600
# Время поиска попыток (10 минут)
findtime = 600
# Максимум попыток до бана
maxretry = 5
# Исключить свои IP из бана!
ignoreip = 127.0.0.1/8 YOUR.TRUSTED.IP
[sshd]
enabled = true
port = 22
logpath = %(sshd_log)s
maxretry = 3
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 5
[postfix-sasl]
enabled = true
port = smtp,submission
logpath = /var/log/mail.log
maxretry = 5
sudo systemctl restart fail2ban
Управление и мониторинг
# Общий статус
sudo fail2ban-client status
# Статус конкретного jail
sudo fail2ban-client status sshd
# Ручной бан IP
sudo fail2ban-client set sshd banip 192.168.1.100
# Разбанить IP
sudo fail2ban-client set sshd unbanip 192.168.1.100
# Посмотреть забаненные IP в iptables
sudo iptables -L f2b-sshd -n -v
# Логи Fail2Ban
sudo journalctl -u fail2ban -f
Мониторинг атак в реальном времени
# Следить за банами SSH в реальном времени
sudo tail -f /var/log/auth.log | grep "Failed password"
# Топ атакующих IP
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20