== Forwarding gpg-agent to a remote system over SSH == GnuPG 2.1 enables you to forward the GnuPG-Agent to a remote system. That means that you can keep your secret keys on a local machine (or even a hardware token like a smartcard or on a [[https://github.com/me21/gnuk|GNUK]]). You need at least GnuPG 2.1.1 on both systems. === GnuPG configuration === For really old versions of GnuPG (< 2.1.17) you need to edit your gpg-agent.conf to configure an extra socket. The extra socket is more restricted then the normal socket and Pinentry messages will differ when gpg-agent is accessed over this socket: {{{ extra-socket /home//.gnupg/S.gpg-agent.extra }}} Replace with your actual username. Current versions of GnuPG create the socket by default. ==== GnuPG on the remote system ==== It is important to note that to work properly GnuPG on the remote system still needs your public keys. So you have to make sure they are available on the remote system even if your secret keys are not. === SSH Configuration === **Note:** With GnuPG >= 2.1.13 the location of the agents socket changed. To find out the name of the local socket, always use: {{{ gpgconf --list-dir agent-extra-socket }}} this is the name of the extra socket on the local box. On the server the standard socket needs to be configured. Find this one out with {{{ gpgconf --list-dir agent-socket }}} ==== OpenSSH >= 6.7 ==== To your {{{~/.ssh/config}}} you can add: {{{ Host gpgtunnel HostName server.domain RemoteForward }}} If you can modify the the remote machine settings you should put into {{{/etc/ssh/sshd_config}}} the following: {{{ StreamLocalBindUnlink yes }}} This enables automatic removal of stale sockets when connecting to the remote machine. Otherwise you will first have to remove the socket on the remote machine before forwarding works. With {{{StreamLocalBindUnlink yes}}} you can connect with {{{ssh gpgtunnel}}} and just use GnuPG as usual. **Note:** On Systems where systemd controls the directories under {{{/var/run/user/}}} it may be that the socket forwarding fails because {{{/var/run/user//gnupg}}} is deleted on logout. To workaround this you can put {{{gpgconf --create-socketdir}}} in the startup script of your shell e.g. {{{~/.bashrc}}} or {{{~/.zshrc}}}. Remote gpg will try to start gpg-agent if it's not running. Remote gpg-agent which will delete your forwarded socket and set up it's own. To avoid this you can pass {{{--no-autostart}}} to remote gpg command. ==== OpenSSH < 6.7 ==== Before ~OpenSSH 6.7 you need to use socat which is a bit more fragile and requires a loop to stay open. {{{ # Execute locally (while true; do socat TCP-LISTEN:16668,bind=127.0.0.1 UNIX-CONNECT:$HOME/.gnupg/S.gpg-agent.extra; done) & # Connect to the remote system with Port forwarding. ssh -R16668:localhost:16668 server.domain # Connect the socket on the remote system (while true; do socat UNIX-LISTEN:$HOME/.gnupg/S.gpg-agent,unlink-close,unlink-early TCP4:localhost:16668; done) & }}}