Start ssh-agent as a user unit

This has some advantages:

* You get ssh-agent regardless of how you logged in. Previously it was
only started for X11 sessions.

* All sessions of a user share the same agent. So if you added a key
on tty1, it will also be available on tty2.

* Systemd will restart ssh-agent if it dies.

* $SSH_AUTH_SOCK now points to the /run/user/<uid> directory, which is
more secure than /tmp.

For bonus points, we should patch ssh-agent to support socket-based
activation...

+38 -26
+1 -1
nixos/modules/config/gnu.nix
··· 36 # GNU lsh. 37 services.openssh.enable = false; 38 services.lshd.enable = true; 39 - services.xserver.startOpenSSHAgent = false; 40 services.xserver.startGnuPGAgent = true; 41 42 # TODO: GNU dico.
··· 36 # GNU lsh. 37 services.openssh.enable = false; 38 services.lshd.enable = true; 39 + programs.ssh.startAgent = false; 40 services.xserver.startGnuPGAgent = true; 41 42 # TODO: GNU dico.
+33
nixos/modules/programs/ssh.nix
··· 47 for help. 48 ''; 49 }; 50 }; 51 }; 52 53 config = { ··· 71 target = "ssh/ssh_config"; 72 } 73 ]; 74 }; 75 }
··· 47 for help. 48 ''; 49 }; 50 + 51 + startAgent = mkOption { 52 + type = types.bool; 53 + default = true; 54 + description = '' 55 + Whether to start the OpenSSH agent when you log in. The OpenSSH agent 56 + remembers private keys for you so that you don't have to type in 57 + passphrases every time you make an SSH connection. Use 58 + <command>ssh-add</command> to add a key to the agent. 59 + ''; 60 + }; 61 + 62 }; 63 + 64 }; 65 66 config = { ··· 84 target = "ssh/ssh_config"; 85 } 86 ]; 87 + 88 + # FIXME: this should really be socket-activated for über-awesomeness. 89 + systemd.user.services.ssh-agent = 90 + { enable = cfg.startAgent; 91 + description = "SSH Agent"; 92 + wantedBy = [ "default.target" ]; 93 + serviceConfig = 94 + { ExecStart = "${pkgs.openssh}/bin/ssh-agent -a %t/ssh-agent"; 95 + Type = "forking"; 96 + Restart = "on-failure"; 97 + }; 98 + }; 99 + 100 + environment.extraInit = optionalString cfg.startAgent 101 + '' 102 + if [ -z "$SSH_AUTH_SOCK" -a -n "$XDG_RUNTIME_DIR" ]; then 103 + export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent" 104 + fi 105 + ''; 106 + 107 }; 108 }
+1
nixos/modules/rename.nix
··· 103 ++ obsolete [ "services" "sshd" "gatewayPorts" ] [ "services" "openssh" "gatewayPorts" ] 104 ++ obsolete [ "services" "sshd" "permitRootLogin" ] [ "services" "openssh" "permitRootLogin" ] 105 ++ obsolete [ "services" "xserver" "startSSHAgent" ] [ "services" "xserver" "startOpenSSHAgent" ] 106 ++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "xbmc" ] 107 108 # KDE
··· 103 ++ obsolete [ "services" "sshd" "gatewayPorts" ] [ "services" "openssh" "gatewayPorts" ] 104 ++ obsolete [ "services" "sshd" "permitRootLogin" ] [ "services" "openssh" "permitRootLogin" ] 105 ++ obsolete [ "services" "xserver" "startSSHAgent" ] [ "services" "xserver" "startOpenSSHAgent" ] 106 + ++ obsolete [ "services" "xserver" "startOpenSSHAgent" ] [ "programs" "ssh" "startAgent" ] 107 ++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "xbmc" ] 108 109 # KDE
-11
nixos/modules/services/x11/display-managers/default.nix
··· 51 52 ''} 53 54 - ${optionalString cfg.startOpenSSHAgent '' 55 - if test -z "$SSH_AUTH_SOCK"; then 56 - # Restart this script as a child of the SSH agent. (It is 57 - # also possible to start the agent as a child that prints 58 - # the required environment variabled on stdout, but in 59 - # that mode ssh-agent is not terminated when we log out.) 60 - export SSH_ASKPASS=${pkgs.x11_ssh_askpass}/libexec/x11-ssh-askpass 61 - exec ${pkgs.openssh}/bin/ssh-agent "$0" "$sessionType" 62 - fi 63 - ''} 64 - 65 ${optionalString cfg.startGnuPGAgent '' 66 if test -z "$SSH_AUTH_SOCK"; then 67 # Restart this script as a child of the GnuPG agent.
··· 51 52 ''} 53 54 ${optionalString cfg.startGnuPGAgent '' 55 if test -z "$SSH_AUTH_SOCK"; then 56 # Restart this script as a child of the GnuPG agent.
+3 -14
nixos/modules/services/x11/xserver.nix
··· 201 ''; 202 }; 203 204 - startOpenSSHAgent = mkOption { 205 - type = types.bool; 206 - default = true; 207 - description = '' 208 - Whether to start the OpenSSH agent when you log in. The OpenSSH agent 209 - remembers private keys for you so that you don't have to type in 210 - passphrases every time you make an SSH connection. Use 211 - <command>ssh-add</command> to add a key to the agent. 212 - ''; 213 - }; 214 - 215 startGnuPGAgent = mkOption { 216 type = types.bool; 217 default = false; ··· 400 hardware.opengl.videoDrivers = mkIf (cfg.videoDriver != null) [ cfg.videoDriver ]; 401 402 assertions = 403 - [ { assertion = !(cfg.startOpenSSHAgent && cfg.startGnuPGAgent); 404 message = 405 '' 406 - The OpenSSH agent and GnuPG agent cannot be started both. 407 - Choose between `startOpenSSHAgent' and `startGnuPGAgent'. 408 ''; 409 } 410 { assertion = config.security.polkit.enable;
··· 201 ''; 202 }; 203 204 startGnuPGAgent = mkOption { 205 type = types.bool; 206 default = false; ··· 389 hardware.opengl.videoDrivers = mkIf (cfg.videoDriver != null) [ cfg.videoDriver ]; 390 391 assertions = 392 + [ { assertion = !(config.programs.ssh.startAgent && cfg.startGnuPGAgent); 393 message = 394 '' 395 + The OpenSSH agent and GnuPG agent cannot be started both. Please 396 + choose between ‘programs.ssh.startAgent’ and ‘services.xserver.startGnuPGAgent’. 397 ''; 398 } 399 { assertion = config.security.polkit.enable;