Files
radicle-infra/os/module/iroh-relay.nix
T

167 lines
4.6 KiB
Nix

{
config,
lib,
pkgs,
...
}: let
cfg = config.services.iroh.relay;
settingsFormat = pkgs.formats.toml {};
configFile = settingsFormat.generate "iroh-relay.toml" cfg.settings;
in {
options.services.iroh.relay = {
enable = lib.mkEnableOption "iroh Relay";
package = lib.mkPackageOption pkgs "iroh-relay" {};
user = lib.mkOption {
type = lib.types.str;
default = "iroh";
description = "User under which iroh-relay runs.";
};
group = lib.mkOption {
type = lib.types.str;
default = "iroh";
description = "Group under which iroh-relay runs.";
};
domain = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "relay.example.org";
description = "Public hostname of the relay.";
};
settings = lib.mkOption {
type = settingsFormat.type;
default = {};
description = ''
Configuration written to `iroh-relay.toml`. See the upstream
`iroh-relay` configuration for supported values.
'';
};
nginx = {
enable = lib.mkEnableOption "nginx reverse-proxy for iroh-relay";
proxyPass = lib.mkOption {
type = lib.types.str;
default = "http://127.0.0.1:3340";
description = "URL to which nginx proxies relay HTTP and WebSocket traffic.";
};
};
};
config = lib.mkIf cfg.enable (lib.mkMerge [
{
services.iroh.relay.settings = {
http_bind_addr = lib.mkDefault (
if cfg.nginx.enable
then "127.0.0.1:3340"
else "[::]:3340"
);
enable_quic_addr_discovery = lib.mkDefault cfg.nginx.enable;
enable_metrics = lib.mkDefault true;
metrics_bind_addr = lib.mkDefault "127.0.0.1:9091";
};
users = {
users.${cfg.user} = {
isSystemUser = true;
group = cfg.group;
};
groups.${cfg.group} = {};
};
systemd.services.iroh-relay = {
description = "iroh Relay";
wantedBy = ["multi-user.target"];
wants = ["network-online.target"];
after = ["network-online.target"];
serviceConfig = {
Type = "simple";
ExecStart = "${lib.getExe cfg.package} --config-path ${configFile}";
Restart = "on-failure";
RestartSec = 5;
User = cfg.user;
Group = cfg.group;
RuntimeDirectory = "iroh-relay";
StateDirectory = "iroh-relay";
CapabilityBoundingSet = "";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateIPC = true;
PrivateTmp = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
RemoveIPC = true;
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallErrorNumber = "EPERM";
SystemCallFilter = ["@system-service"];
LimitNOFILE = 65536;
};
};
}
(lib.mkIf cfg.nginx.enable {
assertions = [
{
assertion = cfg.domain != null;
message = "services.iroh.relay.domain must be set when its nginx frontend is enabled";
}
];
services.iroh.relay.settings = {
tls = {
cert_mode = lib.mkDefault "Reloading";
manual_cert_path = lib.mkDefault "/var/lib/acme/${cfg.domain}/fullchain.pem";
manual_key_path = lib.mkDefault "/var/lib/acme/${cfg.domain}/key.pem";
dangerous_http_only = lib.mkDefault true;
quic_bind_addr = lib.mkDefault "[::]:7842";
};
};
users.users.${cfg.user}.extraGroups = [config.services.nginx.group];
systemd.services.iroh-relay = {
requires = ["acme-${cfg.domain}.service"];
after = ["acme-${cfg.domain}.service"];
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts.${cfg.domain} = {
enableACME = true;
forceSSL = true;
quic = true;
locations."/" = {
proxyPass = "http://127.0.0.1:3340";
proxyWebsockets = true;
extraConfig = ''
proxy_buffering off;
proxy_request_buffering off;
'';
};
};
};
})
]);
}