How To Setup a Convenient SSH Agent
Motivation
(Feel free to skip this section)
If you don't use a full desktop environment, you might have configured an SSH agent in your .bashrc
that makes connecting to some hosts more convenient. In my case I installed keychain
, which served it's purpose, but at the small inconvenience of me having to type in a password twice every time I turn on my PC: once to login, and once to unlock my SSH key.
These pain points tugged at me for a while. Why do I have to authenticate myself again to unlock my SSH key if I just authenticated myself as much as could be reasonably desired only moments ago? Can't we link these authentication actions together so that logging in is enough to unlock the SSH key as well? It seemed vaguely possible to me with some complicated PAM magic, but thankfully GNOME Keychain has not only already done all of that PAM magic for us, but provides a keyring management interface, a clean GUI password prompt, and an SSH agent implementation. I admit that I feel a bit humbled for eschewing the desktop environment to go my own way, only to come crawling back to the componenents that a desktop environment would have graciously provided without me even asking. But I digress.
Another problem the method I describe here solves is that of providing SSH agent environment variables to all graphical programs, not just terminal ones. In older X11 graphical environments, this wasn't a problem because they would be started by a bash shell which reads .bashrc
. But with the coming of Wayland, this is no longer the case, so we need another way to set environment variables for all programs. This should allow me to start virt-manager
and the like from the normal application launcher instead of the terminal.
Setup
Packages
Install gnome-keyring
(the daemon) and seahorse
(the GUI).
Gnome Keyring Daemon
systemctl --user enable --now gnome-keyring-daemon.service
Environment Variables
There are a number of ways to set environment variables for the entire graphical session, but I found using systemd's new environment.d
feature to be the most straightforward and well-supported way of doing so.
Create the file ~/.config/environment.d/50-ssh-auth-sock-gcr.conf
with the following contents:
SSH_AUTH_SOCK=$XDG_RUNTIME_DIR/gcr/ssh
Keyrings
This is the part I'm still fuzzy on. As far as I can tell, there is no documented or supported way of manually creating keyrings in Seahorse that contain SSH keys and are unlocked on login. Instead you just have to attempt to use an SSH key, and when it prompts for the password, check a box that says "Unlock this key at login". But there's actually another step that needs to happen, which is that a keyring needs to be created to store the key, and what makes it funky is that only one if these things can happen per login attempt. So this is the flow I suggest.
- Try to SSH with your key. Enter the password for the key and check the box saying you want to unlock this key at login. It will then ask you to create a keyring to store the key in (this is the Default Keyring), for which you should choose whatever password you like.
- Reboot (this might be unnecessary, but it at least ensures the keyring daemon is in a fresh and consistent state)
- Try to SSH with your key. It will ask you to unlock the Default Keyring. Enter the password you created before and check the box saying you would like to unlock this keyring at login.
Now there should be two keyrings. The "Default Keyring", which has your SSH key inside of it. And the "Login" keyring, which has the password to the "Default Keyring" and will unlock that upon login.