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
 | 
						|
          );
 | 
						|
        };
 | 
						|
      })
 | 
						|
    ]
 | 
						|
  );
 | 
						|
}
 |