Reaction

Daemon that scans program outputs for repeated patterns, and takes action

Declared in: projects/Reaction/default.nix

Try the service in a VM

  1. 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
  2. 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).
        };
      }
    )
    
  3. 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='
  4. 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
  5. Usage Instructions
    1. 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.

    2. Run the demo vm, it runs an ssh server at port 10022, a user nixos with password nixos exists.

      Run watch journalctl -u reaction --no-pager inside the demo vm.

    3. Open a new terminal in your host system and run try this ssh command thrice.

      ssh -p 10022 nixos@localhost -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null

      Attempt login to the demo vm with wrong passwords twice.

    4. Go back to the demo vm terminal, and notice that you've been banned in the last line.

Examples

non-root
{ pkgs, ... }:
{
  config = {
    services.reaction = {
      enable = true;
      stopForFirewall = false;
      # 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

This project is funded by NLnet through these subgrants:

Core
Reaction

Related links: