fail2ban
Защита от перебора паролей: fail2ban читает журналы служб и банит адреса, с которых подбирают пароли. В nkt у него свой раздел — сразу под «Firewall» — и сводка по всем хостам на хабе.

Установка и подготовка
Если fail2ban не установлен, в разделе есть кнопка «Установить fail2ban»: пакет дистрибутива (apt) ставится фоновым заданием в стандартном окне журнала, как ufw и firewalld. После установки nkt сам выполняет подготовку (её же можно запустить кнопкой «Подготовить» в любой момент):
- адрес хаба в
ignoreip— файлjail.d/zz-nkt-hub.localс[DEFAULT] ignoreip: прежний список изjail.localиjail.dплюс внешний адрес хаба (подробнее — ниже); - джейл ручных банов
nkt-manual— без журнала и фильтра, на все порты: в него попадают баны из интерфейса и «Забанить на всех хостах»; - sshd через journald там, где у sshd нет журнала в файле (Debian 12 и новее пишут только в journald, и джейл sshd с
auth.logне стартует) — файлjail.d/nkt-sshd.localсbackend = systemd; - затем
reloadработающему fail2ban или запуск остановленного.
nkt пишет только свои файлы — jail.d/nkt-*.local, jail.d/zz-nkt-hub.local, filter.d/nkt-*.conf. jail.conf пакета не трогается: его перезаписывает обновление пакета.
Свои файлы прежних версий nkt обновляет сам — при запуске службы и раз в полчаса. Фильтр nkt-manual из nkt 1.11.x был без группы <HOST>: fail2ban-client -t его пропускает, а перезагрузка fail2ban падает целиком, и сервер остаётся без джейлов, в том числе без sshd («jail 'sshd' does not exist»). Такой фильтр заменяется текущим, работающий fail2ban перезагружается; запись — в журнале действий от имени nkt.
Состояние и джейлы
Карточка «Состояние»: работает ли сервер, версия, сколько джейлов и забанено сейчас, адрес хаба и попал ли он в ignoreip каждого джейла, ваш адрес.
Таблица «Джейлы» — запущенные джейлы: откуда читают (файлы журнала или совпадения journald; файл, которого нет на диске, подсвечен красным), правила («5 попыток за 10 мин → бан на 1 ч»), провалы и баны (сейчас / всего). Действия в строке:
- править — окно с формой и текстом (ниже);
- перезагрузить джейл (
fail2ban-client reload <джейл>); - выключить — то же окно правки с
enabled = false: перед записью виден дифф; - история версий файла джейла.
Выключенные джейлы nkt (enabled = false) перечислены под таблицей со ссылкой «включить». Джейлы, которые включены, но fail2ban их не поднял (нет журнала, нет фильтра, не тот backend), показаны отдельно, красным: со строками журнала fail2ban о причине и ссылкой «Править» — «включить» им не поможет. Если вся конфигурация fail2ban не проходит проверку (fail2ban-client -t), над таблицей — предупреждение с ошибкой: сервер ещё работает со старыми настройками, но следующая перезагрузка упадёт.
Правка джейла

Правка пишется в файл nkt jail.d/nkt-<джейл>.local — настройки поверх jail.conf. Над редактором — форма: включён, maxretry, findtime, bantime, bantime.increment, backend, logpath, ignoreip; пустое поле — значение по умолчанию (подсказка показывает действующее). Форма меняет строки текста, не трогая остального, текст можно править и руками.
Запись — общим путём «Конфигураций»: «Сохранить» показывает дифф «сохранено → черновик», затем fail2ban-client -t проверяет всю конфигурацию; если она не проходит — файл возвращается как был. После записи — reload. Каждая запись — версия в истории, с диффом и откатом.
Свой ignoreip у джейла заменяет [DEFAULT] целиком — поэтому адрес хаба добавляется в него сам, как только поле заполнено.
Исключения (ignoreip)

Карточка «Исключения (ignoreip)» — адреса, которые fail2ban не банит никогда:
- Общий список (
[DEFAULT] ignoreip) и файл, где он задан. Адрес хаба показан отдельно и закреплён: его держит файл защиты nktjail.d/zz-nkt-hub.localповерх общего списка. - Действующий список каждого джейла с пометкой «общий» или «свой»: свой
ignoreipджейла заменяет общий целиком и правится в окне джейла (кнопка рядом).
«Изменить общий список» — по одному адресу, сети (CIDR) или имени хоста в строке; кнопка «добавить мой адрес» — ваш текущий. Список пишется туда, где он уже задан (обычно jail.local; если нигде — в jail.local), затем файл защиты хаба собирается заново. Перед записью — дифф всех файлов, которые изменятся, и проверка fail2ban-client -t; у файла со списком — история версий.
Правка ignoreip мимо этой карточки — в «Конфигурациях» (запись или откат любого файла fail2ban) — тоже подхватывается: файл защиты хаба собирается заново сам.
Забаненные адреса
Таблица всех банов по джейлам: адрес, джейл, когда забанен и до какого времени (fail2ban 0.11+). Поиск по адресу и джейлу, разбан строкой или галочками, «Разбанить все» — с подтверждением.
«Забанить…» — ручной бан: адреса (по одному в строке), джейл (по умолчанию nkt-manual) и срок (час, сутки, неделя, 30 дней, год). Свой адрес и адрес хаба забанить нельзя: окно предупреждает, сервер отказывает.
Журнал событий

События Ban / Unban / Found / Restore Ban / Increase Ban за 1, 3 или 7 дней — из /var/log/fail2ban.log и его ротаций (включая .gz), а если fail2ban пишет в journald — из journald. Поиск по адресу, джейлу и тексту строки, фильтры по джейлу и событию, новые сверху. Отдельно nkt ничего не хранит: это журнал самого fail2ban.
Шаблоны

«Шаблоны» — готовые джейлы:
| Шаблон | Для чего |
|---|---|
sshd | перебор паролей и ключей SSH (с backend = systemd, если журнала в файле нет) |
nginx-http-auth | неверный пароль basic auth в nginx |
nginx-botsearch | боты, ищущие админки и уязвимые скрипты |
nginx-limit-req | превышение limit_req |
haproxy-http-auth | неверный пароль basic auth в HAProxy |
postfix, dovecot | почта: отказы SMTP, подбор паролей IMAP/POP3 |
recidive | рецидивисты: кого банили много раз — надолго и на всех портах |
Колонка «На этом хосте» показывает, есть ли программа шаблона; выделены те, что к месту. «Применить» открывает текст (его можно поправить), затем — дифф файлов, которые изменятся, и запись с проверкой fail2ban-client -t; если проверка не прошла, всё возвращается как было.
Свои шаблоны — кнопка «Новый шаблон»: имя, описание, текст джейла и, при желании, свой фильтр с failregex. Фильтр записывается в filter.d/nkt-<имя>.conf, строка filter = nkt-<имя> добавляется в джейл сама. «Проверить фильтр» гоняет fail2ban-regex по журналу этого хоста (файл под /var/log или systemd-journal) и показывает, сколько строк совпало. Сохранение — через дифф, у каждого шаблона история версий с откатом; удаление — тоже версия, шаблон можно вернуть.
Под хабом свои шаблоны хранятся на хабе — одни на все хосты; на одиночном хосте — на нём самом.
Защита от самоблокировки
Хаб ходит на хосты по SSH, и несколько неудачных подключений подряд (сменился ключ, хост перегружен) — повод для джейла sshd забанить сам хаб. Поэтому:
- хаб узнаёт свой внешний адрес глазами хоста — из
SSH_CONNECTIONсвоей SSH-сессии — и передаёт его хосту: после запуска хаба, раз в 6 часов и в течение 10 минут, если хост сообщает, что защиты у него нет (например, fail2ban только что поставили); перед шаблоном на хосты — всегда, первым файлом; - хост держит этот адрес в
[DEFAULT] ignoreip(файлjail.d/zz-nkt-hub.local, читается последним: общий список плюс адрес хаба) и собирает файл заново, если сменился адрес или общий список (Исключения); - забанить адрес хаба или адрес, с которого пришёл сам запрос, нельзя — ни на странице, ни заданием хаба;
- находка «Хаб может забанить сам себя» появляется, если у какого-то джейла адреса хаба нет в
ignoreip.
Находки
- SSH открыт наружу, а fail2ban не установлен — средняя.
- fail2ban установлен, но не работает — высокая при открытом SSH.
- fail2ban не защищает SSH — нет запущенного джейла sshd.
- Джейл ничего не видит — файлов его журнала нет на диске.
- Хаб может забанить сам себя — высокая.
- Конфигурация fail2ban не проходит проверку — высокая: следующая перезагрузка или перезапуск fail2ban упадёт.
Находки видны в «Проблемах» хоста; высокие приходят оповещением хаба.
На хабе

Раздел «fail2ban» в меню хаба:
- Хосты — где fail2ban установлен, работает и сколько забанено.
- Забаненные адреса по всем хостам: адрес, на каких хостах и в каких джейлах; сверху — забаненные на большем числе хостов. Галочками — «Забанить на всех хостах» и «Разбанить на всех хостах».
- Шаблоны — стандартные и свои (свои хранятся здесь, с историей версий); у каждого — «На хосты».
Шаблон на хосты. Окно со списком хостов: галочки по умолчанию сняты, есть «Выбрать все» и «Снять все»; хост без fail2ban выбрать нельзя. Сначала обязательно «Проверить» — задание хаба: пробный прогон на каждом выбранном хосте, ничего не записывая. Хост собирает копию своей конфигурации fail2ban с файлами шаблона и проверяет её целиком (fail2ban-client -t). По каждому хосту — «будут изменения», «без изменений», «пропущен» (с причиной) или «ошибка», у изменений — дифф файлов и защита хаба: «хаб в ignoreip» или «защита хаба будет добавлена первой». Если конфигурация хоста сломана ещё до шаблона (например, джейл ссылается на несуществующий фильтр), это сказано прямо, и в применение такой хост не попадает.
«Применить» доступно только после проверки и применяет ровно проверенное: задание хаба, по три хоста сразу, со стандартным окном журнала. На каждом хосте по порядку:
- Файл защиты хаба — адрес хаба глазами этого хоста (хаб узнаёт его по SSH прямо перед проверкой) в
ignoreip. Хост, чей адрес хаба не узнать (связь только через туннель), шаблон не получает. - Файлы шаблона, проверка конфигурации и перезагрузка fail2ban.
- Проверка, что работают все прежние джейлы и джейл шаблона; нет — файлы откатываются, fail2ban перезагружается обратно, в ошибке — строки журнала fail2ban.
- Если хаб всё же успел попасть в бан (старые записи журнала свежим джейлом), бан снимается сразу; это видно в журнале задания.
Все задания fail2ban хаба — проверки, применения шаблонов, бан и разбан на всех хостах — идут одной очередью, по одному. Проверка годна 30 минут и один раз; изменили выбор хостов — проверяйте заново. Хост со старым nkt (без проверки конфигурации) пропускается с просьбой обновить nkt.
Стандартный шаблон каждый хост отдаёт свой: например, sshd на хосте, где журнал sshd только в journald, — с backend = systemd. Хост без программы шаблона (нет nginx для nginx-*) пропускается. Свой шаблон — один текст с хаба на все хосты.
Бан на всех хостах — задание хаба с журналом, по шагу на хост: адрес банится в джейле nkt-manual на выбранный срок (по умолчанию неделя), хосты по умолчанию — все, где есть fail2ban; хост без fail2ban или со старой версией nkt пропускается с пометкой в журнале.
- Внутренний адрес (частная сеть 10/8, 172.16/12, 192.168/16, loopback, link-local, CGNAT) банится только после отдельного подтверждения со списком таких адресов: так можно отрезать доступ своим — прокси, VPN, соседней машине, самому хабу.
- «Отменить» — после успешного бана или разбана внизу экрана 15 секунд держится плашка с обратным отсчётом. Кнопка запускает обратное задание на тех же хостах: разбан тех же адресов или бан их на неделю (прежний срок не известен). Отменённое повторно не отменяется.
В списке хостов хаба — колонка «f2b»: сколько адресов забанено сейчас.
Оповещения и проверка адреса

Хаб опрашивает хосты раз в минуту и замечает новые баны — оповещение «fail2ban забанил новые адреса» с адресами и джейлами (вид «новые баны» в настройках оповещений; по умолчанию записывается, но не всплывает).
У каждого внешнего адреса в тексте любого оповещения — своя лампочка: проверка адреса моделью со своей инструкцией (правится в «О системе → ИИ», вид «проверка внешнего адреса»). Хаб собирает факты об адресе: тип (публичный или частный), обратный DNS, на каких хостах и в каких джейлах он забанен сейчас, строки журналов fail2ban хостов за неделю, упоминания в оповещениях. Модель отвечает: кто это, насколько опасен, что сделать. Проверяемый адрес уходит модели как есть — даже при включённом «скрывать адреса и имена» (он чужой, и без него разбор бессмыслен); адреса и имена ваших хостов по-прежнему заменяются.
В окне ответа — кнопка «Забанить на всех хостах»: то же задание хаба. Кнопка есть и если ИИ не настроен или не ответил. Та же лампочка — у адресов на странице fail2ban хоста и в сводке хаба.