Skip to content

Configure SSH to use a Yubikey as a private key

jeff oconnell edited this page Jun 7, 2017 · 1 revision

You can use a Yubikey for SSH authentication by configuring gpg-agent to take the place of ssh-agent.

After you have configured your Yubikey, follow these steps to configure gpg-agent:

  • Edit ~/.gnupg/gpg-agent.conf and update:

    • add write-env-file /Users/<USERNAME>/.gnupg/gpg-agent-info, substituting <USERNAME>
    • add enable-ssh-support
    • set default-cache-ttl to 3600
    • set default-cache-ttl-ssh to 3600
    • set max-cache-ttl to 7200
    • set max-cache-ttl-ssh to 7200

Your updated gpg-agent.conf should look something like this:

$ cat ~/.gnupg/gpg-agent.conf
pinentry-program /usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac
default-cache-ttl 3600
default-cache-ttl-ssh 3600
max-cache-ttl 7200
max-cache-ttl-ssh 7200
write-env-file /Users/haxor/.gnupg/gpg-agent-info
enable-ssh-support
  • Add this bash function to your ~/.bash_profile so that your shell environment has the proper gpg-agent env info
function init_gpg_ssh {
    source ~/.gnupg/gpg-agent-info
    for key in $( cat ~/.gnupg/gpg-agent-info | cut -d = -f 1 )
    do
        eval "export $key"
    done
    ssh-add -l 2> /dev/null
}
init_gpg_ssh
  • Run the inig_gpg_ssh function:
$ source ~/.bash_profile
  • Restart gpg-agent:
$ killall gpg-agent ; /usr/local/MacGPG2/bin/gpg-agent --daemon

GPG_AGENT_INFO=/Users/jeffo/.gnupg/S.gpg-agent:11065:1; export GPG_AGENT_INFO;
SSH_AUTH_SOCK=/Users/jeffo/.gnupg/S.gpg-agent.ssh; export SSH_AUTH_SOCK;
SSH_AGENT_PID=11065; export SSH_AGENT_PID;
  • Ensure that your yubikey is inserted into your machine and re-source your ~/.bash_profile:
$ source ~/.bash_profile
4096 SHA256:QbdjxFcOgrojfkslgirj85k2lDD45R5FQ9gJ4yvMM cardno:000604707305 (RSA)
  • Run ssh-add -L to retrieve the public key:
$ ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC2cyirWkIThHEcuCC4Oodi7kFXtuET5DHX/Md0e8lLS1kMep
         Dnkq69zhPwgR9QknVQq8jPxYUUdBU6w10dmm6Ro9A/ut1QFfGDJsQBG0TaBKeqKHJCUaseNHeF0j3
         QdNIQMC4XMKOyUcKfqBf0nVtwVzvChnotmNEtnCbwoFE7NhYejq6pncRy3piVp1kpSfUcqb0CoRag
         VX9oPRQ9XzVpVV0Gu0vVYG9f4wyiyxqo5dvPFrwnaZkqrLJDA2/gCInT62AWIb/3nDe2pGy5F3CUd
         mcH+jhIgG2LBtklhZ+LbVjQONMUmkLDr8khqqLvwzDz1g7ubrqlMZ2v2IT8+WitunCsZRSktmqmD5
         qfYegU3EOj1N/48oFainib4UdMabYhgOWOsoEb/yQPjTC3JRMfjlHZL3FxJO7bgbyyKu5TKt3Hx4I
         ...
         sscjHBfgxzVHh7p1fJEcjqsAqkFRAD2EnrmUih6Hu28AAtqw+RBoEnw== cardno:000604707305
  • Save the public key to a file:
$ ssh-add -L > ~/.ssh/yubikey_gpg_${KEY_ID}.pub

It's okay if you see error fetching identities for protocol 1: agent refused operation in the above output. This just means your ssh client still has SSH v1 enabled.

You can now use the saved public key anywhere you would use a normal ssh public key: GitHub, a remote ~/.ssh/authorized_keys, etc.

When you ssh to a service has your new public key, you do not need to specify an IdentifyFile using ssh -i <path>. The ssh client will ask the gpg-agent for available identities and the gpg-agent will offer your authentication key.

Notes

This documentation was written using:

Clone this wiki locally