From 8eba3b905cc07efbed300e0158c1a744b727b020 Mon Sep 17 00:00:00 2001 From: Chris Toph Date: Tue, 22 Apr 2025 21:10:28 -0400 Subject: [PATCH] Refactors SSH config management - Consolidates SSH config into a unified file - Replaces deprecated config files and updates file sources - Ensures proper SSH key permission handling and mapping --- home/toph/common/core/default.nix | 7 ++-- home/toph/common/core/ssh.nix | 58 +++++++++++++++++++++++++++ home/toph/common/core/ssh/config | 17 -------- home/toph/common/core/ssh/default.nix | 32 --------------- hosts/common/core/ssh.nix | 5 --- hosts/common/optional/system/pool.nix | 3 +- hosts/users/toph/default.nix | 9 +++-- 7 files changed, 69 insertions(+), 62 deletions(-) create mode 100644 home/toph/common/core/ssh.nix delete mode 100644 home/toph/common/core/ssh/config delete mode 100644 home/toph/common/core/ssh/default.nix diff --git a/home/toph/common/core/default.nix b/home/toph/common/core/default.nix index eafda22..96a101c 100644 --- a/home/toph/common/core/default.nix +++ b/home/toph/common/core/default.nix @@ -10,6 +10,7 @@ let username = config.hostSpec.username; homeDir = config.hostSpec.home; + shell = config.hostSpec.shell; in { imports = lib.flatten [ @@ -18,7 +19,7 @@ in "modules/home" ]) ./asdf.nix - ./bash.nix + ./bash.nix # TODO: setup a nicer bash config... or zsh ./bat.nix ./direnv.nix ./fastfetch @@ -26,7 +27,7 @@ in ./git.nix ./ranger.nix ./screen.nix - ./ssh + ./ssh.nix ./zoxide.nix ]; @@ -45,7 +46,7 @@ in EDITOR = "micro"; FLAKE = "${homeDir}/git/Nix/dot.nix"; MANPAGER = "batman"; # see ./cli/bat.nix - SHELL = "fish"; + SHELL = shell; TERM = "foot"; VISUAL = "micro"; }; diff --git a/home/toph/common/core/ssh.nix b/home/toph/common/core/ssh.nix new file mode 100644 index 0000000..88e756c --- /dev/null +++ b/home/toph/common/core/ssh.nix @@ -0,0 +1,58 @@ +{ + pkgs, + config, + lib, + hostSpec, + secretsSpec, + ... +}: +let + # Generate local key paths for the config + sshKeysMap = lib.mapAttrs (name: _: "${hostSpec.home}/.ssh/${name}") secretsSpec.ssh.privateKeys; + + # 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 + ''; +in +{ + home.file = + { + # SSH config file + ".ssh/config_source" = { + source = sshConfig; + onChange = '' + cp $HOME/.ssh/config_source $HOME/.ssh/config + chmod 400 $HOME/.ssh/config + ''; + }; + } + # Dynamically add all SSH private keys using the existing store paths + # Ensures the keys have correct permissions and are not symlinks + // lib.mapAttrs' (name: path: { + name = ".ssh/${name}_source"; + value = { + source = path; + onChange = '' + cp $HOME/.ssh/${name}_source $HOME/.ssh/${name} + chmod 600 $HOME/.ssh/${name} + ''; + }; + }) secretsSpec.ssh.privateKeys; +} diff --git a/home/toph/common/core/ssh/config b/home/toph/common/core/ssh/config deleted file mode 100644 index 2ee0ec8..0000000 --- a/home/toph/common/core/ssh/config +++ /dev/null @@ -1,17 +0,0 @@ -Host git.ryot.foo - IdentityFile ~/git/.ssh/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 ~/.ssh/pve - UpdateHostKeys ask diff --git a/home/toph/common/core/ssh/default.nix b/home/toph/common/core/ssh/default.nix deleted file mode 100644 index 36adcae..0000000 --- a/home/toph/common/core/ssh/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - config, - inputs, - lib, - ... -}: -{ - # programs.ssh = { - # enable = true; - # # Avoids infinite hang if control socket connection interrupted. ex: vpn goes down/up - # serverAliveCountMax = 3; - # serverAliveInterval = 5; - # addKeysToAgent = "yes"; - - # extraConfig = '' - # IdentityFile ~/.ssh/pve - # UpdateHostKeys ask - # ''; - - # matchBlocks = { - # "git.ryot.foo" = { - # identityFile = "~/git/.ssh/git"; - # }; - # }; - # }; - - home.file.".ssh/config" = { - source = ./config; - target = ".ssh/config_source"; - onChange = ''cat .ssh/config_source > .ssh/config && chmod 400 .ssh/config''; - }; -} diff --git a/hosts/common/core/ssh.nix b/hosts/common/core/ssh.nix index fb2d9b1..aa44bd2 100644 --- a/hosts/common/core/ssh.nix +++ b/hosts/common/core/ssh.nix @@ -1,8 +1,3 @@ -{ - lib, - config, - ... -}: { programs.ssh.startAgent = true; diff --git a/hosts/common/optional/system/pool.nix b/hosts/common/optional/system/pool.nix index a200893..a13b29b 100644 --- a/hosts/common/optional/system/pool.nix +++ b/hosts/common/optional/system/pool.nix @@ -2,6 +2,7 @@ let username = config.hostSpec.username; homeDir = config.hostSpec.home; + pve-key = config.secretsSpec.ssh.privateKeys.pve; in { # For less permission issues with SSHFS @@ -23,7 +24,7 @@ in "reconnect" "_netdev" "allow_other" - "identityfile=${homeDir}/.ssh/pve" + "identityfile=${pve-key}" ]; }; diff --git a/hosts/users/toph/default.nix b/hosts/users/toph/default.nix index 8bde777..15e26b9 100644 --- a/hosts/users/toph/default.nix +++ b/hosts/users/toph/default.nix @@ -9,15 +9,16 @@ let hostSpec = config.hostSpec; username = hostSpec.username; homeDir = hostSpec.home; - pubKeys = lib.filesystem.listFilesRecursive ./keys; + _shell = hostSpec.shell; + pubKeys = builtins.attrValues config.secretsSpec.ssh.publicKeys; in { users.users.${username} = { name = hostSpec.username; - shell = pkgs.fish; # default shell + shell = _shell; # These get placed into /etc/ssh/authorized_keys.d/ on nixos - openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key); + openssh.authorizedKeys.keys = pubKeys; }; # Create ssh sockets directory for controlpaths when homemanager not loaded (i.e. isMinimal) @@ -38,7 +39,7 @@ in home-manager = { extraSpecialArgs = { inherit pkgs inputs; - hostSpec = config.hostSpec; + inherit (config) secretsSpec hostSpec; }; users.${username}.imports = lib.flatten ( lib.optional (!hostSpec.isMinimal) [