nixos/routinator: init module

This commit is contained in:
Peter Lehmann 2025-02-07 09:21:45 +01:00
parent fd527aacc0
commit c468f4e261
No known key found for this signature in database
GPG Key ID: C141E17790DC45F7
6 changed files with 236 additions and 0 deletions

View File

@ -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).

View File

@ -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

View File

@ -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 <https://routinator.docs.nlnetlabs.nl/en/stable/manual-page.html#options> for options.";
'';
type = types.listOf types.str;
default = [ ];
example = [ "--no-rir-tals" ];
};
extraServerArgs = mkOption {
description = ''
Extra arguments passed to the server subcommand, see <https://routinator.docs.nlnetlabs.nl/en/stable/manual-page.html#subcmd-server> 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, <https://routinator.docs.nlnetlabs.nl/en/stable/manual-page.html#logging>
'';
default = "warn";
};
log = mkOption {
type = types.nullOr (
types.enum [
"default"
"stderr"
"syslog"
"file"
]
);
description = ''
A string specifying where to send log messages to.
See, <https://routinator.docs.nlnetlabs.nl/en/stable/manual-page.html#term-log>
'';
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 <https://routinator.docs.nlnetlabs.nl/en/stable/manual-page.html#configuration-file> 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 ];
}

View File

@ -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 {};

View File

@ -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}\" ]]")
'';
}

View File

@ -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;
};
}