EnglishРусский Map

reaction

title
reaction
type
toolbox
summary
Более лёгкая альтернатива fail2ban: следит за выводом любых команд и запускает действия при повторяющихся совпадениях
tags
security, log-monitoring, daemon, rust, self-hosted, watchlist
language
Rust
license
AGPL-3.0
created
2026-07-18
updated
2026-09-14
lang
ru
translation_of
reaction
source_updated
2026-09-14
translated
2026-09-14
translator
lllm/antigravity/gemini-3.7-flash-medium

Демон, который отслеживает вывод программ, ищет слишком часто повторяющиеся паттерны и выполняет команду при их обнаружении. Канонический сценарий аналогичен fail2ban: следить за логами ssh и веб-сервера, считать неудачные попытки входа для каждого IP-адреса источника и банить хост, превысивший порог. Но механизм универсален: поток (stream) - это любая команда, чей stdout нужно читать, а действие (action) - любая команда, которую нужно запустить, так что привязки сугубо к файрволам или банам здесь нет.

Главные аргументы против fail2ban - скорость и простота конфигурации. Автор использовал fail2ban годами и устал от нагрузки на CPU и тяжёлой конфигурации по умолчанию. У reaction меньше возможностей, но заявлено более чем десятикратное снижение нагрузки на процессор и конфиг, который можно прочитать от начала до конца. Проект финансируется фондом NGI0 Core от NLnet (европейские гранты Next Generation Internet), поэтому это не пет-проект одного энтузиаста, рискующий быть заброшенным, хотя автор у него действительно один.

Версия 2.x - это полная переработка на Rust с сохранением всех возможностей старой версии на Golang (1.x, теперь устаревшей).

Как это устроено

Конфигурация хранится в одном файле - YAML или JSONnet. Оба формата являются надмножествами JSON, поэтому обычный JSON тоже подойдёт. JSONnet даёт больше возможностей: в нём можно писать и переиспользовать функции (например, хелпер banFor(time), генерирующий парные действия бана и разбана). Ту же задачу решает dhall, добавляя проверку типов: функции и импорты поверх JSON, но тотальные и типизированные. Напрямую reaction его не читает - придётся генерировать YAML.

Четыре основных элемента:

  • patterns - именованные типы захвата, например ip: { type: ipv4 }. Паттерн с именем ip указывается в регулярных выражениях как <ip>. Обратите внимание: это не привычный синтаксис групп захвата (...) со ссылками $1. reaction использует именованные токены <placeholder>, что удивило некоторых пользователей, но читается очень наглядно.
  • start / stop - списки команд, которые запускаются один раз при старте и остановке демона. Обычно они создают и удаляют цепочку файрвола, куда действия бана добавляют правила.
  • streams - у каждого потока есть cmd, выдающая построчный вывод (journalctl -fu sshd.service, tail -f или любой вывод в stdout), и набор фильтров (filters).
  • filters - каждый фильтр содержит список regex, счётчик retry, временное окно retryperiod и именованные действия (actions). Когда одно и то же захваченное значение (например, IP) совпадает retry раз за период retryperiod, фильтр запускает свои действия. Действие - это команда cmd; у действия может быть задержка after, чтобы демон запланировал его на потом - именно так unban срабатывает через 48h после ban.

Ожидающие отложенные действия (текущие баны) хранятся во встроенной дисковой базе данных в рабочей директории (путь можно переопределить через state_directory, рекомендуется /var/lib/reaction). Поскольку состояние сохраняется на диск, баны не сбрасываются при перезапуске.

Использование

Минимальная защита от перебора паролей по ssh, /etc/reaction.yml:

patterns:
  ip:
    type: ipv4

start:
  - [ 'iptables', '-w', '-N', 'reaction' ]
  - [ 'iptables', '-w', '-I', 'INPUT', '-p', 'all', '-j', 'reaction' ]

stop:
  - [ 'iptables', '-w', '-F', 'reaction' ]
  - [ 'iptables', '-w', '-X', 'reaction' ]

streams:
  ssh:
    cmd: [ 'journalctl', '-fu', 'sshd.service' ]
    filters:
      failedlogin:
        regex:
          - 'Failed password for .* from <ip>'
          - 'Invalid user .* from <ip>'
        retry: 3
        retryperiod: '6h'
        actions:
          ban:
            cmd: [ 'iptables', '-w', '-I', 'reaction', '1', '-s', '<ip>', '-j', 'DROP' ]
          unban:
            cmd: [ 'iptables', '-w', '-D', 'reaction', '1', '-s', '<ip>', '-j', 'DROP' ]
            after: '48h'

CLI утилиты минималистичен:

  • reaction start - запуск демона
  • reaction show - список ожидающих действий (текущих банов)
  • reaction flush - досрочное выполнение ожидающих действий (снятие банов)
  • reaction trigger - ручной запуск фильтра (ручной бан)
  • reaction test-regex - проверка регулярного выражения на тестовых данных
  • reaction test-config - вывод загруженной и разрешённой конфигурации

Документация рекомендует использовать nftables или ipset + iptables вместо чистого iptables, поскольку плоская цепочка iptables начинает тормозить, когда в ней накапливаются тысячи заблокированных адресов. В Linux это та же область контроля входящего трафика, что и в little-snitch-linux, но со стороны автоматической блокировки входящих соединений по логам, а не интерактивных запросов на исходящие подключения для каждого приложения.

Ограничения

  • Заточен под Linux: готовые бинарники и пакеты .deb доступны только для Linux (amd64 и arm64). OpenBSD поддерживается по инструкции в wiki, но полноценной поддержки macOS или Windows нет. Примеры по умолчанию рассчитаны на systemd/journald и iptables.
  • Пока нет внешнего аудита безопасности - об этом прямо написано в README. Для инструмента безопасности, который запускается от root и управляет правилами файрвола, это важно.
  • Меньше возможностей, чем у fail2ban. Это осознанный компромисс ради скорости и простоты настройки, но если вам критически необходима конкретная возможность fail2ban, проверьте её наличие заранее.
  • Один мейнтейнер (ppom). По отзывам пользователей, он оперативно отвечает в Matrix и получает финансирование от NLnet, но bus factor равен единице.
  • Старые вспомогательные утилиты ip46tables / nft46 были удалены во второй версии.

Заметки

В репозитории есть файл AGENTS.md - это не документация, а инструкция для кодинг-агентов на базе LLM. Файл декларирует запрет на вклад в код с помощью LLM (отчасти из-за лицензирования, отчасти из-за политических и экономических претензий мейнтейнера и сообщества к LLM-инструментам) и предписывает любому прочитавшему его агенту предупредить пользователя и отказаться помогать с кодом. Это полезно знать, прежде чем натравливать кодинг-агента на исходники: автор проекта против, а в качестве юридического основания приводится AGPL. На использование reaction в качестве готового развёрнутого инструмента это никак не влияет.

reaction находится в watchlist - единственный мейнтейнер, пока нет аудита безопасности, поддержка только Linux и ещё свежая версия v2, переписанная на Rust. При следующей проверке стоит посмотреть, появился ли аудит и остаётся ли проект активным.

vps-audit позволяет быстро проверить, слушает ли связка в духе fail2ban реальный порт SSH, независимо от того, какой именно демон блокировок используется.

Репозиторий

framagit.org/ppom/reaction - Rust (первая версия была на Golang, теперь устарела), AGPL-3.0, 65 звёзд / 36 форков на framagit по состоянию на июль 2026 года. Последняя активность: 2026-07-12. Размещён на self-hosted GitLab организации Framasoft, а не на GitHub.