From 5695caa8cf130258d3ee7d19cbb1912062933652 Mon Sep 17 00:00:00 2001 From: Chris Toph Date: Wed, 28 May 2025 21:26:31 -0400 Subject: [PATCH] Refactors SSH/GPG secrets handling - Switches to per-user SSH configuration by retrieving user-specific secrets - Integrates GPG key creation and config into secret spec structure - Simplifies SSH config and key copying logic for better maintainability - Streamlines SMTP and firewall option mappings --- home/global/core/ssh.nix | 39 ++---- modules/global/secret-spec.nix | 221 +++++++++++++++++++++------------ secrets.nix | Bin 13470 -> 20513 bytes 3 files changed, 151 insertions(+), 109 deletions(-) diff --git a/home/global/core/ssh.nix b/home/global/core/ssh.nix index 79f51ab..1f943eb 100644 --- a/home/global/core/ssh.nix +++ b/home/global/core/ssh.nix @@ -7,52 +7,35 @@ ... }: let - # Generate local key paths for the config - sshKeysMap = lib.mapAttrs (name: _: "${hostSpec.home}/.ssh/${name}") secretsSpec.ssh.privateKeys; + ## Get the current user's SSH config ## + userSsh = secretsSpec.users.${hostSpec.user}.ssh; - # Create the SSH config file with local paths - sshConfig = pkgs.writeText "ssh-config" '' - Host git.ryot.foo - IdentityFile ${sshKeysMap.git} - - Host * - ForwardAgent no - AddKeysToAgent yes - Compression no - ServerAliveInterval 5 - ServerAliveCountMax 3 - HashKnownHosts no - UserKnownHostsFile ~/.ssh/known_hosts - ControlMaster no - ControlPath ~/.ssh/master-%r@%n:%p - ControlPersist no - - IdentityFile ${sshKeysMap.pve} - UpdateHostKeys ask - ''; + ## Generate local key paths for the config ## + sshKeysMap = lib.mapAttrs (name: _: "${hostSpec.home}/.ssh/${name}") userSsh.privateKeys; in { home.file = { - # SSH config file + ## SSH config file ## ".ssh/config_source" = { - source = sshConfig; + source = userSsh.config; onChange = '' cp $HOME/.ssh/config_source $HOME/.ssh/config chmod 400 $HOME/.ssh/config ''; }; + ## Known hosts ## ".ssh/known_hosts_source" = { - source = pkgs.writeText "known-hosts" (lib.concatStringsSep "\n" secretsSpec.ssh.knownHosts); + source = pkgs.writeText "known-hosts" (lib.concatStringsSep "\n" userSsh.knownHosts); onChange = '' cp $HOME/.ssh/known_hosts_source $HOME/.ssh/known_hosts chmod 644 $HOME/.ssh/known_hosts ''; }; } - # Dynamically add all SSH private keys using the existing store paths - # Ensures the keys have correct permissions and are not symlinks + + ## Dynamically copy all SSH private keys from store ensuring symlinks are not used ## // lib.mapAttrs' (name: path: { name = ".ssh/${name}_source"; value = { @@ -62,5 +45,5 @@ in chmod 600 $HOME/.ssh/${name} ''; }; - }) secretsSpec.ssh.privateKeys; + }) userSsh.privateKeys; } diff --git a/modules/global/secret-spec.nix b/modules/global/secret-spec.nix index 4e2b06f..d2a6445 100644 --- a/modules/global/secret-spec.nix +++ b/modules/global/secret-spec.nix @@ -6,7 +6,7 @@ ... }: let - # Function to create a private key file in the Nix store with proper permissions + ## SSH key creation function ## mkSshKeyFile = name: content: pkgs.writeTextFile { @@ -14,56 +14,24 @@ let text = content; executable = false; checkPhase = '' - # Verify it's a valid SSH key (optional) grep -q "BEGIN OPENSSH PRIVATE KEY" "$out" || (echo "Invalid SSH key format"; exit 1) ''; }; + + ## GPG key creation function ## + mkGpgKeyFile = + name: content: + pkgs.writeTextFile { + name = "gpg-key-${name}"; + text = content; + executable = false; + checkPhase = '' + grep -q "BEGIN PGP PRIVATE KEY BLOCK" "$out" || (echo "Invalid GPG key format"; exit 1) + ''; + }; in { options.secretsSpec = { - ssh = lib.mkOption { - type = lib.types.submodule { - options = { - # privateKeys are set up automagically 🌠, see config below - privateKeyContents = lib.mkOption { - type = lib.types.attrsOf lib.types.str; - description = "SSH private key contents keyed by name"; - default = { }; - }; - privateKeys = lib.mkOption { - type = lib.types.attrsOf lib.types.path; - description = "SSH private key file paths keyed by name"; - # default = { }; - readOnly = true; - }; - publicKeys = lib.mkOption { - type = lib.types.attrsOf lib.types.str; - description = "SSH public keys keyed by name"; - default = { }; - }; - knownHosts = lib.mkOption { - type = lib.types.listOf lib.types.str; - description = "SSH known hosts entries"; - default = [ ]; - }; - }; - }; - default = { }; - description = "SSH key related secrets"; - }; - - api = lib.mkOption { - type = lib.types.attrsOf lib.types.str; - description = "API keys keyed by service name"; - default = { }; - }; - - docker = lib.mkOption { - type = lib.types.attrsOf (lib.types.attrsOf lib.types.str); - description = "Docker environment variables keyed by container name"; - default = { }; - }; - users = lib.mkOption { type = lib.types.attrsOf ( lib.types.submodule { @@ -84,40 +52,98 @@ in type = lib.types.str; description = "Full name of the user"; }; - sshKeys = lib.mkOption { - type = lib.types.listOf lib.types.str; - description = "SSH public keys for the user"; - default = [ ]; - }; - smtp = lib.mkOption { - type = lib.types.submodule ( - { config, ... }: - { - options = { - host = lib.mkOption { - type = lib.types.str; - description = "SMTP server hostname"; - }; - user = lib.mkOption { - type = lib.types.str; - description = "SMTP username for authentication"; - }; - password = lib.mkOption { - type = lib.types.str; - description = "SMTP password for authentication"; - }; - port = lib.mkOption { - type = lib.types.port; - description = "SMTP server port"; - default = 587; - }; - from = lib.mkOption { - type = lib.types.str; - description = "Email address to send from"; - }; + + ## SSH configuration ## + ssh = lib.mkOption { + type = lib.types.submodule { + options = { + publicKeys = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "SSH public keys for the user"; + default = [ ]; }; - } - ); + privateKeyContents = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + description = "SSH private key contents keyed by name"; + default = { }; + }; + privateKeys = lib.mkOption { + type = lib.types.attrsOf lib.types.path; + description = "SSH private key file paths keyed by name"; + readOnly = true; + }; + config = lib.mkOption { + type = lib.types.path; + description = "SSH config file path"; + }; + knownHosts = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "SSH known hosts entries"; + default = [ ]; + }; + }; + }; + default = { }; + description = "SSH configuration for the user"; + }; + + ## GPG configuration ## + gpg = lib.mkOption { + type = lib.types.submodule { + options = { + publicKey = lib.mkOption { + type = lib.types.str; + description = "GPG public key content"; + default = ""; + }; + privateKeyContents = lib.mkOption { + type = lib.types.str; + description = "GPG private key content"; + default = ""; + }; + privateKey = lib.mkOption { + type = lib.types.path; + description = "GPG private key file path"; + readOnly = true; + }; + trust = lib.mkOption { + type = lib.types.str; + description = "GPG trust database content (base64)"; + default = ""; + }; + }; + }; + default = { }; + description = "GPG configuration for the user"; + }; + + ## SMTP configuration ## + smtp = lib.mkOption { + type = lib.types.submodule { + options = { + host = lib.mkOption { + type = lib.types.str; + description = "SMTP server hostname"; + }; + user = lib.mkOption { + type = lib.types.str; + description = "SMTP username for authentication"; + }; + password = lib.mkOption { + type = lib.types.str; + description = "SMTP password for authentication"; + }; + port = lib.mkOption { + type = lib.types.port; + description = "SMTP server port"; + default = 587; + }; + from = lib.mkOption { + type = lib.types.str; + description = "Email address to send from"; + }; + }; + }; description = "SMTP configuration for the user"; default = null; }; @@ -128,6 +154,7 @@ in default = { }; }; + ## Firewall configurations by host ## firewall = lib.mkOption { type = lib.types.attrsOf ( lib.types.submodule { @@ -205,9 +232,41 @@ in description = "Firewall configuration by host"; default = { }; }; + + ## API keys ## + api = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + description = "API keys keyed by service name"; + default = { }; + }; + + ## Docker environment variables ## + docker = lib.mkOption { + type = lib.types.attrsOf (lib.types.attrsOf lib.types.str); + description = "Docker environment variables keyed by container name"; + default = { }; + }; }; - config.secretsSpec.ssh.privateKeys = lib.mapAttrs ( - name: content: mkSshKeyFile name content - ) config.secretsSpec.ssh.privateKeyContents; + config.secretsSpec.users = lib.mapAttrs ( + userName: userConfig: + userConfig + // { + ## Auto-generate SSH private key files ## + ssh = userConfig.ssh // { + privateKeys = lib.mapAttrs ( + name: content: mkSshKeyFile "${userName}-${name}" content + ) userConfig.ssh.privateKeyContents; + }; + + ## Auto-generate GPG private key file ## + gpg = userConfig.gpg // { + privateKey = + if userConfig.gpg.privateKeyContents != "" then + mkGpgKeyFile "${userName}-gpg" userConfig.gpg.privateKeyContents + else + null; + }; + } + ) config.secretsSpec.users; } diff --git a/secrets.nix b/secrets.nix index b188add5c0f5ae9deacde626509f7fdada7d2107..f1808e6a4d16d2184d3680849759a81a412d6bf7 100644 GIT binary patch literal 20513 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