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.