Skip to content

Instantly share code, notes, and snippets.

Forked from surhudm/
Last active February 26, 2024 03:48
  • Star 37 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save TimJDFletcher/85fafd023c81aabfad57454111c1564d to your computer and use it in GitHub Desktop.
GnuPG agent forwarding

Forward GnuPG agent from macOS to Linux

On the remote machine

Run gpg once as your to create the directory structure

gpg --list-keys

For headless systemd based hosts

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

For interactive systemd hosts

If you want to maintain the auto start and stop of gpg-agent on the host you need to do the following:

Edit /etc/ssh/sshd_config to include the line:

StreamLocalBindUnlink yes

Add this line to your user's $HOME/.bashrc:

gpgconf --create-socketdir

On the local machine

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 gpgtunnel
    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 gpgtunnel
    User yourusername
    RemoteForward /run/user/<remote UID>/gnupg/S.gpg-agent /Users/<user>/.gnupg/S.gpg-agent.extra

Copy the public half of your keys to the remote machine:

scp $HOME/.gnupg/pubring.gpg gpgtunnel:$HOME/.gnupg/

You only have to copy the public half of the private key you are going to use, if you have that handy you can just copy it over and then use gpg --import

Now test that the gpg-agent works on the local machine:

echo "test" | gpg --encrypt -r $MYKEYID 
echo "test" | gpg --encrypt -r $MYKEYID > output
gpg --decrypt output

Now ssh to remote machine

scp output gpgtunnel:
ssh gpgtunnel
gpg --decrypt output

The gpg-agent should be able to use your authentication on the local machine.


Copy link

I got it to work between OSX 11.5 and ubuntu 18.04. gpg && gpg-agent 2.3.2 (remote: 2.2.4)
The , should be replaced by the actual values.

On OSX, the pinentry-mac should be installed
Disclaimer: its possibly not the minimal requited configuration, I could not change the StreamLocalBindUnlink of the the remote system. So systemd part might not be needed.

Local configuration:

GPG agent:~/.gnupg/gpg-agent.conf

extra-socket /Users/<user>/.gnupg/S.gpg-agent.extra
pinentry-program /usr/local/bin/pinentry-mac

ssh (~/.ssh/config)

Host remote-host
   RemoteForward /run/user/<uid>/gnupg/S.gpg-agent /Users/<user>/.gnupg/S.gpg-agent.extra

Remote configuration:

Remote gpg: ~/.gnupg/gpg.conf

default-key <public key>

No interference from systemd.
I am not sure if its needed or has any effect.

systemctl --user disable gpg-agent-browser.socket gpg-agent-extra.socket gpg-agent-ssh.socket gpg-agent.socket
mkdir -p ~/.config/systemd/user/
cd ~/.config/systemd/user/
ln -s /dev/null gpg-agent-browser.socket 
ln -s /dev/null gpg-agent-extra.socket
ln -s /dev/null gpg-agent.socket
ln -s /dev/null gpg-agent-ssh.socket
systemctl --user daemon-reload

Initialize gpg

gpg --list-keys

Export public key from local machine to remote machine

On local machine: Export public key to remote host
gpg --export -a Public-key | ssh remote-host 'gpg --import -'


On remote machine:

gpg --decrypt output

That should prompt the pin entry on the local machine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment