Reaction
Daemon that scans program outputs for repeated patterns, and takes action
Declared in: projects/Reaction/default.nix
Try the service in a VM
-
Install Nix
- Bash
-
$ apt install --yes curl git jq nix
- Bash
-
$ apt install --yes curl git jq nix
- Bash
-
$ pacman --sync --refresh --noconfirm curl git jq nix
-
Download a configuration file
# default.nix { ngipkgs ? import (fetchTarball "https://github.com/ngi-nix/ngipkgs/tarball/main") { }, }: ngipkgs.demo-vm ( { pkgs, ... }: { services.reaction = { enable = true; settingsFiles = [ ./example-ssh.jsonnet ]; # Prefer `runAsRoot` to `false` in a production deployment, this is just for the demo runAsRoot = true; # and give the reaction user and service the proper permissions (see the non-root example, below). }; } )
-
Enable binary substituters
- Bash
-
$ export NIX_CONFIG='substituters = https://cache.nixos.org/ https://ngi.cachix.org/ trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= ngi.cachix.org-1:n+CAL72ROC3qQuLxIHpV+Tw5t42WhXmMhprAGkRSrOw='
-
Build and run a virtual machine
- Bash
-
$ nix-build ./default.nix && ./result
- Bash
-
$ nix-build ./default.nix && ./result
- Bash
-
$ rev=$(nix-instantiate --eval --attr sources.nixpkgs.rev https://github.com/ngi-nix/ngipkgs/archive/master.tar.gz | jq --raw-output)$ nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/$rev.tar.gz --packages nix --run "nix-build ./default.nix && ./result"
- Bash
-
$ nix-build ./default.nix && ./result
-
Usage Instructions
-
Reaction is a very powerful rules based engine.
A common usecase is to scan ssh and webserver logs, and to ban hosts that cause multiple authentication errors.
Provide a configuration file for reaction, for example:
example.jsonnet. -
Run the demo vm, it runs an ssh server at port 10022, a user
nixoswith passwordnixosexists.Run
journalctl -finside the demo vm. -
Open a new terminal in your host system and run this ssh command:
ssh -p 10022 nixos@localhost -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/nullAttempt login to the demo vm with wrong passwords thrice.
-
Go back to the demo vm terminal, and notice that you've been banned in the last line.
-
To unban yourself, go to the vm terminal and run:
sudo reaction flush -
Attempt to login with the correct password.
-
Options
services.reaction
-
Check the syntax of the configuration files at build time
- Type:
boolean- Default:
true- Declared in:
- nixos/modules/services/security/reaction.nix
-
Whether to enable enable reaction.
- Type:
boolean- Default:
false- Declared in:
- nixos/modules/services/security/reaction.nix
-
reaction's loglevel. One of DEBUG, INFO, WARN, ERROR.
- Type:
null or one of "DEBUG", "INFO", "WARN", "ERROR"- Default:
null- Declared in:
- nixos/modules/services/security/reaction.nix
-
The reaction package to use.
- Type:
package- Default:
pkgs.reaction- Declared in:
- nixos/modules/services/security/reaction.nix
-
Whether to run reaction as root. Defaults to false, where an unprivileged reaction user is created.
Be sure to give it sufficient permissions. Example config permitting
iptablesandjournalctluse{ # allows reading journal logs of processess users.users.reaction.extraGroups = [ "systemd-journal" ]; # allows modifying ip firewall rules systemd.services.reaction.unitConfig.ConditionCapability = "CAP_NET_ADMIN"; systemd.services.reaction.serviceConfig = { CapabilityBoundingSet = [ "CAP_NET_ADMIN" ]; AmbientCapabilities = [ "CAP_NET_ADMIN" ]; }; # optional, if more control over ssh logs is needed services.openssh.settings.LogLevel = lib.mkDefault "VERBOSE"; }- Type:
boolean- Default:
false- Declared in:
- nixos/modules/services/security/reaction.nix
-
Configuration for reaction. See the wiki.
The settings are written as a YAML file.
Can be used in combination with
settingsFilesoption, both will be present in the configuration directory.- Type:
open submodule of (YAML 1.1 value)- Default:
{ }- Declared in:
- nixos/modules/services/security/reaction.nix
-
Configuration for reaction, see the wiki.
reaction supports JSON, YAML and JSONnet. For those who prefer to take advantage of JSONnet rather than Nix.
Can be used in combination with
settingsoption, both will be present in the configuration directory.- Type:
list of absolute path- Default:
[ ]- Declared in:
- nixos/modules/services/security/reaction.nix
-
Whether to stop reaction when reloading the firewall.
The presence of a reaction chain in the INPUT table may cause the firewall reload to fail. One can alternatively cherry-pick the right iptables commands to execute before and after the firewall
{ systemd.services.firewall.serviceConfig = { ExecStopPre = [ "${pkgs.iptables}/bin/iptables -w -D INPUT -p all -j reaction" ]; ExecStartPost = [ "${pkgs.iptables}/bin/iptables -w -I INPUT -p all -j reaction" ]; }; }- Type:
boolean- Default:
false- Declared in:
- nixos/modules/services/security/reaction.nix
services.reaction.checkConfig
services.reaction.enable
services.reaction.loglevel
services.reaction.package
services.reaction.runAsRoot
services.reaction.settings
services.reaction.settingsFiles
services.reaction.stopForFirewall
Examples
non-root
{ pkgs, ... }: { config = { services.reaction = { enable = true; stopForFirewall = true; # example.jsonnet/example.yml can be copied and modified from ${pkgs.reaction}/share/examples settingsFiles = [ "${pkgs.reaction}/share/examples/example.jsonnet" ]; runAsRoot = false; }; services.openssh.enable = true; # If not running as root you need to give the reaction user and service the proper permissions # allows reading journal logs of processess users.users.reaction.extraGroups = [ "systemd-journal" ]; # allows modifying ip firewall rules systemd.services.reaction.unitConfig.ConditionCapability = "CAP_NET_ADMIN"; systemd.services.reaction.serviceConfig = { CapabilityBoundingSet = [ "CAP_NET_ADMIN" ]; AmbientCapabilities = [ "CAP_NET_ADMIN" ]; }; }; }
Declared in: projects/Reaction/services/reaction/examples/non-root.nix
root
{ pkgs, ... }: { config = { services.reaction = { enable = true; stopForFirewall = true; # with this enabled restarting firewall will restart reaction settingsFiles = [ # supports jsonnet as well as yml config formats "${pkgs.reaction}/share/examples/example.jsonnet" # "${pkgs.reaction}/share/examples/example.yml" ]; runAsRoot = true; }; networking.firewall.enable = true; }; }
Declared in: projects/Reaction/services/reaction/examples/root.nix
Metadata
This project is funded by NLnet through these subgrants:
- Core
- Reaction
Related links: