DEV Community

Cover image for SSH with gpg-agent on systemd
Erik Huelsmann
Erik Huelsmann

Posted on • Edited on

SSH with gpg-agent on systemd

There's a lot of information floating around on the web explaining how to replace ssh-agent with gpg-agent. This is important if you - like me - want to use a yubikey or smart card device to store the private key of your SSH key pair.

Unfortunately, none of the advice worked for me with the following system setup:

  • systemd v249
  • GNOME desktop 42.9
  • Ubuntu 22.04

Although the above is quite specific, I expect the information below to be much more generally applicable. [[edit: this article also applies to Ubuntu 24.04; I learned that after upgrading]]

Prerequisite for Yubikeys and smart cards

GPG needs pcscd and scdaemon to be able to access private keys stored on a yubikey or smart card:

$ sudo apt install pcscd scdaemon
$ systemctl enable --now pcscd
$ systemctl enable --now scdaemon
Enter fullscreen mode Exit fullscreen mode

After running these commands, gpg --card-status should provide you with information about your smart card.

Configuring GPG with ssh-agent support

To enable ssh-agent support in gpg-agent, add the following to your gpg-agent.conf:

# ~/.gnupg/gpg-agent.conf
enable-ssh-support
Enter fullscreen mode Exit fullscreen mode

Enabling gpg-agent (per user)

gpg-agent is a per-user service, which systemd facilitates with the --user flag on the systemctl command:

$ systemctl enable --user --now gpg-agent.socket
$ systemctl enable --user --now gpg-agent-ssh.socket
Enter fullscreen mode Exit fullscreen mode

If you forget to add the .socket extension, systemctl will throw an error about a missing [Install] section in the service definition. Please note that the sockets are to be enabled; the service itself is to be left untouched.

Verifying status of the GPG agent can be done using:

$ systemctl status --user gpg-agent.socket
$ systemctl status --user gpg-agent-ssh.socket
Enter fullscreen mode Exit fullscreen mode

Although the service is now running, the environment shows an incorrect value for SSH_AUTH_SOCK (/run/user/<uid>/keyring/ssh).

Fixing SSH_AUTH_SOCK

There are several configurations blocking successful use of gpg-agent for SSH, causing the value of SSH_AUTH_SOCK to be incorrect.

Disable ssh-agent user service

If it is enabled, this service needs to be disabled, as it is conflicting:

$ systemctl disable --user --now ssh-agent
Enter fullscreen mode Exit fullscreen mode

Disable Xsession.options ssh-agent

The Xsession script tries to start an ssh-agent. This can be disabled by modifying /etc/X11/Xsession.options and /etc/X11/Xsession.options.d/*.conf, making sure the last file loaded contains:

no-use-ssh-agent
Enter fullscreen mode Exit fullscreen mode

This is best achieved by creating a file named /etc/X11/Xsession.options.d/zz-no-ssh-agent.conf with that content.

Disable GNOME Keyring (gnome-keyring-ssh.desktop)

GNOME Keyring tries to start an SSH agent if none is running. The way to disable this is by executing the following commands - which are different from those published all around:

$ cp /etc/xdg/autostart/gnome-keyring-ssh.desktop ~/.config/autostart/gnome-keyring-ssh.desktop
$ echo "X-GNOME-Autostart-enabled=false" >> ~/.config/autostart/gnome-keyring-ssh.desktop
$ echo "Hidden=true" >> ~/.config/autostart/gnome-keyring-ssh.desktop
Enter fullscreen mode Exit fullscreen mode

The "Hidden=true" addition is advertized all around the web, but didn't work for me.

Setting SSH_AUTH_SOCK

Using systemd to manage gpg-agent has one drawback: systemd doesn't set environment variables in the user shell session. This can be solved by adding this snippet to the user's bashrc:

# to be appended to ~/.bashrc
if [[ -z "$SSH_AUTH_SOCK" ]]
then
  if [[ -e "/run/user/$(id -u)/gnupg/S.gpg-agent.ssh" ]]
  then
    export SSH_AUTH_SOCK="/run/user/$(id -u)/gnupg/S.gpg-agent.ssh"
  fi
fi
Enter fullscreen mode Exit fullscreen mode

Conclusion

Yubikey and smart card support with private keys on the key or card does not come out of the box, even in this day and age, but with a bit of configuration, setting up private keys on a smart card and making it work under GNOME, is doable.

Top comments (0)