ssh-agent 🤝 systemd user-service
Marrying ssh-agent to a systemd user-service finally gave me peace of mind and saved me some keystrokes.
I may not use SSH as much as I used to, but I still use it regularly. Which is why "not having to enter the passphrase for my SSH-key every single time I open up a new shell" is a big deal for me - and ssh-agent
, which is part of openssh-client
on Debian, makes exactly that possible.
In theory at least. While I never had an issue with it while using a desktop environment like GNOME or MATE, I always struggled to get it to work reliably when running my old, trusted i3. To the point that I eventually trashed my semi-working hackish setup and simply ran keychain
, which is pretty much a minimal wrapper around ssh-agent
.
However .. this was a constant thorn in my side. Not because there were any issues with it, it worked flawlessly. But it bothered me that I had to rely on another piece of software just to achieve something that should, and could, be reliably performed by ssh-agent
on its own.
Which is why I eventually set down for an hour, read a couple of manpages and posts on the Internet, and came to the conclusion that it's ultimately rather trivial.
I ended up setting up a systemd user service for ssh-agent
(located in ~/.config/systemd/user/ssh-agent.service
:
[Unit]
Description=SSH key agent
[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStart=/usr/bin/ssh-agent -D -a ${SSH_AUTH_SOCK}
[Install]
WantedBy=default.target
After enabling / starting it (systemctl --user enable --now ssh-agent.service
) I simply had to point my shells to the agent, by adding this to my ~/.bashrc
:
export SSH_AUTH_SOCK="${XDG_RUNTIME_DIR}/ssh-agent.socket"
Last but not least I instructed ssh
to use the agent automatically, adding the following lines to ~/.ssh/config
:
Host *
IdentitiesOnly yes
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
ForwardAgent no
Obviously, adjust the path according to the location of your key.
A lot has been written about the many potential risks that come with using ssh-agent
. And yes, if someone has the appropriate privileges on your system, they could steal your keys. But they could also do that without the agent in that scenario. Configuring ssh-agent
like this however ensures that regular users shouldn't pose a threat:
- Per-user runtime dir:
%t/ssh-agent.socket
expands to$XDG_RUNTIME_DIR/ssh-agent.socket
. On modern distributions this directory is created bysystemd-logind
at login with mode 0700 and your user as the owner. This should ensure other users can't traverse. - Agent checks the peer UID:
ssh-agent
validates that the connecting process has the same UID as the agent. So even if another user could reach the socket (which they really shouldn't be able to), the agent would still refuse them.
Of course there are edge cases, for example a system without XDG_RUNTIME_DIR
. But if you are encountering these edge cases I trust that you know what you are doing well enough so that you are not relying on my notes.