Files
2026-05-26 08:26:03 +05:30

109 lines
3.1 KiB
Nix

{
lib,
pkgs,
...
}:
{
name = "reaction";
nodes.server = _: {
services.reaction = {
enable = true;
stopForFirewall = false;
# example.jsonnet or 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" ];
};
users.users.nixos.isNormalUser = true; # neeeded to establish a ssh connection, by default root login is succeeding without any password
};
nodes.client = _: {
environment.systemPackages = [
pkgs.sshpass
pkgs.libressl.nc
];
};
testScript =
{ nodes, ... }: # py
''
start_all()
# Wait for everything to be ready.
server.wait_for_unit("multi-user.target")
server.wait_for_unit("reaction")
server.wait_for_unit("sshd")
client_addr = "${(lib.head nodes.client.networking.interfaces.eth1.ipv4.addresses).address}"
server_addr = "${(lib.head nodes.server.networking.interfaces.eth1.ipv4.addresses).address}"
# Verify there is not ban and the port is reachable from the client.
server.succeed(f"reaction show | grep -q {client_addr} || test $? -eq 1")
client.succeed(f"nc -w3 -z {server_addr} 22")
# Cause authentication failure log entries.
for _ in range(2):
client.fail(f"""
sshpass -p 'wrongpassword' \
ssh -o StrictHostKeyChecking=no \
-o User=nixos \
-o ServerAliveInterval=1 \
-o ServerAliveCountMax=2 \
{server_addr}
""")
# Verify there is a ban and the port is unreachable from the client.
server.sleep(2)
output = server.succeed("reaction show")
print(output)
assert client_addr in output, f"client did not get banned, {client_addr}"
client.fail(f"nc -w3 -z {server_addr} 22")
# Check that unbanning works
output = server.succeed("reaction flush")
print(output)
client.succeed(f"nc -w3 -z {server_addr} 22")
'';
# Debug interactively with:
# - nix run .#nixosTests.reaction.driverInteractive -L
# - run_tests()
interactive.sshBackdoor.enable = true;
interactive.nodes.server =
{ config, ... }:
{
# not needed, only for manual interactive debugging
virtualisation.memorySize = 4096;
virtualisation.graphics = false;
environment.systemPackages = with pkgs; [
btop
sysz
sshpass
libressl.nc
];
};
meta.maintainers =
with lib.maintainers;
[
ppom
]
++ lib.teams.ngi.members;
}