From dbd3fc8bae57326a8f37001afcd5db8b38cd123a Mon Sep 17 00:00:00 2001 From: alexion Date: Wed, 7 Oct 2026 20:05:55 -0400 Subject: [PATCH] refactor(nixos): isolate SSH fleet configuration --- configs/nixos/modules/network/ssh.nix | 137 ++++++++++++++------------ 1 file changed, 75 insertions(+), 62 deletions(-) diff --git a/configs/nixos/modules/network/ssh.nix b/configs/nixos/modules/network/ssh.nix index 4864773..2669dbd 100644 --- a/configs/nixos/modules/network/ssh.nix +++ b/configs/nixos/modules/network/ssh.nix @@ -5,70 +5,83 @@ ... }: # Configures inbound and outbound SSH access. -# Keep bindings grouped by purpose rather than dependency traversal. -# NOLINT(let_order) let - cfg = config.modules.network.ssh; - user = config.user.name; - - workstationNames = [ - "neogaia" - "zeus" - ]; - serverNames = [ "pikachu" ]; - managedHostNames = workstationNames ++ serverNames; - isWorkstation = lib.elem config.networking.hostName workstationNames; - isServer = lib.elem config.networking.hostName serverNames; - - clientKeyFor = host: builtins.readFile (../../hosts + "/${host}/ssh_user_ed25519_key.pub"); - hostKeysFor = - host: - map builtins.readFile [ - (../../hosts + "/${host}/ssh_host_ed25519_key.pub") - (../../hosts + "/${host}/ssh_host_rsa_key.pub") - ]; - managedTargets = lib.genAttrs managedHostNames (name: { - hostName = registry.address.${name}.self; - clientKey = clientKeyFor name; - hostKeys = hostKeysFor name; - }); - extraTargets = { - # TODO: Pin Gitea's host key after migrating it from Proxmox. - gitea = { - hostName = "git.alexion.dev"; - port = 2022; - user = "gitea"; - aliases = [ - "gitea" - "git.alexion.dev" - ]; - }; - }; - mkTarget = name: target: { - hostName = target.hostName or name; - user = target.user or user; - port = target.port or 22; - aliases = target.aliases or [ name ]; - clientKey = target.clientKey or null; - hostKeys = target.hostKeys or [ ]; - }; - targets = lib.mapAttrs mkTarget (managedTargets // extraTargets); - - clientKeysFor = names: lib.filter (key: key != null) (map (name: targets.${name}.clientKey) names); + cfg = config.modules.network.ssh; # NOLINT(let_order) defaultAuthorizedKeys = lib.flatten ( - clientKeysFor workstationNames ++ lib.optional isServer (clientKeysFor serverNames) + clientKeysFor fleet.workstationNames + ++ lib.optional fleet.isServer (clientKeysFor fleet.serverNames) ); - outboundTargetNames = + clientKeysFor = + names: lib.filter (key: key != null) (map (name: fleet.targets.${name}.clientKey) names); + + fleet = + # Keep fleet policy and target construction in conceptual order. + # NOLINT(let_order) let - groupTargets = - if isServer then - [ "gitea" ] ++ serverNames - else if isWorkstation then - [ "gitea" ] ++ serverNames ++ workstationNames - else - [ "gitea" ]; + workstationNames = [ + "neogaia" + "zeus" + ]; + serverNames = [ "pikachu" ]; + managedHostNames = workstationNames ++ serverNames; + isWorkstation = lib.elem config.networking.hostName workstationNames; + isServer = lib.elem config.networking.hostName serverNames; + + clientKeyFor = host: builtins.readFile (../../hosts + "/${host}/ssh_user_ed25519_key.pub"); + hostKeysFor = + host: + map builtins.readFile [ + (../../hosts + "/${host}/ssh_host_ed25519_key.pub") + (../../hosts + "/${host}/ssh_host_rsa_key.pub") + ]; + managedTargets = lib.genAttrs managedHostNames (name: { + hostName = registry.address.${name}.self; + clientKey = clientKeyFor name; + hostKeys = hostKeysFor name; + }); + extraTargets = { + # TODO: Pin Gitea's host key after migrating it from Proxmox. + gitea = { + hostName = "git.alexion.dev"; + port = 2022; + user = "gitea"; + aliases = [ + "gitea" + "git.alexion.dev" + ]; + }; + }; + mkTarget = name: target: { + hostName = target.hostName or name; + user = target.user or user; + port = target.port or 22; + aliases = target.aliases or [ name ]; + clientKey = target.clientKey or null; + hostKeys = target.hostKeys or [ ]; + }; + targets = lib.mapAttrs mkTarget (managedTargets // extraTargets); + outboundTargetNames = + let + groupTargets = + if isServer then + [ "gitea" ] ++ serverNames + else if isWorkstation then + [ "gitea" ] ++ serverNames ++ workstationNames + else + [ "gitea" ]; + in + lib.filter (name: name != config.networking.hostName) groupTargets; in - lib.filter (name: name != config.networking.hostName) groupTargets; + { + inherit + isServer + outboundTargetNames + serverNames + targets + workstationNames + ; + }; + user = config.user.name; knownHosts = lib.listToAttrs ( lib.concatLists ( @@ -81,7 +94,7 @@ let publicKey = keyWithoutComment key; } ) target.hostKeys - ) targets + ) fleet.targets ) ); knownHostNamesFor = @@ -96,7 +109,7 @@ let sshSettingsFor = name: let - target = targets.${name}; + target = fleet.targets.${name}; in { header = "Host ${lib.concatStringsSep " " target.aliases}"; @@ -161,7 +174,7 @@ in enable = true; enableDefaultConfig = false; settings = lib.mapAttrs (name: _: sshSettingsFor name) ( - lib.genAttrs outboundTargetNames (name: name) + lib.genAttrs fleet.outboundTargetNames (name: name) ); }; }