diff options
Diffstat (limited to 'nixpkgs/nixos/modules/services/networking')
13 files changed, 497 insertions, 22 deletions
diff --git a/nixpkgs/nixos/modules/services/networking/i2pd.nix b/nixpkgs/nixos/modules/services/networking/i2pd.nix index 0e9b354cfcaf..40478b85b75e 100644 --- a/nixpkgs/nixos/modules/services/networking/i2pd.nix +++ b/nixpkgs/nixos/modules/services/networking/i2pd.nix @@ -470,7 +470,7 @@ in ''; }; - trust.hidden = mkEnableOption "Router concealment."; + trust.hidden = mkEnableOption "Router concealment"; websocket = mkEndpointOpt "websockets" "127.0.0.1" 7666; @@ -478,7 +478,7 @@ in exploratory.outbound = i2cpOpts "exploratory"; ntcp2.enable = mkEnableTrueOption "NTCP2."; - ntcp2.published = mkEnableOption "NTCP2 publication."; + ntcp2.published = mkEnableOption "NTCP2 publication"; ntcp2.port = mkOption { type = types.int; default = 0; diff --git a/nixpkgs/nixos/modules/services/networking/miredo.nix b/nixpkgs/nixos/modules/services/networking/miredo.nix index 8694d08385ca..2c8393fb5b41 100644 --- a/nixpkgs/nixos/modules/services/networking/miredo.nix +++ b/nixpkgs/nixos/modules/services/networking/miredo.nix @@ -20,7 +20,7 @@ in services.miredo = { - enable = mkEnableOption "the Miredo IPv6 tunneling service."; + enable = mkEnableOption "the Miredo IPv6 tunneling service"; package = mkOption { type = types.package; diff --git a/nixpkgs/nixos/modules/services/networking/monero.nix b/nixpkgs/nixos/modules/services/networking/monero.nix index 8241c32bad07..831e4d60d8da 100644 --- a/nixpkgs/nixos/modules/services/networking/monero.nix +++ b/nixpkgs/nixos/modules/services/networking/monero.nix @@ -51,7 +51,7 @@ in services.monero = { - enable = mkEnableOption "Monero node daemon."; + enable = mkEnableOption "Monero node daemon"; mining.enable = mkOption { type = types.bool; diff --git a/nixpkgs/nixos/modules/services/networking/mosquitto.nix b/nixpkgs/nixos/modules/services/networking/mosquitto.nix index 9974cbd89d1e..1d49c137723c 100644 --- a/nixpkgs/nixos/modules/services/networking/mosquitto.nix +++ b/nixpkgs/nixos/modules/services/networking/mosquitto.nix @@ -44,7 +44,7 @@ in options = { services.mosquitto = { - enable = mkEnableOption "Enable the MQTT Mosquitto broker."; + enable = mkEnableOption "the MQTT Mosquitto broker"; host = mkOption { default = "127.0.0.1"; @@ -65,7 +65,7 @@ in }; ssl = { - enable = mkEnableOption "Enable SSL listener."; + enable = mkEnableOption "SSL listener"; cafile = mkOption { type = types.nullOr types.path; diff --git a/nixpkgs/nixos/modules/services/networking/mxisd.nix b/nixpkgs/nixos/modules/services/networking/mxisd.nix index 0aa6d0d9ecd3..0b9824f29fd7 100644 --- a/nixpkgs/nixos/modules/services/networking/mxisd.nix +++ b/nixpkgs/nixos/modules/services/networking/mxisd.nix @@ -116,7 +116,6 @@ in { Group = "mxisd"; ExecStart = "${cfg.package}/bin/mxisd --spring.config.location=${cfg.dataDir}/ --spring.profiles.active=systemd --java.security.egd=file:/dev/./urandom"; WorkingDirectory = cfg.dataDir; - PermissionsStartOnly = true; SuccessExitStatus = 143; Restart = "on-failure"; }; diff --git a/nixpkgs/nixos/modules/services/networking/namecoind.nix b/nixpkgs/nixos/modules/services/networking/namecoind.nix index 8de23b442f93..a569ca87e262 100644 --- a/nixpkgs/nixos/modules/services/networking/namecoind.nix +++ b/nixpkgs/nixos/modules/services/networking/namecoind.nix @@ -1,3 +1,4 @@ + { config, lib, pkgs, ... }: with lib; @@ -43,7 +44,7 @@ in services.namecoind = { - enable = mkEnableOption "namecoind, Namecoin client."; + enable = mkEnableOption "namecoind, Namecoin client"; wallet = mkOption { type = types.path; diff --git a/nixpkgs/nixos/modules/services/networking/nullidentdmod.nix b/nixpkgs/nixos/modules/services/networking/nullidentdmod.nix index 786b5227dbad..b0d338a27941 100644 --- a/nixpkgs/nixos/modules/services/networking/nullidentdmod.nix +++ b/nixpkgs/nixos/modules/services/networking/nullidentdmod.nix @@ -3,7 +3,7 @@ in { options.services.nullidentdmod = with types; { - enable = mkEnableOption "Enable the nullidentdmod identd daemon"; + enable = mkEnableOption "the nullidentdmod identd daemon"; userid = mkOption { type = nullOr str; diff --git a/nixpkgs/nixos/modules/services/networking/smokeping.nix b/nixpkgs/nixos/modules/services/networking/smokeping.nix index 9ba6e48f417c..fab3ed5bb39d 100644 --- a/nixpkgs/nixos/modules/services/networking/smokeping.nix +++ b/nixpkgs/nixos/modules/services/networking/smokeping.nix @@ -285,12 +285,12 @@ in uid = config.ids.uids.smokeping; description = "smokeping daemon user"; home = smokepingHome; + createHome = true; }; systemd.services.smokeping = { wantedBy = [ "multi-user.target"]; serviceConfig = { User = cfg.user; - PermissionsStartOnly = true; Restart = "on-failure"; }; preStart = '' @@ -300,7 +300,6 @@ in cp ${cgiHome} ${smokepingHome}/smokeping.fcgi ${cfg.package}/bin/smokeping --check --config=${configPath} ${cfg.package}/bin/smokeping --static --config=${configPath} - chown -R ${cfg.user} ${smokepingHome} ''; script = ''${cfg.package}/bin/smokeping --config=${configPath} --nodaemon''; }; diff --git a/nixpkgs/nixos/modules/services/networking/syncthing.nix b/nixpkgs/nixos/modules/services/networking/syncthing.nix index 702481ec5177..114a64dfb175 100644 --- a/nixpkgs/nixos/modules/services/networking/syncthing.nix +++ b/nixpkgs/nixos/modules/services/networking/syncthing.nix @@ -151,7 +151,6 @@ in { RestartForceExitStatus="3 4"; User = cfg.user; Group = cfg.group; - PermissionsStartOnly = true; ExecStart = '' ${cfg.package}/bin/syncthing \ -no-browser \ diff --git a/nixpkgs/nixos/modules/services/networking/tedicross.nix b/nixpkgs/nixos/modules/services/networking/tedicross.nix new file mode 100644 index 000000000000..0716975f594a --- /dev/null +++ b/nixpkgs/nixos/modules/services/networking/tedicross.nix @@ -0,0 +1,100 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + dataDir = "/var/lib/tedicross"; + cfg = config.services.tedicross; + configJSON = pkgs.writeText "tedicross-settings.json" (builtins.toJSON cfg.config); + configYAML = pkgs.runCommand "tedicross-settings.yaml" { preferLocalBuild = true; } '' + ${pkgs.remarshal}/bin/json2yaml -i ${configJSON} -o $out + ''; + +in { + options = { + services.tedicross = { + enable = mkEnableOption "the TediCross Telegram-Discord bridge service"; + + config = mkOption { + type = types.attrs; + # from https://github.com/TediCross/TediCross/blob/master/example.settings.yaml + example = literalExample '' + { + telegram = { + useFirstNameInsteadOfUsername = false; + colonAfterSenderName = false; + skipOldMessages = true; + sendEmojiWithStickers = true; + }; + discord = { + useNickname = false; + skipOldMessages = true; + displayTelegramReplies = "embed"; + replyLength = 100; + }; + bridges = [ + { + name = "Default bridge"; + direction = "both"; + telegram = { + chatId = -123456789; + relayJoinMessages = true; + relayLeaveMessages = true; + sendUsernames = true; + ignoreCommands = true; + }; + discord = { + serverId = "DISCORD_SERVER_ID"; + channelId = "DISCORD_CHANNEL_ID"; + relayJoinMessages = true; + relayLeaveMessages = true; + sendUsernames = true; + crossDeleteOnTelegram = true; + }; + } + ]; + + debug = false; + } + ''; + description = '' + <filename>settings.yaml</filename> configuration as a Nix attribute set. + Secret tokens should be specified using <option>environmentFile</option> + instead of this world-readable file. + ''; + }; + + environmentFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + File containing environment variables to be passed to the TediCross service, + in which secret tokens can be specified securely using the + <literal>TELEGRAM_BOT_TOKEN</literal> and <literal>DISCORD_BOT_TOKEN</literal> + keys. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + # from https://github.com/TediCross/TediCross/blob/master/guides/autostart/Linux.md + systemd.services.tedicross = { + description = "TediCross Telegram-Discord bridge service"; + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + serviceConfig = { + Type = "simple"; + ExecStart = "${pkgs.nodePackages.tedicross}/bin/tedicross --config='${configYAML}' --data-dir='${dataDir}'"; + Restart = "always"; + DynamicUser = true; + StateDirectory = baseNameOf dataDir; + EnvironmentFile = cfg.environmentFile; + }; + }; + }; + + meta.maintainers = with maintainers; [ pacien ]; +} + diff --git a/nixpkgs/nixos/modules/services/networking/toxvpn.nix b/nixpkgs/nixos/modules/services/networking/toxvpn.nix index b7655f4bec62..7830dfb1834c 100644 --- a/nixpkgs/nixos/modules/services/networking/toxvpn.nix +++ b/nixpkgs/nixos/modules/services/networking/toxvpn.nix @@ -5,7 +5,7 @@ with lib; { options = { services.toxvpn = { - enable = mkEnableOption "enable toxvpn running on startup"; + enable = mkEnableOption "toxvpn running on startup"; localip = mkOption { type = types.string; diff --git a/nixpkgs/nixos/modules/services/networking/wg-quick.nix b/nixpkgs/nixos/modules/services/networking/wg-quick.nix new file mode 100644 index 000000000000..b770d47d269e --- /dev/null +++ b/nixpkgs/nixos/modules/services/networking/wg-quick.nix @@ -0,0 +1,312 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.networking.wg-quick; + + kernel = config.boot.kernelPackages; + + # interface options + + interfaceOpts = { ... }: { + options = { + address = mkOption { + example = [ "192.168.2.1/24" ]; + default = []; + type = with types; listOf str; + description = "The IP addresses of the interface."; + }; + + dns = mkOption { + example = [ "192.168.2.2" ]; + default = []; + type = with types; listOf str; + description = "The IP addresses of DNS servers to configure."; + }; + + privateKey = mkOption { + example = "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk="; + type = with types; nullOr str; + default = null; + description = '' + Base64 private key generated by wg genkey. + + Warning: Consider using privateKeyFile instead if you do not + want to store the key in the world-readable Nix store. + ''; + }; + + privateKeyFile = mkOption { + example = "/private/wireguard_key"; + type = with types; nullOr str; + default = null; + description = '' + Private key file as generated by wg genkey. + ''; + }; + + listenPort = mkOption { + default = null; + type = with types; nullOr int; + example = 51820; + description = '' + 16-bit port for listening. Optional; if not specified, + automatically generated based on interface name. + ''; + }; + + preUp = mkOption { + example = literalExample '' + ${pkgs.iproute}/bin/ip netns add foo + ''; + default = ""; + type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines; + description = '' + Commands called at the start of the interface setup. + ''; + }; + + preDown = mkOption { + example = literalExample '' + ${pkgs.iproute}/bin/ip netns del foo + ''; + default = ""; + type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines; + description = '' + Command called before the interface is taken down. + ''; + }; + + postUp = mkOption { + example = literalExample '' + ${pkgs.iproute}/bin/ip netns add foo + ''; + default = ""; + type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines; + description = '' + Commands called after the interface setup. + ''; + }; + + postDown = mkOption { + example = literalExample '' + ${pkgs.iproute}/bin/ip netns del foo + ''; + default = ""; + type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines; + description = '' + Command called after the interface is taken down. + ''; + }; + + table = mkOption { + example = "main"; + default = null; + type = with types; nullOr str; + description = '' + The kernel routing table to add this interface's + associated routes to. Setting this is useful for e.g. policy routing + ("ip rule") or virtual routing and forwarding ("ip vrf"). Both numeric + table IDs and table names (/etc/rt_tables) can be used. Defaults to + "main". + ''; + }; + + mtu = mkOption { + example = 1248; + default = null; + type = with types; nullOr int; + description = '' + If not specified, the MTU is automatically determined + from the endpoint addresses or the system default route, which is usually + a sane choice. However, to manually specify an MTU to override this + automatic discovery, this value may be specified explicitly. + ''; + }; + + peers = mkOption { + default = []; + description = "Peers linked to the interface."; + type = with types; listOf (submodule peerOpts); + }; + }; + }; + + # peer options + + peerOpts = { + options = { + publicKey = mkOption { + example = "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg="; + type = types.str; + description = "The base64 public key the peer."; + }; + + presharedKey = mkOption { + default = null; + example = "rVXs/Ni9tu3oDBLS4hOyAUAa1qTWVA3loR8eL20os3I="; + type = with types; nullOr str; + description = '' + Base64 preshared key generated by wg genpsk. Optional, + and may be omitted. This option adds an additional layer of + symmetric-key cryptography to be mixed into the already existing + public-key cryptography, for post-quantum resistance. + + Warning: Consider using presharedKeyFile instead if you do not + want to store the key in the world-readable Nix store. + ''; + }; + + presharedKeyFile = mkOption { + default = null; + example = "/private/wireguard_psk"; + type = with types; nullOr str; + description = '' + File pointing to preshared key as generated by wg pensk. Optional, + and may be omitted. This option adds an additional layer of + symmetric-key cryptography to be mixed into the already existing + public-key cryptography, for post-quantum resistance. + ''; + }; + + allowedIPs = mkOption { + example = [ "10.192.122.3/32" "10.192.124.1/24" ]; + type = with types; listOf str; + description = ''List of IP (v4 or v6) addresses with CIDR masks from + which this peer is allowed to send incoming traffic and to which + outgoing traffic for this peer is directed. The catch-all 0.0.0.0/0 may + be specified for matching all IPv4 addresses, and ::/0 may be specified + for matching all IPv6 addresses.''; + }; + + endpoint = mkOption { + default = null; + example = "demo.wireguard.io:12913"; + type = with types; nullOr str; + description = ''Endpoint IP or hostname of the peer, followed by a colon, + and then a port number of the peer.''; + }; + + persistentKeepalive = mkOption { + default = null; + type = with types; nullOr int; + example = 25; + description = ''This is optional and is by default off, because most + users will not need it. It represents, in seconds, between 1 and 65535 + inclusive, how often to send an authenticated empty packet to the peer, + for the purpose of keeping a stateful firewall or NAT mapping valid + persistently. For example, if the interface very rarely sends traffic, + but it might at anytime receive traffic from a peer, and it is behind + NAT, the interface might benefit from having a persistent keepalive + interval of 25 seconds; however, most users will not need this.''; + }; + }; + }; + + writeScriptFile = name: text: ((pkgs.writeShellScriptBin name text) + "/bin/${name}"); + + generateUnit = name: values: + assert assertMsg ((values.privateKey != null) != (values.privateKeyFile != null)) "Only one of privateKey or privateKeyFile may be set"; + let + preUpFile = if values.preUp != "" then writeScriptFile "preUp.sh" values.preUp else null; + postUp = + optional (values.privateKeyFile != null) "wg set ${name} private-key <(cat ${values.privateKeyFile})" ++ + (concatMap (peer: optional (peer.presharedKeyFile != null) "wg set ${name} peer ${peer.publicKey} preshared-key <(cat ${peer.presharedKeyFile})") values.peers) ++ + optional (values.postUp != null) values.postUp; + postUpFile = if postUp != [] then writeScriptFile "postUp.sh" (concatMapStringsSep "\n" (line: line) postUp) else null; + preDownFile = if values.preDown != "" then writeScriptFile "preDown.sh" values.preDown else null; + postDownFile = if values.postDown != "" then writeScriptFile "postDown.sh" values.postDown else null; + configDir = pkgs.writeTextFile { + name = "config-${name}"; + executable = false; + destination = "/${name}.conf"; + text = + '' + [interface] + ${concatMapStringsSep "\n" (address: + "Address = ${address}" + ) values.address} + ${concatMapStringsSep "\n" (dns: + "DNS = ${dns}" + ) values.dns} + '' + + optionalString (values.table != null) "Table = ${values.table}\n" + + optionalString (values.mtu != null) "MTU = ${toString values.mtu}\n" + + optionalString (values.privateKey != null) "PrivateKey = ${values.privateKey}\n" + + optionalString (values.listenPort != null) "ListenPort = ${toString values.listenPort}\n" + + optionalString (preUpFile != null) "PreUp = ${preUpFile}\n" + + optionalString (postUpFile != null) "PostUp = ${postUpFile}\n" + + optionalString (preDownFile != null) "PreDown = ${preDownFile}\n" + + optionalString (postDownFile != null) "PostDown = ${postDownFile}\n" + + concatMapStringsSep "\n" (peer: + assert assertMsg (!((peer.presharedKeyFile != null) && (peer.presharedKey != null))) "Only one of presharedKey or presharedKeyFile may be set"; + "[Peer]\n" + + "PublicKey = ${peer.publicKey}\n" + + optionalString (peer.presharedKey != null) "PresharedKey = ${peer.presharedKey}\n" + + optionalString (peer.endpoint != null) "Endpoint = ${peer.endpoint}\n" + + optionalString (peer.persistentKeepalive != null) "PersistentKeepalive = ${toString peer.persistentKeepalive}\n" + + optionalString (peer.allowedIPs != []) "AllowedIPs = ${concatStringsSep "," peer.allowedIPs}\n" + ) values.peers; + }; + configPath = "${configDir}/${name}.conf"; + in + nameValuePair "wg-quick-${name}" + { + description = "wg-quick WireGuard Tunnel - ${name}"; + requires = [ "network-online.target" ]; + after = [ "network.target" "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + environment.DEVICE = name; + path = [ pkgs.kmod pkgs.wireguard-tools ]; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + + script = '' + ${optionalString (!config.boot.isContainer) "modprobe wireguard"} + wg-quick up ${configPath} + ''; + + preStop = '' + wg-quick down ${configPath} + ''; + }; +in { + + ###### interface + + options = { + networking.wg-quick = { + interfaces = mkOption { + description = "Wireguard interfaces."; + default = {}; + example = { + wg0 = { + address = [ "192.168.20.4/24" ]; + privateKey = "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk="; + peers = [ + { allowedIPs = [ "192.168.20.1/32" ]; + publicKey = "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg="; + endpoint = "demo.wireguard.io:12913"; } + ]; + }; + }; + type = with types; attrsOf (submodule interfaceOpts); + }; + }; + }; + + + ###### implementation + + config = mkIf (cfg.interfaces != {}) { + boot.extraModulePackages = [ kernel.wireguard ]; + environment.systemPackages = [ pkgs.wireguard-tools ]; + # This is forced to false for now because the default "--validmark" rpfilter we apply on reverse path filtering + # breaks the wg-quick routing because wireguard packets leave with a fwmark from wireguard. + networking.firewall.checkReversePath = false; + systemd.services = mapAttrs' generateUnit cfg.interfaces; + }; +} diff --git a/nixpkgs/nixos/modules/services/networking/wireguard.nix b/nixpkgs/nixos/modules/services/networking/wireguard.nix index 41aff1480a05..dd3cb1af2716 100644 --- a/nixpkgs/nixos/modules/services/networking/wireguard.nix +++ b/nixpkgs/nixos/modules/services/networking/wireguard.nix @@ -26,19 +26,28 @@ let type = with types; nullOr str; default = null; description = '' - Base64 private key generated by wg genkey. + Base64 private key generated by <command>wg genkey</command>. Warning: Consider using privateKeyFile instead if you do not want to store the key in the world-readable Nix store. ''; }; + generatePrivateKeyFile = mkOption { + default = false; + type = types.bool; + description = '' + Automatically generate a private key with + <command>wg genkey</command>, at the privateKeyFile location. + ''; + }; + privateKeyFile = mkOption { example = "/private/wireguard_key"; type = with types; nullOr str; default = null; description = '' - Private key file as generated by wg genkey. + Private key file as generated by <command>wg genkey</command>. ''; }; @@ -124,8 +133,8 @@ let example = "rVXs/Ni9tu3oDBLS4hOyAUAa1qTWVA3loR8eL20os3I="; type = with types; nullOr str; description = '' - Base64 preshared key generated by wg genpsk. Optional, - and may be omitted. This option adds an additional layer of + Base64 preshared key generated by <command>wg genpsk</command>. + Optional, and may be omitted. This option adds an additional layer of symmetric-key cryptography to be mixed into the already existing public-key cryptography, for post-quantum resistance. @@ -139,8 +148,8 @@ let example = "/private/wireguard_psk"; type = with types; nullOr str; description = '' - File pointing to preshared key as generated by wg pensk. Optional, - and may be omitted. This option adds an additional layer of + File pointing to preshared key as generated by <command>wg pensk</command>. + Optional, and may be omitted. This option adds an additional layer of symmetric-key cryptography to be mixed into the already existing public-key cryptography, for post-quantum resistance. ''; @@ -182,9 +191,48 @@ let }; - generateUnit = name: values: + + generatePathUnit = name: values: + assert (values.privateKey == null); + assert (values.privateKeyFile != null); + nameValuePair "wireguard-${name}" + { + description = "WireGuard Tunnel - ${name} - Private Key"; + requiredBy = [ "wireguard-${name}.service" ]; + before = [ "wireguard-${name}.service" ]; + pathConfig.PathExists = values.privateKeyFile; + }; + + generateKeyServiceUnit = name: values: + assert values.generatePrivateKeyFile; + nameValuePair "wireguard-${name}-key" + { + description = "WireGuard Tunnel - ${name} - Key Generator"; + wantedBy = [ "wireguard-${name}.service" ]; + requiredBy = [ "wireguard-${name}.service" ]; + before = [ "wireguard-${name}.service" ]; + path = with pkgs; [ wireguard ]; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + + script = '' + mkdir --mode 0644 -p "${dirOf values.privateKeyFile}" + if [ ! -f "${values.privateKeyFile}" ]; then + touch "${values.privateKeyFile}" + chmod 0600 "${values.privateKeyFile}" + wg genkey > "${values.privateKeyFile}" + chmod 0400 "${values.privateKeyFile}" + fi + ''; + }; + + + generateSetupServiceUnit = name: values: # exactly one way to specify the private key must be set - assert (values.privateKey != null) != (values.privateKeyFile != null); + #assert (values.privateKey != null) != (values.privateKeyFile != null); let privKey = if values.privateKeyFile != null then values.privateKeyFile else pkgs.writeText "wg-key" values.privateKey; in nameValuePair "wireguard-${name}" @@ -279,10 +327,27 @@ in config = mkIf (cfg.interfaces != {}) { + assertions = (attrValues ( + mapAttrs (name: value: { + assertion = (value.privateKey != null) != (value.privateKeyFile != null); + message = "Either networking.wireguard.interfaces.${name}.privateKey or networking.wireguard.interfaces.${name}.privateKeyFile must be set."; + }) cfg.interfaces)) + ++ (attrValues ( + mapAttrs (name: value: { + assertion = value.generatePrivateKeyFile -> (value.privateKey == null); + message = "networking.wireguard.interfaces.${name}.generatePrivateKey must not be set if networking.wireguard.interfaces.${name}.privateKey is set."; + }) cfg.interfaces)); + + boot.extraModulePackages = [ kernel.wireguard ]; environment.systemPackages = [ pkgs.wireguard-tools ]; - systemd.services = mapAttrs' generateUnit cfg.interfaces; + systemd.services = (mapAttrs' generateSetupServiceUnit cfg.interfaces) + // (mapAttrs' generateKeyServiceUnit + (filterAttrs (name: value: value.generatePrivateKeyFile) cfg.interfaces)); + + systemd.paths = mapAttrs' generatePathUnit + (filterAttrs (name: value: value.privateKeyFile != null) cfg.interfaces); }; |