Forward GnuPG agent from key-host to signing-host
Run gpg once as your to create the directory structure
gpg --list-keys
Make the public key of the signing key available on the signing host after completing all the key host steps (last command in that section).
Disable gpg-agent startup via systemd by masking the sockets:
sudo systemctl --global mask gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socket
killall gpg-agent
If you want to maintain the auto start and stop of gpg-agent on the host you need to do the following:
Create a file /etc/ssh/sshd_config.d/gpg-cleanup.conf to include the line:
StreamLocalBindUnlink yes
Add this line to your user's $HOME/.bashrc:
gpgconf --create-socketdir
Add this line to the file: $HOME/.gnupg/gpg-agent.conf
extra-socket $HOME/.gnupg/S.gpg-agent.extra
Reload your current gpg-agent:
gpg-connect-agent reloadagent /bye
Edit $HOME/.ssh/config to forward the gpg-agent socket.
Note this doesn't support ssh config variables so you need to use the full path.
Forwarding from macOS to Linux:
host signinghost
hostname remotehost.example.com
User yourusername
RemoteForward /home/<user>/.gnupg/S.gpg-agent /Users/<user>/.gnupg/S.gpg-agent.extra
Forwarding from macOS to systemd based Linux, use id -u on the remote system to find your UID:
host signinghost
hostname systemd-host.example.com
User yourusername
RemoteForward /run/user/<remote UID>/gnupg/S.gpg-agent /Users/<user>/.gnupg/S.gpg-agent.extra
Forwarding from one systemd based Linux to another, use id -u on the both systems to find your UIDs:
host signinghost
hostname systemd-host.example.com
User yourusername
RemoteForward /run/user/<SIGN-HOST-UID>/gnupg/S.gpg-agent /run/user/<KEY-HOST-UID>/gnupg/S.gpg-agent.extra
Additionally, for linux based key hosts, run the following (or add it to ~/.bashrc or equivalent shell rc), to tell gpg-agent the terminal where pinentry should pop up the keyphrase dialog:
$ export GPG_TTY=$(tty)
$ gpg-connect-agent updatestartuptty /bye
Copy the GPG public keyring to the signing host (now named signinghost via .ssh/config):
scp ~/.gnupg/pubring.kbx signinghost:.gnupg/
Instead of copying the public keyring, you can instead import the public key of your GPG signing key on the signing host, if you have that handy:
gpg --import mypublickey.pub
Get the key ID of the key from the server
gpg --list-keys
Trust the signing key
gpg --edit-key $KEYID_FROM_LIST_KEY_OUTPUT
....................
..Key details here..
....................
gpg> trust
....................
..Key details here..
....................
Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)
1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu
Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y
gpg> quit
Now test that the gpg-agent works on the key host:
echo "test" | gpg --encrypt -r $MYKEYID
echo "test" | gpg --encrypt -r $MYKEYID > output
gpg --decrypt output
copy the encryted file to the signing host (now named signinghost via .ssh/config) and try decrypting there:
scp output signinghost:
ssh $SIGNING_HOST
gpg --decrypt output
The gpg-agent should be able to use the key from the key host on the signing host.
- Debian 12 key host, with Debian 12 signing host
- Debian 11 key host, with Debian 12 signing host