Серверы и мониторинг

fail2ban молчал полгода: защита, которая читала не тот журнал

Автобан сканеров стоял полгода и не забанил никого. Конфиг был верный, сухой прогон проходил. Разбор: почему проверка регулярки ничего не доказывает.

Александр Цапков10 сентября 20263 мин
Статус jail fail2ban: нули в Total failed и Total banned, ниже строка «No file is currently monitored»

Полгода на боевом сервере стоял fail2ban и не забанил ни одного адреса. Настроен он был правильно — и именно поэтому проблему не искали.

Как это выглядит снаружи

Служба запущена, jail включён, logpath прописан явно, fail2ban-regex на тестовом наборе строк показывает совпадения. Все привычные признаки живой защиты на месте.

Единственное, что вызывало вопрос, — счётчик:

Status for the jail: nginx-scan
|- Filter
|  |- Currently failed: 0
|  `- Total failed:     0
`- Actions
   `- Total banned:     0

Ноль. За полгода, на сервере, который сканируют ежедневно.

Нолю легко найти объяснение: «значит, до нас не доходят», «фильтр строгий». Так и было — до тех пор, пока в том же статусе не обнаружилась строка «No file is currently monitored».

Почему jail не дошёл до файла

Глобальный backend у fail2ban на Ubuntu — systemd. Jail с этим backend читает системный журнал, а не файл, и logpath в нём при этом остаётся записанным: значение есть, оно просто не используется.

Внешне конфиг выглядит настроенным. Внутри jail слушает журнал, куда логи nginx не попадают вовсе.

Лечится одной строкой в jail:

backend = polling

Почему сухой прогон это пропустил

fail2ban-regex открывает указанный файл сам, напрямую. Он проверяет одно: подходит ли регулярное выражение к строкам. Дошёл ли до этого файла живой jail — вопрос, которого он не задаёт.

Отсюда правило, которое дороже самой правки:

Сухой прогон проверяет регулярку, а не работу.

Тот же класс ошибки бывает у любой проверки, которую пишут «чтобы была»: она зелёная, потому что проверяет не то. У нас из-за этого появилось отдельное требование к собственным проверкам — новая обязана быть испытана подстановкой той поломки, ради которой написана. Сломай нарочно, убедись, что ловит, верни.

Как проверить у себя за минуту

sudo fail2ban-client status
sudo fail2ban-client status <имя-jail>

Смотреть надо не на «running», а на две вещи:

  1. Total failed — если за месяцы ноль, это не тишина, а слепота;
  2. строку про наблюдаемый файл — «No file is currently monitored» означает, что jail не читает ничего.

Настоящая проверка — срабатыванием: дождаться реального перебора (на любом публичном сервере это часы) и увидеть, как счётчик вырос.

Второй слой: бан есть, а в списке его нет

Из того же разбора. Бан, который fail2ban ставит через ufw, — это REJECT, а не DENY. Привычная команда

sudo ufw status | grep DENY

не покажет ни одного бана, даже когда они есть. Проверять надо ufw status numbered целиком или тем же fail2ban-client status.

Две независимые слепые зоны в одной защите: счётчик, который всегда ноль, и список, в котором бана не видно.

Что из этого следует

Защита на сервере отличается от остального кода тем, что её нормальное состояние и её отказ выглядят одинаково — тихо. Приложение, которое не работает, заметит пользователь; fail2ban, который не работает, не заметит никто, потому что его работа и есть отсутствие событий.

Значит, у любой такой защиты должен быть признак жизни, а не признак настроенности: растущий счётчик, запись в журнале, число забаненных за неделю. Всё, что отвечает «я настроен», не отвечает на вопрос, работает ли оно.


Мы после этого случая вынесли счётчики наружу: подбор паролей и сканы портов видны графиком в самой платформе, а не в выводе команды, за которой надо пойти на сервер. Как это устроено — на странице Аналитика угроз.

Аналитика угроз: подбор паролей и сканы портовКто подбирает пароли, сканирует порты и с каких сетей — по журналам сервера.

Читайте также

Автор

Александр ЦапковОснователь Скоупворк

Веду платформу и её боевой контур сам: разработка, выкат, дежурство. Пишу о том, на чём мы обожглись, — с датами, замерами и ссылками на решения в репозитории.