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:

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.