linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Безопасность/fail2ban

kb/security ── Безопасность ── intermediate

fail2ban - автобан по логам

fail2ban читает логи (sshd, nginx, postfix), регэкспом ловит N неудачных попыток за окно, добавляет IP в правила firewall'а на bantime. Главный инструмент против brute-force на SSH.

view as markdownaka: fail-2-ban, fail2ban-client, jail-local

Что делает и зачем

На любом публичном SSH порт 22 за сутки получает тысячи попыток brute-force: словарные root/password, admin/admin, etc. Сильный пароль

  • ключи защищают, но логи захламлены и тратится CPU на bcrypt-проверки.

fail2ban работает так:

/var/log/auth.log
     ↓ tail -F
fail2ban читает построчно
     ↓
применяет regex-фильтр (filter.d/sshd.conf)
     ↓
если IP X сделал N FAIL'ов за findtime секунд
     ↓
→ добавить правило REJECT для X в firewall на bantime секунд
     ↓
по истечении - удалить правило

Применимо ко всему что пишет логи: SSH, Apache/nginx (auth_basic), Postfix (smtp-auth), Dovecot, ProFTPD, Asterisk, named (DNS-amplification).

Установка

bash
# Debian/Ubuntu
sudo apt install fail2ban
# RHEL/Fedora - нужен EPEL
sudo dnf install epel-release
sudo dnf install fail2ban

Демон fail2ban (через systemd: fail2ban.service). CLI - fail2ban-client.

Архитектура конфигов

/etc/fail2ban/
├── jail.conf          ← vendor, НЕ ТРОГАТЬ (перезапишется при apt upgrade)
├── jail.local         ← твой override (создавать самому)
├── jail.d/            ← модульные override'ы (50-sshd.local и т.д.)
├── filter.d/          ← regex-фильтры под каждый сервис (sshd.conf, apache-auth.conf)
├── action.d/          ← действия (firewallcmd-ipset, iptables, ufw)
└── fail2ban.local     ← глобальные настройки демона

Стандартный путь: скопировать jail.conf в jail.local, править local. fail2ban читает оба, local перебивает vendor.

bash
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Минимальный jail.local

ini
[DEFAULT]
# Глобальные настройки для всех jails
bantime  = 1h           # на сколько банить (поддерживает s, m, h, d, w)
findtime = 10m          # окно для подсчёта попыток
maxretry = 5            # порог попыток
backend  = systemd      # читать journal вместо файлов (важно!)
ignoreip = 127.0.0.1/8 ::1 192.168.0.0/24    # whitelist
banaction = iptables-multiport               # или firewallcmd-ipset, nftables-multiport
# SSH - почти всегда первое что включаем
[sshd]
enabled = true
port    = ssh
filter  = sshd
logpath = %(sshd_log)s
maxretry = 3              # для SSH строже чем глобально
bantime  = 24h            # и баним на дольше

Без enabled = true jail не активируется даже если упомянут.

Опции %(sshd_log)s и %(sshd_backend)s - переменные из paths-*.conf, они автоматически подставят правильный путь для дистрибутива.

bantime / findtime / maxretry

Семантика:

  • maxretry - сколько неудач достаточно для бана.
  • findtime - окно в секундах, в котором считаем maxretry.
  • bantime - на сколько банить.

Пример: findtime=600 maxretry=5 → 5 неудач за 10 минут = бан.

Слишком жёстко (maxretry=2) - банишь себя при опечатке. Слишком мягко (maxretry=20) - boты успевают подобрать. Разумный SSH-default: maxretry=3, bantime=24h, findtime=10m.

bantime.increment - экспоненциальный бан

Современный fail2ban умеет наращивать bantime для рецидивистов:

ini
[DEFAULT]
bantime           = 1h
bantime.increment = true        # включить
bantime.factor    = 2           # множитель
bantime.maxtime   = 1w          # потолок

Первый бан 1ч, второй 2ч, четвёртый 8ч, ..., потолок неделя. После такого боты уходят.

Какой backend выбрать

  • auto - пусть fail2ban сам решит (часто работает плохо).
  • pyinotify - следит за файлом через inotify (быстро, для логов в файле).
  • systemd - читает journald напрямую. Рекомендуется для современных дистрибутивов где sshd пишет в journal а не в auth.log.

Если backend не тот - fail2ban запустится но ничего не увидит. Признак: fail2ban-client status sshd показывает Total failed: 0 хотя в журнале миллион FAIL'ов.

Активация конкретных jails

По умолчанию (jail.conf) большинство jails имеют enabled = false. Включай только те что нужны.

Самые популярные:

ini
[sshd]
enabled = true
...
[apache-auth]
enabled = true
port    = http,https
logpath = /var/log/apache2/error.log
[postfix]
enabled = true
port    = smtp,ssmtp,submission
logpath = %(postfix_log)s
[recidive]
enabled  = true                    # мета-jail: банит тех кто уже был забанен в других jails
bantime  = 1w
findtime = 1d
maxretry = 5

recidive - кросс-jail рецидивист. Кого-то забанили в sshd, потом в apache-auth - recidive забанит на неделю поверх обычного бана.

Управление через fail2ban-client

bash
# обзор всех активных jails
sudo fail2ban-client status

▸Status

▸|- Number of jail: 2

▸`- Jail list: sshd, recidive

# детали по конкретному jail
sudo fail2ban-client status sshd

▸Status for the jail: sshd

▸|- Filter

▸| |- Currently failed: 3

▸| |- Total failed: 1247

▸| `- File list: /var/log/auth.log

▸`- Actions

▸|- Currently banned: 5

▸|- Total banned: 143

▸`- Banned IP list: 45.x.x.x 196.x.x.x ...

# ручной бан / разбан
sudo fail2ban-client set sshd banip 1.2.3.4
sudo fail2ban-client set sshd unbanip 1.2.3.4
# снять все баны во всех jails
sudo fail2ban-client unban --all
# перечитать конфиг без рестарта
sudo fail2ban-client reload
sudo fail2ban-client reload sshd       # один jail

Как написать свой filter

Допустим у тебя своё API логирующее [AUTH-FAIL] from 1.2.3.4 invalid token. Создаём /etc/fail2ban/filter.d/myapi.conf:

ini
[Definition]
failregex = ^.*\[AUTH-FAIL\] from <HOST> .*$
ignoreregex =

<HOST> - специальный токен fail2ban для подстановки IP/hostname.

Подключаем jail в jail.local:

ini
[myapi]
enabled = true
filter  = myapi
port    = http,https
logpath = /var/log/myapi/access.log
maxretry = 3

Проверить regex без перезапуска:

bash
fail2ban-regex /var/log/myapi/access.log /etc/fail2ban/filter.d/myapi.conf

▸Lines: 1234 lines, 0 ignored, 17 matched, 1217 missed

Если matched: 0 - regex не работает.

Дебаг - почему не банит

bash
sudo systemctl status fail2ban
sudo journalctl -u fail2ban -f                  # стрим логов демона
sudo tail -F /var/log/fail2ban.log              # его собственный лог
# проверка что jail видит свой лог:
sudo fail2ban-client status sshd
# Total failed должно расти при попытках
# тест regex на реальном файле
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

Типичные причины «не работает»:

  • Backend mismatch: sshd пишет в journal, а jail настроен на файл. Поставить backend = systemd.
  • maxretry слишком высокий: успеваешь себя забанить сам при тестах, но боты ещё не накопили - поставь временно 2.
  • ignoreip покрывает атакующего: проверь не входит ли его подсеть.
  • firewall не применил правило: на nftables-системах с iptables-legacy может быть конфликт. Использовать banaction = nftables-multiport.

Сравнение с альтернативами

  • CrowdSec - современная замена, шарит блок-листы между всеми инсталляциями (federated). Сложнее, но эффективнее против ботнетов.
  • sshguard - лёгкий, только под SSH/SMTP/etc, на C, не Python.
  • firewalld + ipset вручную - сам пишешь скрипт парсинга. Не делай так в проде.

§ команды

bash
sudo fail2ban-client status sshd

Сколько IP забанено сейчас в SSH-jail и сколько было всего - главный обзор

bash
sudo fail2ban-client set sshd unbanip 1.2.3.4

Разбанить конкретный IP - когда сам случайно попал в свой бан

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

Тест regex'а фильтра на реальном логе - увидеть сколько строк матчатся

bash
sudo fail2ban-client reload sshd

Применить изменения jail.local без полного рестарта демона

bash
sudo journalctl -u fail2ban -f

Live-стрим логов fail2ban - увидеть в реальном времени баны/анбаны

§ см. также

  • sshSSH - secure shellSSH - зашифрованный канал к удалённому хосту: shell, копирование файлов, port-forwarding. Стандартный порт 22, аутентификация по ключам или паролю.
  • apache-httpdApache httpd - веб-серверApache httpd - веб-сервер. На RHEL пакет `httpd`, конфиг `/etc/httpd/conf/httpd.conf`. На Debian/Ubuntu пакет `apache2`, конфиг `/etc/apache2/apache2.conf` + `sites-enabled/`.
  • bind-dns-serverBIND - авторитативный/кеширующий DNS-серверBIND (Berkeley Internet Name Domain) - самый распространённый DNS-сервер в Linux. Демон `named`, конфиг `/etc/named.conf` или `/etc/bind/named.conf`, контроль через `rndc`.
  • pamPAM - Pluggable Authentication ModulesPAM - фреймворк аутентификации в Linux. Программы (sudo, login, sshd) не проверяют пароли сами, а вызывают PAM, который через стек модулей в `/etc/pam.d/<service>` решает: пускать или нет.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки