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 36 # GNU lsh. 37 37 services.openssh.enable = false; 38 38 services.lshd.enable = true; 39 - services.xserver.startOpenSSHAgent = false; 39 + programs.ssh.startAgent = false; 40 40 services.xserver.startGnuPGAgent = true; 41 41 42 42 # TODO: GNU dico.
+33
nixos/modules/programs/ssh.nix
··· 47 47 for help. 48 48 ''; 49 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 + 50 62 }; 63 + 51 64 }; 52 65 53 66 config = { ··· 71 84 target = "ssh/ssh_config"; 72 85 } 73 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 + 74 107 }; 75 108 }
+1
nixos/modules/rename.nix
··· 103 103 ++ obsolete [ "services" "sshd" "gatewayPorts" ] [ "services" "openssh" "gatewayPorts" ] 104 104 ++ obsolete [ "services" "sshd" "permitRootLogin" ] [ "services" "openssh" "permitRootLogin" ] 105 105 ++ obsolete [ "services" "xserver" "startSSHAgent" ] [ "services" "xserver" "startOpenSSHAgent" ] 106 + ++ obsolete [ "services" "xserver" "startOpenSSHAgent" ] [ "programs" "ssh" "startAgent" ] 106 107 ++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "xbmc" ] 107 108 108 109 # KDE
-11
nixos/modules/services/x11/display-managers/default.nix
··· 51 51 52 52 ''} 53 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 54 ${optionalString cfg.startGnuPGAgent '' 66 55 if test -z "$SSH_AUTH_SOCK"; then 67 56 # Restart this script as a child of the GnuPG agent.
+3 -14
nixos/modules/services/x11/xserver.nix
··· 201 201 ''; 202 202 }; 203 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 204 startGnuPGAgent = mkOption { 216 205 type = types.bool; 217 206 default = false; ··· 400 389 hardware.opengl.videoDrivers = mkIf (cfg.videoDriver != null) [ cfg.videoDriver ]; 401 390 402 391 assertions = 403 - [ { assertion = !(cfg.startOpenSSHAgent && cfg.startGnuPGAgent); 392 + [ { assertion = !(config.programs.ssh.startAgent && cfg.startGnuPGAgent); 404 393 message = 405 394 '' 406 - The OpenSSH agent and GnuPG agent cannot be started both. 407 - Choose between `startOpenSSHAgent' and `startGnuPGAgent'. 395 + The OpenSSH agent and GnuPG agent cannot be started both. Please 396 + choose between ‘programs.ssh.startAgent’ and ‘services.xserver.startGnuPGAgent’. 408 397 ''; 409 398 } 410 399 { assertion = config.security.polkit.enable;