diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 9ccb6dd205e4..7327d4ac4dfd 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -620,6 +620,7 @@ ./services/networking/supplicant.nix ./services/networking/supybot.nix ./services/networking/syncthing.nix + ./services/networking/syncthing-relay.nix ./services/networking/tcpcrypt.nix ./services/networking/teamspeak3.nix ./services/networking/tinc.nix diff --git a/nixos/modules/services/networking/syncthing-relay.nix b/nixos/modules/services/networking/syncthing-relay.nix new file mode 100644 index 000000000000..f5ca63e78930 --- /dev/null +++ b/nixos/modules/services/networking/syncthing-relay.nix @@ -0,0 +1,121 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.syncthing.relay; + + dataDirectory = "/var/lib/syncthing-relay"; + + relayOptions = + [ + "--keys=${dataDirectory}" + "--listen=${cfg.listenAddress}:${toString cfg.port}" + "--status-srv=${cfg.statusListenAddress}:${toString cfg.statusPort}" + "--provided-by=${escapeShellArg cfg.providedBy}" + ] + ++ optional (cfg.pools != null) "--pools=${escapeShellArg (concatStringsSep "," cfg.pools)}" + ++ optional (cfg.globalRateBps != null) "--global-rate=${toString cfg.globalRateBps}" + ++ optional (cfg.perSessionRateBps != null) "--per-session-rate=${toString cfg.perSessionRateBps}" + ++ cfg.extraOptions; +in { + ###### interface + + options.services.syncthing.relay = { + enable = mkEnableOption "Syncthing relay service"; + + listenAddress = mkOption { + type = types.str; + default = ""; + example = "1.2.3.4"; + description = '' + Address to listen on for relay traffic. + ''; + }; + + port = mkOption { + type = types.port; + default = 22067; + description = '' + Port to listen on for relay traffic. This port should be added to + networking.firewall.allowedTCPPorts. + ''; + }; + + statusListenAddress = mkOption { + type = types.str; + default = ""; + example = "1.2.3.4"; + description = '' + Address to listen on for serving the relay status API. + ''; + }; + + statusPort = mkOption { + type = types.port; + default = 22070; + description = '' + Port to listen on for serving the relay status API. This port should be + added to networking.firewall.allowedTCPPorts. + ''; + }; + + pools = mkOption { + type = types.nullOr (types.listOf types.str); + default = null; + description = '' + Relay pools to join. If null, uses the default global pool. + ''; + }; + + providedBy = mkOption { + type = types.str; + default = ""; + description = '' + Human-readable description of the provider of the relay (you). + ''; + }; + + globalRateBps = mkOption { + type = types.nullOr types.ints.positive; + default = null; + description = '' + Global bandwidth rate limit in bytes per second. + ''; + }; + + perSessionRateBps = mkOption { + type = types.nullOr types.ints.positive; + default = null; + description = '' + Per session bandwidth rate limit in bytes per second. + ''; + }; + + extraOptions = mkOption { + type = types.listOf types.str; + default = []; + description = '' + Extra command line arguments to pass to strelaysrv. + ''; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + systemd.services.syncthing-relay = { + description = "Syncthing relay service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + DynamicUser = true; + StateDirectory = baseNameOf dataDirectory; + + Restart = "on-failure"; + ExecStart = "${pkgs.syncthing-relay}/bin/strelaysrv ${concatStringsSep " " relayOptions}"; + }; + }; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index ec7178ec9cad..0d5a747b5c56 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -193,6 +193,7 @@ in strongswan-swanctl = handleTest ./strongswan-swanctl.nix {}; sudo = handleTest ./sudo.nix {}; switchTest = handleTest ./switch-test.nix {}; + syncthing-relay = handleTest ./syncthing-relay.nix {}; systemd = handleTest ./systemd.nix {}; taskserver = handleTest ./taskserver.nix {}; tomcat = handleTest ./tomcat.nix {}; diff --git a/nixos/tests/syncthing-relay.nix b/nixos/tests/syncthing-relay.nix new file mode 100644 index 000000000000..f1ceb4993337 --- /dev/null +++ b/nixos/tests/syncthing-relay.nix @@ -0,0 +1,22 @@ +import ./make-test.nix ({ lib, pkgs, ... }: { + name = "syncthing-relay"; + meta.maintainers = with pkgs.stdenv.lib.maintainers; [ delroth ]; + + machine = { + environment.systemPackages = [ pkgs.jq ]; + services.syncthing.relay = { + enable = true; + providedBy = "nixos-test"; + pools = []; # Don't connect to any pool while testing. + port = 12345; + statusPort = 12346; + }; + }; + + testScript = '' + $machine->waitForUnit("syncthing-relay.service"); + $machine->waitForOpenPort(12345); + $machine->waitForOpenPort(12346); + $machine->succeed("curl http://localhost:12346/status | jq -r '.options.\"provided-by\"'") =~ /nixos-test/ or die; + ''; +})