diff --git a/nixos/doc/manual/release-notes/rl-2505.section.md b/nixos/doc/manual/release-notes/rl-2505.section.md index d5ca4a555459..fc987ec35fbe 100644 --- a/nixos/doc/manual/release-notes/rl-2505.section.md +++ b/nixos/doc/manual/release-notes/rl-2505.section.md @@ -79,6 +79,8 @@ - [networking.modemmanager](options.html#opt-networking.modemmanager) has been split out of [networking.networkmanager](options.html#opt-networking.networkmanager). NetworkManager still enables ModemManager by default, but options exist now to run NetworkManager without ModemManager. +- [Routinator 3000](https://nlnetlabs.nl/projects/routing/routinator/), a full-featured RPKI Relying Party software package that runs as a service which periodically downloads and verifies RPKI data. + - [doh-server](https://github.com/m13253/dns-over-https), a high performance DNS over HTTPS server. Available as [services.doh-server](options.html#opt-services.doh-server.enable). - [ncps](https://github.com/kalbasit/ncps), a Nix binary cache proxy service implemented in Go using [go-nix](https://github.com/nix-community/go-nix). Available as [services.ncps](options.html#opt-services.ncps.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index e09380faa6df..e3e22d80204d 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1242,6 +1242,7 @@ ./services/networking/robustirc-bridge.nix ./services/networking/rosenpass.nix ./services/networking/routedns.nix + ./services/networking/routinator.nix ./services/networking/rpcbind.nix ./services/networking/rxe.nix ./services/networking/sabnzbd.nix diff --git a/nixos/modules/services/networking/routinator.nix b/nixos/modules/services/networking/routinator.nix new file mode 100644 index 000000000000..6e693b0cd8e8 --- /dev/null +++ b/nixos/modules/services/networking/routinator.nix @@ -0,0 +1,192 @@ +{ + config, + lib, + pkgs, + utils, + ... +}: +let + inherit (lib) + filterAttrsRecursive + getExe + maintainers + mkEnableOption + mkPackageOption + mkOption + types + ; + inherit (utils) escapeSystemdExecArgs; + cfg = config.services.routinator; + settingsFormat = pkgs.formats.toml { }; +in +{ + options.services.routinator = { + enable = mkEnableOption "Routinator 3000"; + + package = mkPackageOption pkgs "routinator" { }; + + extraArgs = mkOption { + description = '' + Extra arguments passed to routinator, see for options."; + ''; + type = types.listOf types.str; + default = [ ]; + example = [ "--no-rir-tals" ]; + }; + + extraServerArgs = mkOption { + description = '' + Extra arguments passed to the server subcommand, see for options."; + ''; + type = types.listOf types.str; + default = [ ]; + example = [ "--rtr-client-metrics" ]; + }; + + settings = mkOption { + type = types.submodule { + freeformType = settingsFormat.type; + options = { + repository-dir = mkOption { + type = types.path; + description = '' + The path where the collected RPKI data is stored. + ''; + default = "/var/lib/routinator/rpki-cache"; + }; + log-level = mkOption { + type = types.nullOr ( + types.enum [ + "error" + "warn" + "info" + "debug" + ] + ); + description = '' + A string value specifying the maximum log level for which log messages should be emitted. + See, + ''; + default = "warn"; + }; + log = mkOption { + type = types.nullOr ( + types.enum [ + "default" + "stderr" + "syslog" + "file" + ] + ); + description = '' + A string specifying where to send log messages to. + See, + ''; + default = "default"; + }; + log-file = mkOption { + type = types.nullOr types.path; + description = '' + A string value containing the path to a file to which log messages will be appended if the log configuration value is set to file. In this case, the value is mandatory. + ''; + default = null; + }; + http-listen = mkOption { + type = types.nullOr (types.listOf types.str); + description = '' + An array of string values each providing an address and port on which the HTTP server should listen. Address and port should be separated by a colon. IPv6 address should be enclosed in square brackets. + ''; + default = null; + }; + rtr-listen = mkOption { + type = types.nullOr (types.listOf types.str); + description = '' + An array of string values each providing an address and port on which the RTR server should listen in TCP mode. Address and port should be separated by a colon. IPv6 address should be enclosed in square brackets. + ''; + default = null; + }; + refresh = mkOption { + type = types.nullOr types.int; + description = '' + An integer value specifying the number of seconds Routinator should wait between consecutive validation runs in server mode. The next validation run will happen earlier, if objects expire earlier. + ''; + default = 600; + }; + retry = mkOption { + type = types.nullOr types.int; + description = '' + An integer value specifying the number of seconds an RTR client is requested to wait after it failed to receive a data set. + ''; + default = 600; + }; + expire = mkOption { + type = types.nullOr types.int; + description = '' + An integer value specifying the number of seconds an RTR client is requested to use a data set if it cannot get an update before throwing it away and continuing with no data at all. + ''; + default = 7200; + }; + }; + }; + description = '' + Configuration for Routinator 3000, see for options. + ''; + default = { }; + }; + }; + + config = { + systemd.services.routinator = { + description = "Routinator 3000 is free, open-source RPKI Relying Party software made by NLnet Labs."; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + path = with pkgs; [ rsync ]; + serviceConfig = { + Type = "exec"; + ExecStart = escapeSystemdExecArgs ( + [ + (getExe cfg.package) + "--config=${ + settingsFormat.generate "routinator.conf" (filterAttrsRecursive (n: v: v != null) cfg.settings) + }" + ] + ++ cfg.extraArgs + ++ [ + "server" + ] + ++ cfg.extraServerArgs + ); + Restart = "on-failure"; + CapabilityBoundingSet = [ "" ]; + DynamicUser = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "strict"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_UNIX" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + StateDirectory = "routinator"; + SystemCallArchitectures = "native"; + SystemCallErrorNumber = "EPERM"; + SystemCallFilter = "@system-service"; + UMask = "0027"; + }; + }; + }; + + meta.maintainers = with maintainers; [ xgwq ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 24d6e0725f2a..5cb8d695f4be 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -918,6 +918,7 @@ in { rmfakecloud = runTest ./rmfakecloud.nix; robustirc-bridge = handleTest ./robustirc-bridge.nix {}; roundcube = handleTest ./roundcube.nix {}; + routinator = handleTest ./routinator.nix {}; rosenpass = handleTest ./rosenpass.nix {}; rshim = handleTest ./rshim.nix {}; rspamd = handleTest ./rspamd.nix {}; diff --git a/nixos/tests/routinator.nix b/nixos/tests/routinator.nix new file mode 100644 index 000000000000..8a4263feb67b --- /dev/null +++ b/nixos/tests/routinator.nix @@ -0,0 +1,35 @@ +{ + system ? builtins.currentSystem, + pkgs ? import ../.. { + inherit system; + config = { }; + }, +}: + +let + inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest; +in +makeTest { + name = "routinator"; + + nodes.server = + { pkgs, ... }: + { + services.routinator = { + enable = true; + extraArgs = [ "--no-rir-tals" ]; + settings = { + http-listen = [ "[::]:8382" ]; + }; + }; + }; + + testScript = '' + start_all() + + server.wait_for_unit("routinator.service") + + with subtest("Check if routinator reports the correct version"): + server.wait_until_succeeds("[[ \"$(curl http://localhost:8382/version)\" = \"${pkgs.routinator.version}\" ]]") + ''; +} diff --git a/pkgs/by-name/ro/routinator/package.nix b/pkgs/by-name/ro/routinator/package.nix index 89decd1e2ef3..2cf8999f657a 100644 --- a/pkgs/by-name/ro/routinator/package.nix +++ b/pkgs/by-name/ro/routinator/package.nix @@ -4,6 +4,7 @@ fetchFromGitHub, stdenv, darwin, + nixosTests, }: rustPlatform.buildRustPackage rec { @@ -36,4 +37,8 @@ rustPlatform.buildRustPackage rec { maintainers = with maintainers; [ _0x4A6F ]; mainProgram = "routinator"; }; + + passthru.tests = { + basic-functioniality = nixosTests.routinator; + }; }