1
0
Fork
You've already forked reaction
0
fork of https://framagit.org/ppom/reaction, not the official one !
  • Rust 72.5%
  • Go 18.4%
  • Jsonnet 3.5%
  • Python 3.2%
  • C 1.8%
  • Other 0.6%
2025年06月05日 12:00:00 +02:00
bench Update configuration 2025年05月31日 12:00:00 +02:00
config Document state_directory 2025年06月05日 12:00:00 +02:00
go.old Move old go codebase to go.old 2024年10月24日 12:00:00 +02:00
helpers_c Add small doc for C helpers 2025年06月05日 12:00:00 +02:00
logo NLnet statement 2025年06月01日 12:00:00 +02:00
packaging v2.0.0-rc2 release 2025年02月21日 12:00:00 +01:00
src Config: fix state_directory and concurrency merging 2025年05月28日 12:00:00 +02:00
tests Update configuration 2025年05月31日 12:00:00 +02:00
.ccls test infrastructure, new conf's state_directory, less deps 2024年11月13日 12:00:00 +01:00
.gitignore unit tests passing. handle_order in e2e tests panicing 2025年05月28日 12:00:00 +02:00
.gitlab-ci.yml 📦 👷 — Build better deb package in release.sh + test building in CI 2024年04月03日 16:16:53 +02:00
ARCHITECTURE.md rename waltree into treedb 2025年05月28日 12:00:00 +02:00
build.rs Fix spurious rebuild of reaction due to invalid file path 2024年11月14日 19:22:32 +01:00
Cargo.lock fix release 2025年06月05日 12:00:00 +02:00
Cargo.toml version 2.0.0 2025年06月05日 12:00:00 +02:00
LICENSE Add AGPL LICENSE 2023年04月11日 11:03:50 +00:00
Makefile Update ARCHITECTURE.md 2025年02月22日 12:00:00 +01:00
README.md NLnet statement 2025年06月01日 12:00:00 +02:00
release.py fix release 2025年06月05日 12:00:00 +02:00

reaction

A daemon that scans program outputs for repeated patterns, and takes action.

A common usage is to scan ssh and webserver logs, and to ban hosts that cause multiple authentication errors.

🚧 This program hasn't received external audit. however, it already works well on my servers 🚧

Current project status

reaction just reached v2.0.0-rc2 version, which is a complete rust rewrite of reaction. It's in feature parity with the Go version, and breaking changes should be small.

See https://reaction.ppom.me/migrate-to-v2.html

Rationale

I was using the honorable fail2ban since quite a long time, but i was a bit frustrated by its cpu consumption and all its heavy default configuration.

In my view, a security-oriented program should be simple to configure and an always-running daemon should be implemented in a faster language.

reaction does not have all the features of the honorable fail2ban, but it's ~10x faster and has more manageable configuration.

📽️ quick french name explanation 😉

🇬🇧 in-depth blog article / 🇫🇷 french version

Configuration

YAML and JSONnet (more powerful) are supported. both are extensions of JSON, so JSON is transitively supported.

/etc/reaction.yml
patterns:ip:regex:'(([0-9]{1,3}\.){3}[0-9]{1,3})|([0-9a-fA-F:]{2,90})'ignore:- '127.0.0.1'- '::1'start:- ['ip46tables','-w','-N','reaction']- ['ip46tables','-w','-I','INPUT','-p','all','-j','reaction']- ['ip46tables','-w','-I','FORWARD','-p','all','-j','reaction']stop:- ['ip46tables','-w','-D','INPUT','-p','all','-j','reaction']- ['ip46tables','-w','-D','FORWARD','-p','all','-j','reaction']- ['ip46tables','-w','-F','reaction']- ['ip46tables','-w','-X','reaction']streams:ssh:cmd:['journalctl','-fu','sshd.service']filters:failedlogin:regex:- 'authentication failure;.*rhost=<ip>'- 'Failed password for .* from <ip>'- 'Invalid user .* from <ip>',- 'banner exchange: Connection from <ip> port [0-9]*:invalid format',retry:3retryperiod:'6h'actions:ban:cmd:['ip46tables','-w','-I','reaction','1','-s','<ip>','-j','DROP']unban:cmd:['ip46tables','-w','-D','reaction','1','-s','<ip>','-j','DROP']after:'48h'
/etc/reaction.jsonnet
localiptables(args)=['ip46tables','-w']+args;localbanFor(time)={ban:{cmd:iptables(['-A','reaction','-s','<ip>','-j','DROP']),},unban:{after:time,cmd:iptables(['-D','reaction','-s','<ip>','-j','DROP']),},};{patterns:{ip:{regex:@'(?:(?:[ 0-9 ]{1,3}\.){3}[0-9]{1,3})|(?:[0-9a-fA-F:]{2,90})',},},start:[iptables(['-N','reaction']),iptables(['-I','INPUT','-p','all','-j','reaction']),iptables(['-I','FORWARD','-p','all','-j','reaction']),],stop:[iptables(['-D','INPUT','-p','all','-j','reaction']),iptables(['-D','FORWARD','-p','all','-j','reaction']),iptables(['-F','reaction']),iptables(['-X','reaction']),],streams:{ssh:{cmd:['journalctl','-fu','sshd.service'],filters:{failedlogin:{regex:[@'authentication failure;.*rhost=<ip>'@'Failed password for .* from <ip>',@'banner exchange: Connection from <ip> port [0-9]*: invalid format',@'Invalid user .* from <ip>',],retry:3,retryperiod:'6h',actions:banFor('48h'),},},},},}

Database

The embedded database is stored in the working directory (but can be overriden by the state_directory config option). If you don't know where to start reaction, /var/lib/reaction should be a sane choice.

CLI

  • reaction start runs the server
  • reaction show show pending actions (ie. bans)
  • reaction flush permits to run pending actions (ie. clear bans)
  • reaction test-regex permits to test regexes
  • reaction help for full usage.

ip46tables

ip46tables is a minimal c program present in its own subdirectory with only standard posix dependencies.

It permits to configure iptables and ip6tables at the same time. It will execute iptables when detecting ipv4, ip6tables when detecting ipv6 and both if no ip address is present on the command line.

Wiki

You'll find more ressources, service configurations, etc. on the wiki!

We recommend that you read the Good Practices chapters before starting.

Installation

Packaging status

Binaries

Executables and .deb packages are provided in the releases page, for x86-64/amd64 linux and aarch64/arm64 linux.

Signature verification and installation instructions are provided in the releases page.

Provided binaries are compiled by running nix-shell release.py on a NixOS machine with docker installed.

NixOS

reaction is packaged, but the module has not yet been upstreamed.

OpenBSD

See the wiki.

Compilation

You'll need a recent rust toolchain for reaction and a c compiler for ip46tables.

$ make

Don't hesitate to take a look at the Makefile to understand what's happening!

Installation

To install the binaries

make install

To install the systemd file as well

make install_systemd

Contributing

We, as participants in the open source ecosystem, are ethically responsible for the software and hardware we help create - as it can be used to perpetuate inequalities or help empower marginalized communities, and fight against patriarchy, capitalism, sexism, gender violence, racism, ableism, homophobia, colonialism, fascism, surveillance, and oppressive control.

I'll do my best to maintain a safe contribution place, as free as possible from discrimination and elitism. Your ideas are welcome in the issues. Contributions are welcome.

For any substantial feature, please file an issue first, to be assured that we agree on the feature, and to avoid unnecessary work.

I recommend reading ARCHITECTURE.md first. This is a quick tour of the codebase, which should save time to new contributors.

You can also join this Matrix development room: #reaction-dev-en:club1.fr. French version: #reaction-dev-fr:club1.fr.

Help

You can ask for help in the issues or in this Matrix room: #reaction-users-en:club1.fr. French version: #reaction-users-fr:club1.fr.

Funding

This project is currenlty funded through the NGI0 Core Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet programme.

NLnet logo