107 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| {
 | |
|   pkgs,
 | |
|   config,
 | |
|   osConfig,
 | |
|   lib,
 | |
|   ...
 | |
| }: {
 | |
|   options.programs.openssh = {
 | |
|     enable = lib.mkEnableOption "should we enable openssh";
 | |
|     authorizedKeys = lib.mkOption {
 | |
|       type = lib.types.listOf lib.types.str;
 | |
|       default = [];
 | |
|     };
 | |
|     hostKeys = lib.mkOption {
 | |
|       type = lib.types.listOf lib.types.attrs;
 | |
|       default = [];
 | |
|       example = [
 | |
|         {
 | |
|           type = "rsa";
 | |
|           bits = 4096;
 | |
|           path = "${config.home.username}_${osConfig.networking.hostName}_rsa";
 | |
|           rounds = 100;
 | |
|           openSSHFormat = true;
 | |
|         }
 | |
|         {
 | |
|           type = "ed25519";
 | |
|           path = "${config.home.username}_${osConfig.networking.hostName}_ed25519";
 | |
|           rounds = 100;
 | |
|           comment = "key comment";
 | |
|         }
 | |
|       ];
 | |
|       description = ''
 | |
|         NixOS can automatically generate SSH host keys.  This option
 | |
|         specifies the path, type and size of each key.  See
 | |
|         {manpage}`ssh-keygen(1)` for supported types
 | |
|         and sizes. Paths are relative to home directory
 | |
|       '';
 | |
|     };
 | |
|   };
 | |
| 
 | |
|   config = lib.mkIf config.programs.openssh.enable (
 | |
|     lib.mkMerge [
 | |
|       (
 | |
|         lib.mkIf ((builtins.length config.programs.openssh.hostKeys) != 0) {
 | |
|           services.ssh-agent.enable = true;
 | |
|           programs.ssh = {
 | |
|             enable = true;
 | |
|             enableDefaultConfig = false;
 | |
|             matchBlocks = {
 | |
|               "*" = {
 | |
|                 compression = true;
 | |
|                 addKeysToAgent = "confirm";
 | |
|               };
 | |
|             };
 | |
|             extraConfig = lib.strings.concatLines (
 | |
|               builtins.map (hostKey: "IdentityFile ~/.ssh/${hostKey.path}") config.programs.openssh.hostKeys
 | |
|             );
 | |
|           };
 | |
| 
 | |
|           systemd.user.services = builtins.listToAttrs (
 | |
|             builtins.map (hostKey:
 | |
|               lib.attrsets.nameValuePair "ssh-gen-keys-${hostKey.path}" {
 | |
|                 Install = {
 | |
|                   WantedBy = ["default.target"];
 | |
|                 };
 | |
|                 Service = let
 | |
|                   path = "${config.home.homeDirectory}/.ssh/${hostKey.path}";
 | |
|                 in {
 | |
|                   Restart = "always";
 | |
|                   Type = "simple";
 | |
|                   ExecStart = "${
 | |
|                     pkgs.writeShellScript "ssh-gen-keys" ''
 | |
|                       if ! [ -s "${path}" ]; then
 | |
|                           if ! [ -h "${path}" ]; then
 | |
|                               rm -f "${path}"
 | |
|                           fi
 | |
|                           mkdir -p "$(dirname '${path}')"
 | |
|                           chmod 0755 "$(dirname '${path}')"
 | |
|                           ${pkgs.openssh}/bin/ssh-keygen \
 | |
|                             -t "${hostKey.type}" \
 | |
|                             ${lib.optionalString (hostKey ? bits) "-b ${toString hostKey.bits}"} \
 | |
|                             ${lib.optionalString (hostKey ? rounds) "-a ${toString hostKey.rounds}"} \
 | |
|                             ${lib.optionalString (hostKey ? comment) "-C '${hostKey.comment}'"} \
 | |
|                             ${lib.optionalString (hostKey ? openSSHFormat && hostKey.openSSHFormat) "-o"} \
 | |
|                             -f "${path}" \
 | |
|                             -N ""
 | |
|                           chown ${config.home.username} ${path}*
 | |
|                           chgrp ${config.home.username} ${path}*
 | |
|                       fi
 | |
|                     ''
 | |
|                   }";
 | |
|                 };
 | |
|               })
 | |
|             config.programs.openssh.hostKeys
 | |
|           );
 | |
|         }
 | |
|       )
 | |
|       (lib.mkIf config.impermanence.enable {
 | |
|         home.persistence."/persist${config.home.homeDirectory}" = {
 | |
|           files = lib.lists.flatten (
 | |
|             builtins.map (hostKey: [".ssh/${hostKey.path}" ".ssh/${hostKey.path}.pub"]) config.programs.openssh.hostKeys
 | |
|           );
 | |
|         };
 | |
|       })
 | |
|     ]
 | |
|   );
 | |
| }
 |