From 2656cbf2a91f1f350e29e2ee2faa0bbe90f9b717 Mon Sep 17 00:00:00 2001 From: tv Date: Wed, 22 Dec 2021 23:27:07 +0100 Subject: [PATCH 01/10] empty -> emptyDirectory --- krebs/3modules/git.nix | 4 ++-- krebs/5pkgs/simple/empty.nix | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 krebs/5pkgs/simple/empty.nix diff --git a/krebs/3modules/git.nix b/krebs/3modules/git.nix index 1bfd58e31..c038fd4c6 100644 --- a/krebs/3modules/git.nix +++ b/krebs/3modules/git.nix @@ -36,7 +36,7 @@ let type = types.user; default = { name = "fcgiwrap"; - home = toString pkgs.empty; + home = toString pkgs.emptyDirectory; }; }; }; @@ -111,7 +111,7 @@ let type = types.user; default = { name = "git"; - home = toString pkgs.empty; + home = toString pkgs.emptyDirectory; }; }; }; diff --git a/krebs/5pkgs/simple/empty.nix b/krebs/5pkgs/simple/empty.nix deleted file mode 100644 index a45723b65..000000000 --- a/krebs/5pkgs/simple/empty.nix +++ /dev/null @@ -1,2 +0,0 @@ -{ pkgs }: -pkgs.runCommand "empty-1.0.0" {} "mkdir $out" From 9d65a3cdd8d73fd92418ef317b671bd14d105141 Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 23 Dec 2021 00:46:12 +0100 Subject: [PATCH 02/10] lib: add maybeHead --- lib/default.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/default.nix b/lib/default.nix index 738e52186..574713e48 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -39,6 +39,8 @@ let listToAttrs (map (name: nameValuePair name set.${name}) (filter (flip hasAttr set) names)); + maybeHead = x: if isList x && length x > 0 then head x else null; + packageName = pkg: pkg.pname or (parseDrvName pkg.name).name; From d6ebd497f09ed8994594a32f8848d218beea93a3 Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 23 Dec 2021 01:10:22 +0100 Subject: [PATCH 03/10] krebs.systemd.services: restart by LoadCredential --- krebs/3modules/default.nix | 1 + krebs/3modules/systemd.nix | 51 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 krebs/3modules/systemd.nix diff --git a/krebs/3modules/default.nix b/krebs/3modules/default.nix index 2772d8d37..f76d3c536 100644 --- a/krebs/3modules/default.nix +++ b/krebs/3modules/default.nix @@ -50,6 +50,7 @@ let ./shadow.nix ./ssl.nix ./sync-containers.nix + ./systemd.nix ./tinc.nix ./tinc_graphs.nix ./upstream diff --git a/krebs/3modules/systemd.nix b/krebs/3modules/systemd.nix new file mode 100644 index 000000000..c30b2264a --- /dev/null +++ b/krebs/3modules/systemd.nix @@ -0,0 +1,51 @@ +{ config, options, pkgs, ... }: let { + lib = import ../../lib; + + body.options.krebs.systemd.services = lib.mkOption { + default = {}; + type = lib.types.attrs; + description = '' + Definition of systemd service units with bonus features. + + Services defined using this option will be restarted whenever any file + (described by an absolute path) used in LoadCredential changes. + ''; + }; + + body.config.systemd = + lib.mkMerge + (lib.flatten + (lib.mapAttrsToList (serviceName: cfg: let + prefix = [ "krebs" "systemd" "services" serviceName ]; + opts = options.systemd.services.type.getSubOptions prefix; + + paths = + lib.filter + lib.types.absolute-pathname.check + (map + (lib.compose [ lib.maybeHead (lib.match "[^:]*:(.*)") ]) + (cfg.serviceConfig.LoadCredential or [])); + in + lib.singleton { + services.${serviceName} = cfg; + } + ++ + lib.optionals (cfg.enable or opts.enable.default) (map (path: let + triggerName = "trigger-${lib.systemd.encodeName path}"; + in { + paths.${triggerName} = { + wantedBy = ["multi-user.target"]; + pathConfig.PathChanged = path; + }; + services.${triggerName} = { + serviceConfig = { + Type = "oneshot"; + ExecStart = lib.singleton (toString [ + "${pkgs.systemd}/bin/systemctl restart" + (lib.shell.escape serviceName) + ]); + }; + }; + }) paths) + ) config.krebs.systemd.services)); +} From 21e407aa593c4ead51b44b0b993093f32cbdd852 Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 23 Dec 2021 01:12:38 +0100 Subject: [PATCH 04/10] krebs.tinc: use LoadCredential --- krebs/3modules/tinc.nix | 77 +++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 50 deletions(-) diff --git a/krebs/3modules/tinc.nix b/krebs/3modules/tinc.nix index 3d0cc8fb4..a0fc39e6f 100644 --- a/krebs/3modules/tinc.nix +++ b/krebs/3modules/tinc.nix @@ -28,10 +28,6 @@ let Interface = ${netname} Broadcast = no ${concatMapStrings (c: "ConnectTo = ${c}\n") tinc.config.connectTo} - ${optionalString (tinc.config.privkey_ed25519 != null) - "Ed25519PrivateKeyFile = ${tinc.config.privkey_ed25519.path}" - } - PrivateKeyFile = ${tinc.config.privkey.path} Port = ${toString tinc.config.host.nets.${netname}.tinc.port} ${tinc.config.extraConfig} ''; @@ -169,25 +165,17 @@ let }; privkey = mkOption { - type = types.secret-file; - default = { - name = "${tinc.config.netname}.rsa_key.priv"; - path = "${tinc.config.user.home}/tinc.rsa_key.priv"; - owner = tinc.config.user; - source-path = toString + "/${tinc.config.netname}.rsa_key.priv"; - }; + type = types.absolute-pathname; + default = toString + "/${tinc.config.netname}.rsa_key.priv"; defaultText = "‹secrets/‹netname›.rsa_key.priv›"; }; privkey_ed25519 = mkOption { - type = types.nullOr types.secret-file; + type = types.nullOr types.absolute-pathname; default = - if config.krebs.hosts.${tinc.config.host.name}.nets.${tinc.config.netname}.tinc.pubkey_ed25519 == null then null else { - name = "${tinc.config.netname}.ed25519_key.priv"; - path = "${tinc.config.user.home}/tinc.ed25519_key.priv"; - owner = tinc.config.user; - source-path = toString + "/${tinc.config.netname}.ed25519_key.priv"; - }; + if tinc.config.host.nets.${netname}.tinc.pubkey_ed25519 == null + then null + else toString + "/${tinc.config.netname}.ed25519_key.priv"; defaultText = "‹secrets/‹netname›.ed25519_key.priv›"; }; @@ -230,24 +218,6 @@ let # TODO `environment.systemPackages = [ cfg.tincPackage cfg.iproutePackage ]` for each network, # avoid conflicts in environment if the packages differ - krebs.secret.files = - let - ed25519_keys = - filterAttrs - (_: key: key != null) - (mapAttrs' - (netname: cfg: - nameValuePair "${netname}.ed25519_key.priv" cfg.privkey_ed25519 - ) - config.krebs.tinc); - - rsa_keys = - mapAttrs' - (netname: cfg: nameValuePair "${netname}.rsa_key.priv" cfg.privkey) - config.krebs.tinc; - in - ed25519_keys // rsa_keys; - users.users = mapAttrs' (netname: cfg: nameValuePair "${netname}" { inherit (cfg.user) home name uid; @@ -267,30 +237,37 @@ let } ) config.krebs.tinc; - systemd.services = mapAttrs (netname: cfg: + krebs.systemd.services = mapAttrs (netname: cfg: let tinc = cfg.tincPackage; iproute = cfg.iproutePackage; in { description = "Tinc daemon for ${netname}"; - after = [ - "network.target" - config.krebs.secret.files."${netname}.rsa_key.priv".service - ] ++ optionals (cfg.privkey_ed25519 != null) [ - config.krebs.secret.files."${netname}.ed25519_key.priv".service - ]; - partOf = [ - config.krebs.secret.files."${netname}.rsa_key.priv".service - ] ++ optionals (cfg.privkey_ed25519 != null) [ - config.krebs.secret.files."${netname}.ed25519_key.priv".service - ]; + after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; path = [ tinc iproute ]; reloadIfChanged = true; restartTriggers = [ cfg.confDir ]; - serviceConfig = rec { + serviceConfig = { + LoadCredential = filter (x: x != "") [ + (optionalString (cfg.privkey_ed25519 != null) + "ed25519_key:${cfg.privkey_ed25519}" + ) + "rsa_key:${cfg.privkey}" + ]; Restart = "always"; - ExecStart = "${tinc}/sbin/tincd -c /etc/tinc/${netname} -d 0 -U ${cfg.user.name} -D --pidfile=/var/run/tinc.${SyslogIdentifier}.pid"; + ExecStart = toString [ + "${tinc}/sbin/tincd" + "-D" + "-U ${cfg.user.name}" + "-c /etc/tinc/${netname}" + "-d 0" + (optionalString (cfg.privkey_ed25519 != null) + "-o Ed25519PrivateKeyFile=\${CREDENTIALS_DIRECTORY}/ed25519_key" + ) + "-o PrivateKeyFile=\${CREDENTIALS_DIRECTORY}/rsa_key" + "--pidfile=/var/run/tinc.${netname}.pid" + ]; ExecReload = "${tinc}/sbin/tinc -n ${netname} reload"; SyslogIdentifier = netname; }; From 5410c7dcccc44529e5d1071237fbb3cac5aec936 Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 23 Dec 2021 01:23:06 +0100 Subject: [PATCH 05/10] ci: configure krebs.build.host --- ci.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci.nix b/ci.nix index 16c866e76..212114538 100644 --- a/ci.nix +++ b/ci.nix @@ -8,6 +8,9 @@ let imports = [ ./krebs ./krebs/2configs + ({ config, ... }: { + krebs.build.host = config.krebs.hosts.test-all-krebs-modules; + }) ]; }]; } From 018018e16b95b45f4a086df48c10a102a34e79ba Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 23 Dec 2021 03:12:02 +0100 Subject: [PATCH 06/10] krebs.tinc: don't bother aliasing packages --- krebs/3modules/tinc.nix | 70 ++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/krebs/3modules/tinc.nix b/krebs/3modules/tinc.nix index a0fc39e6f..2daef8e15 100644 --- a/krebs/3modules/tinc.nix +++ b/krebs/3modules/tinc.nix @@ -237,41 +237,39 @@ let } ) config.krebs.tinc; - krebs.systemd.services = mapAttrs (netname: cfg: - let - tinc = cfg.tincPackage; - iproute = cfg.iproutePackage; - in { - description = "Tinc daemon for ${netname}"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - path = [ tinc iproute ]; - reloadIfChanged = true; - restartTriggers = [ cfg.confDir ]; - serviceConfig = { - LoadCredential = filter (x: x != "") [ - (optionalString (cfg.privkey_ed25519 != null) - "ed25519_key:${cfg.privkey_ed25519}" - ) - "rsa_key:${cfg.privkey}" - ]; - Restart = "always"; - ExecStart = toString [ - "${tinc}/sbin/tincd" - "-D" - "-U ${cfg.user.name}" - "-c /etc/tinc/${netname}" - "-d 0" - (optionalString (cfg.privkey_ed25519 != null) - "-o Ed25519PrivateKeyFile=\${CREDENTIALS_DIRECTORY}/ed25519_key" - ) - "-o PrivateKeyFile=\${CREDENTIALS_DIRECTORY}/rsa_key" - "--pidfile=/var/run/tinc.${netname}.pid" - ]; - ExecReload = "${tinc}/sbin/tinc -n ${netname} reload"; - SyslogIdentifier = netname; - }; - } - ) config.krebs.tinc; + krebs.systemd.services = mapAttrs (netname: cfg: { + description = "Tinc daemon for ${netname}"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = [ + cfg.iproutePackage + cfg.tincPackage + ]; + reloadIfChanged = true; + restartTriggers = [ cfg.confDir ]; + serviceConfig = { + LoadCredential = filter (x: x != "") [ + (optionalString (cfg.privkey_ed25519 != null) + "ed25519_key:${cfg.privkey_ed25519}" + ) + "rsa_key:${cfg.privkey}" + ]; + Restart = "always"; + ExecStart = toString [ + "${cfg.tincPackage}/sbin/tincd" + "-D" + "-U ${cfg.user.name}" + "-c /etc/tinc/${netname}" + "-d 0" + (optionalString (cfg.privkey_ed25519 != null) + "-o Ed25519PrivateKeyFile=\${CREDENTIALS_DIRECTORY}/ed25519_key" + ) + "-o PrivateKeyFile=\${CREDENTIALS_DIRECTORY}/rsa_key" + "--pidfile=/var/run/tinc.${netname}.pid" + ]; + ExecReload = "${cfg.tincPackage}/sbin/tinc -n ${netname} reload"; + SyslogIdentifier = netname; + }; + }) config.krebs.tinc; }; in out From 8029e80632da0dcb886445bd1e9ba2d55821cc30 Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 23 Dec 2021 03:16:44 +0100 Subject: [PATCH 07/10] krebs.tinc: drop api and imp boilerplate --- krebs/3modules/tinc.nix | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/krebs/3modules/tinc.nix b/krebs/3modules/tinc.nix index 2daef8e15..91aa37fdf 100644 --- a/krebs/3modules/tinc.nix +++ b/krebs/3modules/tinc.nix @@ -1,12 +1,6 @@ with import ; -{ config, pkgs, ... }: -let - out = { - options.krebs.tinc = api; - config = imp; - }; - - api = mkOption { +{ config, pkgs, ... }: { + options.krebs.tinc = mkOption { default = {}; description = '' define a tinc network @@ -214,7 +208,7 @@ let })); }; - imp = { + config = { # TODO `environment.systemPackages = [ cfg.tincPackage cfg.iproutePackage ]` for each network, # avoid conflicts in environment if the packages differ @@ -272,4 +266,4 @@ let }; }) config.krebs.tinc; }; -in out +} From 5f7ab23ebf220194dc9ef28dd164f042ee2804c4 Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 23 Dec 2021 03:20:36 +0100 Subject: [PATCH 08/10] krebs.tinc: drop environment.systemPackages TODO Nobody bothered about this for more than five years. And even though fixable, chances are quite high that this feature is not needed anymore. --- krebs/3modules/tinc.nix | 3 --- 1 file changed, 3 deletions(-) diff --git a/krebs/3modules/tinc.nix b/krebs/3modules/tinc.nix index 91aa37fdf..f709b3343 100644 --- a/krebs/3modules/tinc.nix +++ b/krebs/3modules/tinc.nix @@ -209,9 +209,6 @@ with import ; }; config = { - # TODO `environment.systemPackages = [ cfg.tincPackage cfg.iproutePackage ]` for each network, - # avoid conflicts in environment if the packages differ - users.users = mapAttrs' (netname: cfg: nameValuePair "${netname}" { inherit (cfg.user) home name uid; From 1cf495d6eb113541dfa1667f03f7edd10c2217b1 Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 23 Dec 2021 20:09:06 +0100 Subject: [PATCH 09/10] krebs.systemd: support credentials of any service --- krebs/3modules/systemd.nix | 33 ++++++++++++++++++--------------- krebs/3modules/tinc.nix | 15 +++++++++------ 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/krebs/3modules/systemd.nix b/krebs/3modules/systemd.nix index c30b2264a..00538d5f3 100644 --- a/krebs/3modules/systemd.nix +++ b/krebs/3modules/systemd.nix @@ -1,36 +1,39 @@ -{ config, options, pkgs, ... }: let { +{ config, pkgs, ... }: let { lib = import ../../lib; body.options.krebs.systemd.services = lib.mkOption { default = {}; - type = lib.types.attrs; - description = '' - Definition of systemd service units with bonus features. - - Services defined using this option will be restarted whenever any file - (described by an absolute path) used in LoadCredential changes. - ''; + type = lib.types.attrsOf (lib.types.submodule { + options = { + serviceConfig.LoadCredential = lib.mkOption { + apply = lib.toList; + type = + lib.types.either lib.types.str (lib.types.listOf lib.types.str); + }; + }; + }); }; body.config.systemd = lib.mkMerge (lib.flatten (lib.mapAttrsToList (serviceName: cfg: let - prefix = [ "krebs" "systemd" "services" serviceName ]; - opts = options.systemd.services.type.getSubOptions prefix; - paths = lib.filter lib.types.absolute-pathname.check (map (lib.compose [ lib.maybeHead (lib.match "[^:]*:(.*)") ]) - (cfg.serviceConfig.LoadCredential or [])); + cfg.serviceConfig.LoadCredential); in lib.singleton { - services.${serviceName} = cfg; + services.${serviceName} = { + serviceConfig = { + LoadCredential = cfg.serviceConfig.LoadCredential; + }; + }; } ++ - lib.optionals (cfg.enable or opts.enable.default) (map (path: let + map (path: let triggerName = "trigger-${lib.systemd.encodeName path}"; in { paths.${triggerName} = { @@ -46,6 +49,6 @@ ]); }; }; - }) paths) + }) paths ) config.krebs.systemd.services)); } diff --git a/krebs/3modules/tinc.nix b/krebs/3modules/tinc.nix index f709b3343..dca764f63 100644 --- a/krebs/3modules/tinc.nix +++ b/krebs/3modules/tinc.nix @@ -229,6 +229,15 @@ with import ; ) config.krebs.tinc; krebs.systemd.services = mapAttrs (netname: cfg: { + serviceConfig.LoadCredential = filter (x: x != "") [ + (optionalString (cfg.privkey_ed25519 != null) + "ed25519_key:${cfg.privkey_ed25519}" + ) + "rsa_key:${cfg.privkey}" + ]; + }) config.krebs.tinc; + + systemd.services = mapAttrs (netname: cfg: { description = "Tinc daemon for ${netname}"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; @@ -239,12 +248,6 @@ with import ; reloadIfChanged = true; restartTriggers = [ cfg.confDir ]; serviceConfig = { - LoadCredential = filter (x: x != "") [ - (optionalString (cfg.privkey_ed25519 != null) - "ed25519_key:${cfg.privkey_ed25519}" - ) - "rsa_key:${cfg.privkey}" - ]; Restart = "always"; ExecStart = toString [ "${cfg.tincPackage}/sbin/tincd" From d4521eb339a47c52c5e8f7d82969b54f6dce1e9c Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 23 Dec 2021 20:16:34 +0100 Subject: [PATCH 10/10] krebs.systemd: allow reload if credentials change --- krebs/3modules/systemd.nix | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/krebs/3modules/systemd.nix b/krebs/3modules/systemd.nix index 00538d5f3..6b0fe9672 100644 --- a/krebs/3modules/systemd.nix +++ b/krebs/3modules/systemd.nix @@ -5,6 +5,19 @@ default = {}; type = lib.types.attrsOf (lib.types.submodule { options = { + ifCredentialsChange = lib.mkOption { + default = "restart"; + description = '' + Whether to reload or restart the service whenever any its + credentials change. Only credentials with an absolute path in + LoadCredential= are supported. + ''; + type = lib.types.enum [ + "reload" + "restart" + null + ]; + }; serviceConfig.LoadCredential = lib.mkOption { apply = lib.toList; type = @@ -33,7 +46,7 @@ }; } ++ - map (path: let + lib.optionals (cfg.ifCredentialsChange != null) (map (path: let triggerName = "trigger-${lib.systemd.encodeName path}"; in { paths.${triggerName} = { @@ -44,11 +57,11 @@ serviceConfig = { Type = "oneshot"; ExecStart = lib.singleton (toString [ - "${pkgs.systemd}/bin/systemctl restart" + "${pkgs.systemd}/bin/systemctl ${cfg.ifCredentialsChange}" (lib.shell.escape serviceName) ]); }; }; - }) paths + }) paths) ) config.krebs.systemd.services)); }