iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🔐

Delegating OpenSSH Key Management to gpg-agent on Ubuntu: The Definitive Guide

に公開

In OpenSSH, you can delegate key management to GnuPG by replacing ssh-agent with GnuPG's gpg-agent. Incidentally, gpg-agent is the core component for GnuPG private key management; it streamlines user key operations by caching passphrases for a certain period (it does not cache the private keys themselves). It is also possible to coordinate between remote gpg-agents.

However, Debian-based distributions, including Ubuntu, are configured under the assumption that ssh-agent is used for OpenSSH key management. Therefore, several configuration changes seem to be required to switch to gpg-agent. This article briefly summarizes those configuration changes[1].

Changing Ubuntu Settings

Checking the gpg-agent Service

First, check if gpg-agent is running as a service.

$ systemctl --user status gpg-agent
● gpg-agent.service - GnuPG cryptographic agent and passphrase cache
     Loaded: loaded (/usr/lib/systemd/user/gpg-agent.service; static)
     Active: inactive (dead)
TriggeredBy: ● gpg-agent-extra.socket
             ● gpg-agent-browser.socket
             ● gpg-agent-ssh.socket
             ● gpg-agent.socket
       Docs: man:gpg-agent(1)

The output above shows the state immediately after login where gpg-agent is not running, but it is set to start upon access to the four sockets indicated by TriggeredBy. If gpg-agent-ssh.socket is included among these sockets, you are good to go. Incidentally, you can check the actual socket locations using the gpgconf command.

$ gpgconf --list-dirs | grep socket
socketdir:/run/user/1000/gnupg
dirmngr-socket:/run/user/1000/gnupg/S.dirmngr
agent-ssh-socket:/run/user/1000/gnupg/S.gpg-agent.ssh
agent-extra-socket:/run/user/1000/gnupg/S.gpg-agent.extra
agent-browser-socket:/run/user/1000/gnupg/S.gpg-agent.browser
agent-socket:/run/user/1000/gnupg/S.gpg-agent

Changing Xsession.options

Next, check the /etc/X11/Xsession.options file.

/etc/X11/Xsession.options
# $Id: Xsession.options 189 2005-06-11 00:04:27Z branden $
#
# configuration options for /etc/X11/Xsession
# See Xsession.options(5) for an explanation of the available options.
allow-failsafe
allow-user-resources
allow-user-xsession
use-ssh-agent
use-session-dbus

Replace the use-ssh-agent entry with no-use-ssh-agent. Please note that administrative privileges are required for this change. Be sure to work while making backups.

Adding gnome-keyring-ssh.desktop to autostart

There is a gnome-keyring-ssh.desktop file in the /etc/xdg/autostart/ directory. First, copy this file to the ~/.config/autostart/ directory. Create the directory if it does not exist.

$ cp /etc/xdg/autostart/gnome-keyring-ssh.desktop ~/.config/autostart/

The content of the gnome-keyring-ssh.desktop file is text; append the following line to the end of the copied file:

Hidden=true

[Update 2021-06-05] For Ubuntu 21.04

In Ubuntu 21.04, released in April 2021, this setting doesn't seem to work. In this case, as a temporary measure, you can directly specify the SSH_AUTH_SOCK environment variable in your .bashrc like this (information requested):

export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
dbus-update-activation-environment --systemd SSH_AUTH_SOCK

gpg-agent.conf Configuration

Finally, write the following content into the ~/.gnupg/gpg-agent.conf file. If the gpg-agent.conf file does not exist, please create it.

~/.gnupg/gpg-agent.conf
enable-ssh-support
default-cache-ttl-ssh 1800
max-cache-ttl-ssh 7200

The bottom two options are optional and have the following meanings:

Option Name Content
default-cache-ttl-ssh Specifies the expiration period in seconds for the most recently accessed cache entry. Default is 1800
max-cache-ttl-ssh Specifies the maximum expiration period in seconds for cache entries. The cache is cleared after this period regardless of access. Default is 7200

Don't set the expiration period too long, as it increases the risk of leakage (haha).

This completes the setup. Log in again just to be sure.

Checking Environment Variables

After logging back in, check the environment variables.

$ env | grep SSH
SSH_AUTH_SOCK=/run/user/1000/gnupg/S.gpg-agent.ssh

If the value of the SSH_AUTH_SOCK environment variable is the gpg-agent socket as shown above, you're all set.

Key Management with GnuPG

Registering Existing OpenSSH Authentication Keys

Once the above settings are complete, you can easily register an existing OpenSSH authentication key to the GnuPG keyring using the ssh-add command.

$ ssh-add ./id_ecdsa
Enter passphrase for ./id_ecdsa: 
Identity added: ./id_ecdsa (alice@example.com)

At this point, separate from the passphrase entry via the ssh-add command, a passphrase setup will occur via GnuPG's Pinentry (you will need to enter it in two places, including confirmation).

Pinentry

Authentication keys registered in the GnuPG keyring are protected by this passphrase.

To reiterate an important point, the registered private key is not cached but is stored in the GnuPG keyring (the ~/.gnupg/private-keys-v1.d/ directory). Additionally, information about the added key is included in the ~/.gnupg/sshcontrol file as follows:

# ECDSA key added on: 2020-06-01 14:05:35
# Fingerprints:  MD5:e4:5b:66:a6:03:9a:a4:0e:f2:1b:a5:04:72:93:f3:f0
#                SHA256:DtXgQm9rz7Dc5M5yWu/CNVo341o1rcfN9UCyYu+SZU4
A5353D587000D820669B0BD55A0B4AD6897458DB 0

Incidentally, A5353D587000D820669B0BD55A0B4AD6897458DB is a value called a keygrip, an ID that represents the key uniformly regardless of its type. Keys stored in the ~/.gnupg/private-keys-v1.d/ directory are saved with filenames linked to the keygrip, such as A5353D587000D820669B0BD55A0B4AD6897458DB.key. Also, the 0 at the end apparently refers to the cache period (in seconds). If it is greater than 0, it probably takes precedence over the specification in the gpg-agent.conf file.

Note that you can disable the use of a key by adding a ! mark at the beginning of the line.

Setting a GnuPG Key as an OpenSSH Authentication Key

You can also set a GnuPG key as an OpenSSH authentication key. However, you need to create a dedicated authentication key. For details, please refer to my article:

https://text.baldanders.info/openpgp/ssh-key-management-with-gnupg/

For example, if you have a key like this:

$ gpg --list-keys --with-keygrip alice
pub   ed25519 2021-01-06 [SC] [Expires: 2021-01-13]
      011C720B03D2E1D6BCFA98391DFF44901121B61D
      Keygrip = 97249ABEB2A2FD9E88F6723BB19D4F84B90E261A
uid           [ultimate] Alice <alice@example.com>
sub   cv25519 2021-01-06 [E]
      Keygrip = 96CB831965E1A7EB4705577D6A7CB7F9E05C8192
sub   ed25519 2021-01-06 [A]
      Keygrip = F5C774B5B418B6E0B5B7942F93DE82BF2FEF4C8E

The subkey marked with [A] at the end can be used as an OpenSSH authentication key. You register the keygrip value of this key in the ~/.gnupg/sshcontrol file.

$ echo F5C774B5B418B6E0B5B7942F93DE82BF2FEF4C8E 0 >> ~/.gnupg/sshcontrol

Checking Registered Keys

Registered keys can be checked with the ssh-add -l command. To extract the public key, you can use the ssh-add -L command. If it is a key created with GnuPG, you can also extract it using:

$ gpg --export-ssh-key alice
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFfjejx/Saej929myfZoBQAKgusPi2iiOxdZZfpCLxh5 openpgp:0x390C3E49

Reference Pages

https://curiouslynerdy.com/gpg-agent-for-ssh-on-ubuntu/

https://text.baldanders.info/remark/2020/06/upgrade-openssh-key/

https://text.baldanders.info/openpgp/build-gnupg-in-ubuntu/

Reference Books

https://www.amazon.co.jp/dp/B015643CPE

脚注
  1. For Windows, although it is an older article, please refer to my piece "GnuPG for Windows: About gpg-agent" (Japanese). ↩︎

GitHubで編集を提案

Discussion