@jaspermayone.com's dotfiles
at main 184 lines 5.6 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7with lib; 8let 9 cfg = config.jsp.ssh; 10in 11{ 12 options.jsp.ssh = { 13 enable = mkEnableOption "SSH configuration"; 14 15 zmx = { 16 enable = mkEnableOption "zmx integration for persistent sessions"; 17 hosts = mkOption { 18 type = types.listOf types.str; 19 default = [ ]; 20 description = "List of host patterns to enable zmx auto-attach (e.g., 'pve.*')"; 21 }; 22 }; 23 24 extraConfig = mkOption { 25 type = types.lines; 26 default = ""; 27 description = "Extra SSH configuration"; 28 }; 29 30 hosts = mkOption { 31 type = types.attrsOf ( 32 types.submodule { 33 options = { 34 hostname = mkOption { 35 type = types.nullOr types.str; 36 default = null; 37 description = "Hostname or IP address"; 38 }; 39 40 port = mkOption { 41 type = types.nullOr types.int; 42 default = null; 43 description = "SSH port"; 44 }; 45 46 user = mkOption { 47 type = types.nullOr types.str; 48 default = null; 49 description = "Username for SSH connection"; 50 }; 51 52 identityFile = mkOption { 53 type = types.nullOr types.str; 54 default = null; 55 description = "Path to SSH identity file"; 56 }; 57 58 identitiesOnly = mkOption { 59 type = types.nullOr types.bool; 60 default = null; 61 description = "Only use specified identity files"; 62 }; 63 64 forwardAgent = mkOption { 65 type = types.nullOr types.bool; 66 default = null; 67 description = "Enable SSH agent forwarding"; 68 }; 69 70 addKeysToAgent = mkOption { 71 type = types.nullOr types.str; 72 default = null; 73 description = "Add keys to SSH agent (yes/no/confirm/ask)"; 74 }; 75 76 extraOptions = mkOption { 77 type = types.attrsOf types.str; 78 default = { }; 79 description = "Additional SSH options for this host"; 80 }; 81 82 zmx = mkOption { 83 type = types.bool; 84 default = false; 85 description = "Enable zmx persistent sessions for this host"; 86 }; 87 }; 88 } 89 ); 90 default = { }; 91 description = "SSH host configurations"; 92 }; 93 }; 94 95 config = mkIf cfg.enable { 96 # Install zmx and autossh when zmx is enabled 97 home.packages = optionals cfg.zmx.enable [ 98 pkgs.zmx-binary 99 pkgs.autossh 100 ]; 101 102 programs.ssh = { 103 enable = true; 104 enableDefaultConfig = false; 105 106 matchBlocks = 107 let 108 # Convert jsp.ssh.hosts to SSH matchBlocks 109 hostConfigs = mapAttrs (name: hostCfg: { 110 hostname = mkIf (hostCfg.hostname != null) hostCfg.hostname; 111 port = mkIf (hostCfg.port != null) hostCfg.port; 112 user = mkIf (hostCfg.user != null) hostCfg.user; 113 identityFile = mkIf (hostCfg.identityFile != null) hostCfg.identityFile; 114 identitiesOnly = mkIf (hostCfg.identitiesOnly != null) hostCfg.identitiesOnly; 115 forwardAgent = mkIf (hostCfg.forwardAgent != null) hostCfg.forwardAgent; 116 addKeysToAgent = mkIf (hostCfg.addKeysToAgent != null) hostCfg.addKeysToAgent; 117 extraOptions = 118 hostCfg.extraOptions 119 // ( 120 if hostCfg.zmx then 121 { 122 RemoteCommand = "export PATH=$HOME/.nix-profile/bin:$PATH; zmx attach %n"; 123 RequestTTY = "yes"; 124 ControlPath = "~/.ssh/cm-%r@%h:%p"; 125 ControlMaster = "auto"; 126 ControlPersist = "10m"; 127 } 128 else 129 { } 130 ); 131 }) cfg.hosts; 132 133 # Create zmx pattern hosts if enabled 134 zmxPatternHosts = 135 if cfg.zmx.enable then 136 listToAttrs ( 137 map ( 138 pattern: 139 let 140 patternHost = cfg.hosts.${pattern} or { }; 141 in 142 { 143 name = pattern; 144 value = { 145 hostname = mkIf (patternHost.hostname or null != null) patternHost.hostname; 146 port = mkIf (patternHost.port or null != null) patternHost.port; 147 user = mkIf (patternHost.user or null != null) patternHost.user; 148 extraOptions = { 149 RemoteCommand = "export PATH=$HOME/.nix-profile/bin:$PATH; zmx attach %k"; 150 RequestTTY = "yes"; 151 ControlPath = "~/.ssh/cm-%r@%h:%p"; 152 ControlMaster = "auto"; 153 ControlPersist = "10m"; 154 }; 155 }; 156 } 157 ) cfg.zmx.hosts 158 ) 159 else 160 { }; 161 162 # Default match block for extraConfig 163 defaultBlock = 164 if cfg.extraConfig != "" then 165 { 166 "*" = { }; 167 } 168 else 169 { }; 170 in 171 defaultBlock // hostConfigs // zmxPatternHosts; 172 173 extraConfig = cfg.extraConfig; 174 }; 175 176 # Add shell aliases for zmx usage 177 programs.zsh.shellAliases = mkIf cfg.zmx.enable { 178 zmls = "zmx list"; 179 zmk = "zmx kill"; 180 zma = "zmx attach"; 181 ash = "autossh -M 0 -q"; 182 }; 183 }; 184}