gpg-agent does a good job of caching passphrases, and is essential
when using an authentication subkey exported as an SSH public key
(especially if used with a Yubikey).
With gpg-agent forwarding, we can do things with
gpg on a remote
machine while keeping the private keys on the local computer, like
decrypting files or signing emails.
As of OpenSSH 6.7+ and GnuPG 2.1+, we can reliably do gpg-agent forwarding. This is tailored for OS X, but will probably work on GNU/Linux.
If you already have
gpg2 and keys setup, you'll probably want to skip
to "Step 2: Using
Please send any comments, bugs, or fixes to firstname.lastname@example.org.
Install and configure software
install OpenSSH 6.7+ (MacPorts provides OpenSSH 7.2).
install GnuPG 2.1+ via source or GnuPG for OSX (this will recommend that you remove GPG Suite, if installed)
OS X and GPG
Getting GPG to work with OS X can be a frustrating exercise.
You will have to figure out the best configuration for yourself.
create symlinks to helpful utilities:
ln -s /usr/local/gnupg-2.1/bin/gpg-connect-agent \ /usr/local/bin/gpg-connect-agent ln -s /usr/local/gnupg-2.1/libexec/gpg-preset-passphrase \ /usr/local/bin/gpg-preset-passphrase
GnuPG for OS X
By default, gpg2 will be installed to
/usr/local/gnupg-2.1and create some symlinks to
create your GPG config (
~/.gnupg/gpg.conf) and keys (not covered here)
# use a GUI # pinentry-program /usr/local/gnupg-2.1/bin/pinentry-mac.app/Contents/MacOS/pinentry-mac # don't use a GUI pinentry-program /opt/local/bin/pinentry-curses # set up just for forwarding extra-socket /Users/username/.gnupg/S.gpg-agent-extra # each time cache is accessed, reset the timer to this default-cache-ttl 600 # after this time, expire cache entry max-cache-ttl 3600 # allows use of `gpg-preset-passphrase` allow-preset-passphrase # outdated options as of 2.1.11 #write-env-file #use-standard-socket
start or reload the agent with
gpg-connect-agent. This can also be used to manually clear the cache.
gpg-connect-agent reloadagent /bye
remote-gpg, written by Dustin J. Mitchell, is a
great tool that allows the user to control when
gpg-agent is available.
I've made some tweaks to Dustin's script,
remote-gpg, to account for
(1) different local and remote homedirs,
(2) sleep before deleting remote socket
(3) double-quotes to
sh -c instead of single-quotes to expand local variables:
#! /bin/bash # remote-gpg # original author: Dustin J. Mitchell <email@example.com> set -e host=$1 if [ -z "$host" ]; then echo "Supply a hostname" exit 1 fi # our local and remote homedirs might be different # TODO remote homedirs can vary in paths, too REMOTE_HOME=/nfs/homes/username LOCAL_HOME=/Users/username # remove any existing agent socket (in theory `StreamLocalBindUnlink yes` # does this, but in practice, not so much) /opt/local/bin/ssh $host rm -f $REMOTE_HOME/.gnupg/S.gpg-agent /opt/local/bin/ssh \ -t -R $REMOTE_HOME/.gnupg/S.gpg-agent:$LOCAL_HOME/.gnupg/S.gpg-agent-extra \ $host \ sh -c "echo; echo \"Perform remote GPG operations and hit enter\"; \ read; \ sleep 2; \ rm -f $REMOTE_HOME/.gnupg/S.gpg-agent";
add the following
~/.gnupg/gpg-agent.conf(if you didn't previously do it):
# use a GUI # pinentry-program /usr/local/gnupg-2.1/bin/pinentry-mac.app/Contents/MacOS/pinentry-mac # don't use a GUI pinentry-program /opt/local/bin/pinentry-curses # set up just for forwarding extra-socket /Users/username/.gnupg/S.gpg-agent-extra
on the local machine, run
on the remote machine, run the desired
if your private keys have not already been loaded, you may or may not get a passphrase prompt depending on which
pinentry-mac(GUI), you will locally be prompted for your passphrase (with gpg2 letting you know that it's for a remote operation)
pinentry-curses(no GUI), you will not be prompted for your passphrase and will need to "pre-seed" it with
gpg-preset-passphraseor the following:
gpg2 --output /dev/null --sign -u 0xKEY_ID /dev/null
when finished, go to the local window and press "Enter".
optionally, clear the password cache with
gpg-connect-agent reloadagent /bye
I haven't tested this with authentication or encryption GPG subkeys with a Yubikey, yet.