Fail2ban: как вывести список заблокированных IP по всем jail (2026) | AdminWiki

Fail2ban: как вывести список заблокированных IP по всем jail (2026)

24 сентября 2026 13 мин. чтения

Быстрый ответ: как получить список IP по всем jail

Полный перечень активных блокировок собирается в два шага: команда fail2ban-client status отдаёт список включённых jail, затем для каждого jail вызывается fail2ban-client status <jail> и из вывода берётся строка Banned IP list. Одна строка адресов и есть все IP, забаненные в этом jail прямо сейчас.

Все команды идут через локальный сокет fail2ban (типичный путь /var/run/fail2ban/fail2ban.sock), поэтому запускать их нужно от root или через sudo. На сервере с большим числом jail вывод получится длинным, так что второй шаг сразу планируйте с записью в файл, пример есть ниже.

Дальше разбираем разницу между счётчиками fail2ban, проверяем фактические блокировки в iptables и ipset, выгружаем адреса в текстовый файл и CSV и снимаем баны, когда правило сработало ложно.

Готовая команда для копирования

Цикл по всем активным jail с печатью списка забаненных адресов:

for jail in $(fail2ban-client status | sed -n 's/^.*Jail list:[[:space:]]*//p' | tr -d ' ' | tr ',' ' '); do
  echo "=== $jail ==="
  fail2ban-client status "$jail" | grep -F 'Banned IP list'
done

Что делает каждая часть:

  • fail2ban-client status печатает строку вида Jail list: sshd, nginx-http-auth;
  • sed -n 's/^.*Jail list:[[:space:]]*//p' оставляет от строки только имена, отрезая префикс и служебные символы дерева вывода;
  • tr -d ' ' убирает пробелы, иначе первое имя jail получит лишний символ и команда вернёт ошибку;
  • tr ',' ' ' превращает запятые в пробелы, чтобы цикл for получил отдельные имена. Пропустите этот шаг, и список sshd,nginx-http-auth превратится в одно несуществующее имя;
  • grep -F 'Banned IP list' печатает строку с адресами, а ключ -F отключает разбор шаблона как регулярного выражения.

Тот же список имён можно получить через awk, кому такой вариант читается проще:

fail2ban-client status | awk -F': *' '/Jail list/ {gsub(/,/," "); print $2}'

Пример вывода и что он означает

=== sshd ===
   `- Banned IP list: 203.0.113.14 198.51.100.7 2001:db8::1
=== nginx-http-auth ===
   `- Banned IP list:

Символы |- и `- в выводе служебные, это дерево CLI, а не часть данных. Адреса IPv4 и IPv6 идут в одном списке через пробел, отдельного вывода для шести адресов не будет. Пустая строка после двоеточия значит, что активных банов в jail нет, при этом сам jail включён и продолжает считать неудачные попытки.

Если во всех jail строки Banned IP list пусты, проверьте, что служба вообще работает и что вы смотрите на том сервере, где установлен fail2ban. В контейнерах и на хостах с несколькими сетевыми пространствами имён правила одного окружения не видны из другого.

Разбираем fail2ban-client status: что показывает и как читать

Без аргументов команда даёт общую картину: сколько jail включено и как они называются. С аргументом <jail> выводится статистика одного jail. Поля вывода отвечают на разные вопросы, и путать их не стоит.

Поле выводаЧто означаетКак использовать
Number of jailСколько jail включено в текущей конфигурацииПроверка, что правки в jail.local подхватились после reload
Jail listИмена активных jail через запятую с пробеломИсточник имён для цикла по всем jail
Currently failedНеудачные попытки, накопленные с момента последнего сброса окна findtimeВидно, идёт ли перебор паролей прямо сейчас
Total failedВсе неудачные попытки за время работы jailОценка нагрузки на сервис и активности сканеров
Currently bannedЧисло активных бановДолжно совпадать с количеством адресов в Banned IP list
Total bannedВсе баны за время работы jail, включая истёкшие и снятые вручнуюИсторический счётчик, не текущее состояние
Banned IP listАдреса, которые заблокированы сейчасТо, что нужно для аудита и разблокировки

Fail2ban хранит информацию о банах в базе SQLite и при перезапуске восстанавливает баны, срок которых ещё не истёк; при включённом инкрементальном бане (bantime.increment = true) история банов также сохраняется в базе. Поэтому расхождение между Total banned и Banned IP list нормально и само по себе не говорит о сбое. Точное поведение счётчиков (в частности, обнуляется ли Total banned при перезапуске службы) зависит от версии и сборки — проверяйте его на своём сервере.

В fail2ban 1.1.0 команда fail2ban-client status --all возвращает статус fail2ban и всех jail в обычной форме, а вариант flavor stats выводит статистику всех jail в виде таблицы с колонками jail, backend, found и banned counts. Это удобно, когда нужно быстро увидеть сводку по всем jail без ручного цикла.

Как отличить действующие блокировки от истёкших

Banned IP list содержит только активные баны. Когда время bantime истекает, адрес пропадает из списка автоматически, отдельной команды для чистки не требуется. Практический признак: если Currently banned показывает 0, Total banned показывает 42, а строка Banned IP list пуста, значит все сорок два бана уже истекли и блокировок на сервере нет.

Остаток времени бана удобно смотреть в наборе ipset: у каждой записи есть поле timeout в секундах. В цепочке iptables остаток времени бана не отображается. Настроенное время бана запрашивается у jail напрямую, например fail2ban-client get sshd bantime вернёт настроенное время бана. Команда get <jail> <параметр> есть в актуальных версиях fail2ban; если сборка старая, читайте значения в /etc/fail2ban/jail.local.

В fail2ban-client v0.11.2 команда get <JAIL> banip позволяет получить список заблокированных IP-адресов, в том числе с опцией --with-time для вывода времени бана. В fail2ban 1.0.1 эта команда также присутствует. Это альтернативный способ получить список адресов, не разбирая строку Banned IP list вручную.

Почему в списке могут отсутствовать некоторые IP

Бывает так: правило в iptables видно, а в fail2ban-client status адреса нет. Причины разные, и проверять их стоит по порядку.

  1. Бан истёк, а fail2ban ещё не успел снять правило, или наоборот: правило снято, а состояние уже обновилось. Задержка обычно измеряется секундами.
  2. Используется action без добавления адреса в фильтр: например, action только пишет в лог или отправляет уведомление, а бан выполняет внешняя система.
  3. Состояние потеряно после перезапуска: сборки без постоянной базы не восстанавливают баны, и записи в фильтре остаются без учёта в fail2ban.
  4. Адрес заблокирован вручную в iptables, ipset или сторонним агентом, например WAF, и fail2ban к этому бане отношения не имеет.
  5. Разные семейства адресов: блокировка IPv6 лежит в ip6tables, а смотрите вы iptables.
  6. Опечатка в имени jail: список из status регистрозависим, а лишний пробел после запятой легко попадает в переменную цикла.

Полную картину даёт сверка трёх источников: вывод fail2ban-client, цепочки пакетного фильтра и наборы ipset.

Проверка блокировок на уровне iptables и ipset

fail2ban-client показывает внутреннее состояние службы, а трафик режет пакетный фильтр. Расхождение между этими двумя картинами и есть повод разбираться. Общие принципы работы фильтров и сохранения правил после перезагрузки разобраны в материале о сравнении iptables, nftables и ufw.

Просмотр цепочек iptables, созданных fail2ban

Fail2ban создаёт для каждого jail отдельную пользовательскую цепочку с именем f2b-[jail] (например, f2b-sshd), а в INPUT добавляется правило, направляющее трафик на порт 22 в эту цепочку. Список всех таких цепочек и активных правил в них:

iptables -L -n --line-numbers | grep -E 'Chain f2b-|DROP|REJECT'
iptables -L f2b-sshd -n -v

Пример содержимого цепочки для jail sshd:

Chain f2b-sshd (1 references)
target     prot opt source               destination
REJECT     all  --  203.0.113.14         0.0.0.0/0            reject-with icmp-port-unreachable
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Пустая цепочка без адресов значит, что активных банов в этом jail нет. Для шести адресов те же команды выполняются через ip6tables. Ключ -v добавляет счётчики пакетов и байтов, по ним видно, сколько трафика реально отброшено; ключ -Z обнуляет эти счётчики, что удобно при аудите.

Цепочки f2b-* не редактируйте руками. При reload или restart fail2ban пересобирает их по своему состоянию, и снятое вручную правило вернётся, а внутренний список банов останется прежним. Ручные блокировки ведите в отдельных цепочках или наборах. При перезапуске сервера fail2ban цепочки iptables пересоздаются на основе информации, сохранённой в базе sqlite3.

В Docker-образе fail2ban переменная F2B_IPTABLES_CHAIN задаёт цепочку iptables, в которую добавляются правила Fail2Ban, по умолчанию DOCKER-USER. Если fail2ban работает в контейнере, проверяйте правила именно в этой цепочке, а не в INPUT.

Использование ipset для просмотра заблокированных IP

Наборы ipset держат тысячи адресов дешевле, чем длинные цепочки правил, поэтому часть сборок использует action с ipset. Посмотреть все наборы fail2ban и содержимое одного из них:

ipset -n list | grep '^f2b-'
ipset list f2b-sshd

Вывод для набора jail sshd выглядит так:

Name: f2b-sshd
Type: hash:ip
Header: family inet hashsize 1024 maxelem 65536 timeout 600
Number of entries: 2
Members:
203.0.113.14 timeout 421
198.51.100.7 timeout 588

Все типы наборов ipset поддерживают необязательный параметр timeout при создании набора и добавлении записей; значение задаёт время жизни новых записей в секундах. Поле timeout показывает остаток в секундах: запись 203.0.113.14 перестанет действовать через 421 секунду. Истечение обрабатывает ядро само, без участия fail2ban, поэтому в ipset блокировки живут ровно до конца таймаута. Время жизни уже добавленных в ipset элементов можно изменить, повторно добавив элемент с опцией timeout; максимально возможное значение timeout — 2147483. Какой механизм применяет ваш jail, видно по параметру banaction: проверьте его командой grep -R "banaction" /etc/fail2ban/. Конкретное значение banaction по умолчанию зависит от дистрибутива и сборки, поэтому ориентируйтесь на фактический конфиг, а не на ожидаемое имя.

Если banaction переводит блокировки в nftables, проверка идёт через nft list ruleset: ищите таблицу и наборы с упоминанием f2b. Имена объектов зависят от версии и шаблона action, поэтому ориентируйтесь на фактический вывод, а не на ожидаемое имя. Техника работы с наборами и таймаутами разобрана в статье про динамические наборы nftables.

Как выгрузить список заблокированных IP в файл

Команду из начала статьи удобно держать отдельным скриптом, чтобы запускать её из cron и не собирать цикл заново. В примерах ниже сохранение идёт в файл с датой в имени.

Простой экспорт в текстовый файл

Скрипт /usr/local/bin/f2b-banned.sh:

#!/usr/bin/env bash
set -u
for jail in $(fail2ban-client status | sed -n 's/^.*Jail list:[[:space:]]*//p' | tr -d ' ' | tr ',' ' '); do
  echo "=== $jail ==="
  fail2ban-client status "$jail" | grep -F 'Banned IP list'
done

Выдайте права на запуск и сохраните результат:

chmod +x /usr/local/bin/f2b-banned.sh
sudo /usr/local/bin/f2b-banned.sh > banned_ips_$(date +%F).txt

Файл собирается из секций по каждому jail, читать его удобно глазами. Тонкость с правами: перенаправление выполняет ваша оболочка, а не sudo, поэтому файл создастся от вашего пользователя в текущем каталоге. Если нужен файл в /root, запускайте через sudo sh -c с записью внутри команды.

Экспорт в CSV для анализа

Для таблиц и скриптов удобнее построчный формат jail,ip. Скрипт /usr/local/bin/f2b-banned-csv.sh:

#!/usr/bin/env bash
set -u
printf 'jail,ip\n'
for jail in $(fail2ban-client status | sed -n 's/^.*Jail list:[[:space:]]*//p' | tr -d ' ' | tr ',' ' '); do
  for ip in $(fail2ban-client status "$jail" | sed -n 's/^.*Banned IP list:[[:space:]]*//p'); do
    printf '%s,%s\n' "$jail" "$ip"
  done
done

Запуск и результат:

sudo /usr/local/bin/f2b-banned-csv.sh > banned_ips_$(date +%F).csv
jail,ip
sshd,203.0.113.14
sshd,198.51.100.7
nginx-http-auth,198.51.100.7

Внутренний цикл разбивает строку адресов по пробелам, а sed с ключом -n вырезает только нужную часть строки, поэтому лишние пробелы и служебные символы в CSV не попадают. Запуск каждые 15 минут настраивается файлом /etc/cron.d/f2b-export со строкой вида */15 * * * * root /usr/local/bin/f2b-banned-csv.sh >> /var/log/f2b-banned.csv. Для cron уберите из скрипта printf заголовка, иначе строки jail,ip будут дублироваться при каждом запуске, и добавьте файл в logrotate, чтобы он не вырос до гигабайтов. Сбор статистики банов в общую картину мониторинга и алертов описан в материале про мониторинг и автоматическое реагирование.

Как разблокировать IP: снятие бана вручную и массово

Снимайте блокировки только после подтверждения, что срабатывание ложное. Если адрес ваш собственный, надёжнее добавить его в ignoreip в jail.local и выполнить reload: тогда он не попадёт в бан снова. После ручного снятия атакующий со стороны продолжит перебор, и тот же IP вернётся в список при следующем срабатывании правила.

Снятие блокировки с одного IP

fail2ban-client set sshd unbanip 203.0.113.14

Имя jail указывается точно так, как оно выводится в Jail list. Проверка результата:

fail2ban-client status sshd

Адрес должен исчезнуть из Banned IP list, а счётчик Currently banned уменьшиться на единицу. Если IP остался в списке, посмотрите цепочку iptables -L f2b-sshd -n и набор ipset list f2b-sshd: расхождение укажет, что бан добавлен вручную или другим инструментом.

Массовая разблокировка всех IP в jail

Когда правило настроено слишком строго и под бан попали десятки адресов, снять их все можно циклом по текущему списку:

for ip in $(fail2ban-client status sshd | sed -n 's/^.*Banned IP list:[[:space:]]*//p'); do
  fail2ban-client set sshd unbanip "$ip"
done

Цикл работает во всех версиях, потому что опирается только на вывод status и set <jail> unbanip. В fail2ban-client v0.11.2 команда unban --all снимает баны всех IP-адресов во всех jail и в базе данных, а unban <IP> — бан указанного IP во всех jail и в базе данных. Наличие и поведение ключа --all зависит от версии, поэтому перед использованием проверьте справку на своём сервере: fail2ban-client --help. Если ключ есть, команда выполняется быстрее и без цикла.

Разблокировка IP во всех jail

Один и тот же адрес может быть забанен сразу в нескольких jail: например, в sshd и в nginx-http-auth. Снять его везде помогает обход всех jail:

for jail in $(fail2ban-client status | sed -n 's/^.*Jail list:[[:space:]]*//p' | tr -d ' ' | tr ',' ' '); do
  fail2ban-client set "$jail" unbanip 198.51.100.7
done

В fail2ban-client v0.11.2 команда unban <IP> снимает бан указанного IP во всех jail и в базе данных, но её поведение отличается между сборками, поэтому цикл предсказуемее. После массовых операций вернитесь к списку и убедитесь, что лишние баны исчезли, а нужные остались: если адреса были забанены обоснованно, вы только что открыли им доступ.

Чек-лист и типичные ошибки

Порядок действий при аудите блокировок:

  1. Проверьте, что служба запущена: systemctl status fail2ban, и что сокет доступен вашему пользователю или sudo.
  2. Соберите список jail через fail2ban-client status и убедитесь, что все нужные jail в нём есть.
  3. Сравните Banned IP list с цепочками f2b-* в iptables или наборами f2b-* в ipset: расхождения разбирайте, а не игнорируйте.
  4. Сверьте счётчик Currently banned с числом адресов в списке.
  5. После разблокировки проверьте, что адрес ушёл из fail2ban-client status и из фильтра.
  6. Настройте периодический экспорт в файл, чтобы видеть динамику банов и рост числа атак.

Ошибки, которые встречаются чаще всего:

  • Удаление запятых без замены на пробел: имена jail слипаются, и команда падает с ошибкой про несуществующий jail.
  • Путаница между Total banned и Banned IP list: первый счётчик исторический, второй показывает текущие блокировки.
  • Проверка только через fail2ban-client без просмотра iptables и ipset, из-за чего ручные блокировки и остатки правил остаются незамеченными.
  • Ручное удаление правил в цепочках f2b-*: fail2ban восстановит их при следующем reload, а состояние разойдётся с фильтром.
  • Просмотр iptables там, где блокировка IPv6 живёт в ip6tables.
  • Массовая разблокировка без проверки списка: часть адресов могла быть забанена за реальную атаку.
  • Чтение сокета без прав root, что даёт ошибку соединения вместо списка адресов.

Команды fail2ban-client status, set <jail> unbanip и unban не менялись в основных версиях 0.11 и 1.0, так что приведённые примеры остаются рабочими. Отличия между сборками лежат в другом: в шаблонах action (iptables, ipset, nftables), в постоянной базе банов и в unit-файле systemd. Формат вывода и набор доступных ключей проверяйте на своём сервере через man fail2ban-client и fail2ban-client --help, а любые массовые операции сначала прогоняйте на тестовом стенде, чтобы не потерять SSH-доступ к продакшн-хосту. Заготовки для ручных блокировок и подсетей собраны в статье про блокировку IP-адресов в 2026 году.

Источники

Поделиться:
Сохранить гайд? В закладки браузера