From 75c60a6103da01d8dcd46c68b2dabbdfa0c02d05 Mon Sep 17 00:00:00 2001 From: pinpox Date: Mon, 11 Aug 2025 12:34:04 +0200 Subject: [PATCH] Refactor admin module --- clanServices/admin/default.nix | 28 +--- clanServices/admin/root-password.nix | 83 +++++----- clanServices/admin/ssh.nix | 223 ++++++++++++++------------- 3 files changed, 169 insertions(+), 165 deletions(-) diff --git a/clanServices/admin/default.nix b/clanServices/admin/default.nix index c7c6d16f0..fb48612f4 100644 --- a/clanServices/admin/default.nix +++ b/clanServices/admin/default.nix @@ -41,25 +41,13 @@ }; }; }; - - perInstance = - { settings, ... }: - { - nixosModule = - { ... }: - { - imports = [ - # We don't have a good way to specify dependencies between - # clanServices for now. When it get's implemtende, we should just - # use the ssh and users modules here. - ./ssh.nix - ./root-password.nix - ]; - - _module.args = { inherit settings; }; - - users.users.root.openssh.authorizedKeys.keys = builtins.attrValues settings.allowedKeys; - }; - }; }; + + # We don't have a good way to specify dependencies between + # clanServices for now. When it get's implemtende, we should just + # use the ssh and users modules here. + imports = [ + ./ssh.nix + ./root-password.nix + ]; } diff --git a/clanServices/admin/root-password.nix b/clanServices/admin/root-password.nix index 8d1d39d65..9b4044e32 100644 --- a/clanServices/admin/root-password.nix +++ b/clanServices/admin/root-password.nix @@ -1,48 +1,55 @@ # We don't have a way of specifying dependencies between clanServices for now. # When it get's added this file should be removed and the users module used instead. { - config, - pkgs, - ... -}: -{ + roles.default.perInstance = + { ... }: + { + nixosModule = + { + config, + pkgs, + ... + }: + { - users.mutableUsers = false; - users.users.root.hashedPasswordFile = - config.clan.core.vars.generators.root-password.files.password-hash.path; + users.mutableUsers = false; + users.users.root.hashedPasswordFile = + config.clan.core.vars.generators.root-password.files.password-hash.path; - clan.core.vars.generators.root-password = { - files.password-hash.neededFor = "users"; + clan.core.vars.generators.root-password = { + files.password-hash.neededFor = "users"; - files.password.deploy = false; + files.password.deploy = false; - runtimeInputs = [ - pkgs.coreutils - pkgs.mkpasswd - pkgs.xkcdpass - ]; + runtimeInputs = [ + pkgs.coreutils + pkgs.mkpasswd + pkgs.xkcdpass + ]; - prompts.password.display = { - group = "Root User"; - label = "Password"; - required = false; - helperText = '' - Your password will be encrypted and stored securely using the secret store you've configured. - ''; + prompts.password.display = { + group = "Root User"; + label = "Password"; + required = false; + helperText = '' + Your password will be encrypted and stored securely using the secret store you've configured. + ''; + }; + + prompts.password.type = "hidden"; + prompts.password.persist = true; + prompts.password.description = "Leave empty to generate automatically"; + + script = '' + prompt_value="$(cat "$prompts"/password)" + if [[ -n "''${prompt_value-}" ]]; then + echo "$prompt_value" | tr -d "\n" > "$out"/password + else + xkcdpass --numwords 5 --delimiter - --count 1 | tr -d "\n" > "$out"/password + fi + mkpasswd -s -m sha-512 < "$out"/password | tr -d "\n" > "$out"/password-hash + ''; + }; + }; }; - - prompts.password.type = "hidden"; - prompts.password.persist = true; - prompts.password.description = "Leave empty to generate automatically"; - - script = '' - prompt_value="$(cat "$prompts"/password)" - if [[ -n "''${prompt_value-}" ]]; then - echo "$prompt_value" | tr -d "\n" > "$out"/password - else - xkcdpass --numwords 5 --delimiter - --count 1 | tr -d "\n" > "$out"/password - fi - mkpasswd -s -m sha-512 < "$out"/password | tr -d "\n" > "$out"/password-hash - ''; - }; } diff --git a/clanServices/admin/ssh.nix b/clanServices/admin/ssh.nix index 3e888de7d..d96be61c2 100644 --- a/clanServices/admin/ssh.nix +++ b/clanServices/admin/ssh.nix @@ -1,115 +1,124 @@ { - config, - pkgs, - lib, - settings, - ... -}: -let - stringSet = list: builtins.attrNames (builtins.groupBy lib.id list); + roles.default.perInstance = + { settings, ... }: + { + nixosModule = - domains = stringSet settings.certificateSearchDomains; + { + config, + pkgs, + lib, + ... + }: + let + stringSet = list: builtins.attrNames (builtins.groupBy lib.id list); -in -{ + domains = stringSet settings.certificateSearchDomains; - services.openssh = { - enable = true; - settings.PasswordAuthentication = false; + in + { - settings.HostCertificate = lib.mkIf ( - settings.certificateSearchDomains != [ ] - ) config.clan.core.vars.generators.openssh-cert.files."ssh.id_ed25519-cert.pub".path; + users.users.root.openssh.authorizedKeys.keys = builtins.attrValues settings.allowedKeys; - hostKeys = [ - { - path = config.clan.core.vars.generators.openssh.files."ssh.id_ed25519".path; - type = "ed25519"; - } - ] - ++ lib.optional settings.rsaHostKey.enable { - path = config.clan.core.vars.generators.openssh-rsa.files."ssh.id_rsa".path; - type = "rsa"; + services.openssh = { + enable = true; + settings.PasswordAuthentication = false; + + settings.HostCertificate = lib.mkIf ( + settings.certificateSearchDomains != [ ] + ) config.clan.core.vars.generators.openssh-cert.files."ssh.id_ed25519-cert.pub".path; + + hostKeys = [ + { + path = config.clan.core.vars.generators.openssh.files."ssh.id_ed25519".path; + type = "ed25519"; + } + ] + ++ lib.optional settings.rsaHostKey.enable { + path = config.clan.core.vars.generators.openssh-rsa.files."ssh.id_rsa".path; + type = "rsa"; + }; + }; + + clan.core.vars.generators.openssh = { + files."ssh.id_ed25519" = { }; + files."ssh.id_ed25519.pub".secret = false; + migrateFact = "openssh"; + runtimeInputs = [ + pkgs.coreutils + pkgs.openssh + ]; + script = '' + ssh-keygen -t ed25519 -N "" -C "" -f "$out"/ssh.id_ed25519 + ''; + }; + + programs.ssh.knownHosts.clan-sshd-self-ed25519 = { + hostNames = [ + "localhost" + config.networking.hostName + ] + ++ (lib.optional (config.networking.domain != null) config.networking.fqdn); + publicKey = config.clan.core.vars.generators.openssh.files."ssh.id_ed25519.pub".value; + }; + + clan.core.vars.generators.openssh-rsa = lib.mkIf settings.rsaHostKey.enable { + files."ssh.id_rsa" = { }; + files."ssh.id_rsa.pub".secret = false; + runtimeInputs = [ + pkgs.coreutils + pkgs.openssh + ]; + script = '' + ssh-keygen -t rsa -b 4096 -N "" -C "" -f "$out"/ssh.id_rsa + ''; + }; + + clan.core.vars.generators.openssh-cert = lib.mkIf (settings.certificateSearchDomains != [ ]) { + files."ssh.id_ed25519-cert.pub".secret = false; + dependencies = [ + "openssh" + "openssh-ca" + ]; + validation = { + name = config.clan.core.settings.machine.name; + domains = lib.genAttrs settings.certificateSearchDomains lib.id; + }; + runtimeInputs = [ + pkgs.openssh + pkgs.jq + ]; + script = '' + ssh-keygen \ + -s $in/openssh-ca/id_ed25519 \ + -I ${config.clan.core.settings.machine.name} \ + -h \ + -n ${lib.concatMapStringsSep "," (d: "${config.clan.core.settings.machine.name}.${d}") domains} \ + $in/openssh/ssh.id_ed25519.pub + mv $in/openssh/ssh.id_ed25519-cert.pub "$out"/ssh.id_ed25519-cert.pub + ''; + }; + + clan.core.vars.generators.openssh-ca = lib.mkIf (settings.certificateSearchDomains != [ ]) { + share = true; + files.id_ed25519.deploy = false; + files."id_ed25519.pub" = { + deploy = false; + secret = false; + }; + runtimeInputs = [ + pkgs.openssh + ]; + script = '' + ssh-keygen -t ed25519 -N "" -C "" -f "$out"/id_ed25519 + ''; + }; + + programs.ssh.knownHosts.ssh-ca = lib.mkIf (settings.certificateSearchDomains != [ ]) { + certAuthority = true; + extraHostNames = builtins.map (domain: "*.${domain}") settings.certificateSearchDomains; + publicKey = config.clan.core.vars.generators.openssh-ca.files."id_ed25519.pub".value; + }; + }; }; - }; - - clan.core.vars.generators.openssh = { - files."ssh.id_ed25519" = { }; - files."ssh.id_ed25519.pub".secret = false; - migrateFact = "openssh"; - runtimeInputs = [ - pkgs.coreutils - pkgs.openssh - ]; - script = '' - ssh-keygen -t ed25519 -N "" -C "" -f "$out"/ssh.id_ed25519 - ''; - }; - - programs.ssh.knownHosts.clan-sshd-self-ed25519 = { - hostNames = [ - "localhost" - config.networking.hostName - ] - ++ (lib.optional (config.networking.domain != null) config.networking.fqdn); - publicKey = config.clan.core.vars.generators.openssh.files."ssh.id_ed25519.pub".value; - }; - - clan.core.vars.generators.openssh-rsa = lib.mkIf settings.rsaHostKey.enable { - files."ssh.id_rsa" = { }; - files."ssh.id_rsa.pub".secret = false; - runtimeInputs = [ - pkgs.coreutils - pkgs.openssh - ]; - script = '' - ssh-keygen -t rsa -b 4096 -N "" -C "" -f "$out"/ssh.id_rsa - ''; - }; - - clan.core.vars.generators.openssh-cert = lib.mkIf (settings.certificateSearchDomains != [ ]) { - files."ssh.id_ed25519-cert.pub".secret = false; - dependencies = [ - "openssh" - "openssh-ca" - ]; - validation = { - name = config.clan.core.settings.machine.name; - domains = lib.genAttrs settings.certificateSearchDomains lib.id; - }; - runtimeInputs = [ - pkgs.openssh - pkgs.jq - ]; - script = '' - ssh-keygen \ - -s $in/openssh-ca/id_ed25519 \ - -I ${config.clan.core.settings.machine.name} \ - -h \ - -n ${lib.concatMapStringsSep "," (d: "${config.clan.core.settings.machine.name}.${d}") domains} \ - $in/openssh/ssh.id_ed25519.pub - mv $in/openssh/ssh.id_ed25519-cert.pub "$out"/ssh.id_ed25519-cert.pub - ''; - }; - - clan.core.vars.generators.openssh-ca = lib.mkIf (settings.certificateSearchDomains != [ ]) { - share = true; - files.id_ed25519.deploy = false; - files."id_ed25519.pub" = { - deploy = false; - secret = false; - }; - runtimeInputs = [ - pkgs.openssh - ]; - script = '' - ssh-keygen -t ed25519 -N "" -C "" -f "$out"/id_ed25519 - ''; - }; - - programs.ssh.knownHosts.ssh-ca = lib.mkIf (settings.certificateSearchDomains != [ ]) { - certAuthority = true; - extraHostNames = builtins.map (domain: "*.${domain}") settings.certificateSearchDomains; - publicKey = config.clan.core.vars.generators.openssh-ca.files."id_ed25519.pub".value; - }; }