If you have configured an authentication key in your Yubikey’s OpenPGP slot, you
gpg-agent to SSH with this authentication key. The advantages are :
- your key is secure: it never leaves your Yubikey
- your key is always with you
- you can use “Touch to authenticate”
But there are some inconveniences:
- You must install and configure gpg-agent on the computer you wish to use the Yubikey
- The setup was not that easy, and it must be repeated for each computer
This guide is largely based on DrDuh YubiKey Guide.
Create your GPG configuration
We start by creating the gpg configuration if it does not exist already. Paste the following text into a terminal window to create a recommended GPG configuration:
$ cat << EOF > ~/.gnupg/gpg.conf auto-key-locate keyserver keyserver hkps://hkps.pool.sks-keyservers.net keyserver-options no-honor-keyserver-url keyserver-options ca-cert-file=/etc/sks-keyservers.netCA.pem keyserver-options no-honor-keyserver-url keyserver-options debug keyserver-options verbose personal-cipher-preferences AES256 AES192 AES CAST5 personal-digest-preferences SHA512 SHA384 SHA256 SHA224 default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed cert-digest-algo SHA512 s2k-cipher-algo AES256 s2k-digest-algo SHA512 charset utf-8 fixed-list-mode no-comments no-emit-version keyid-format 0xlong list-options show-uid-validity verify-options show-uid-validity with-fingerprint use-agent require-cross-certification EOF
To install the keyservers CA file:
$ sudo curl -s "https://sks-keyservers.net/sks-keyservers.netCA.pem" -o /etc/sks-keyservers.netCA.pem
Importing the public key
Import the public key from a file with:
$ gpg2 --import < /mnt/public-usb-key/pubkey.txt gpg: key 0xFF3E7D88647EBCDB: public key "Dr Duh <email@example.com>" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1)
Or download from a keyserver:
$ gpg --recv 0xFF3E7D88647EBCDB gpg: requesting key 0xFF3E7D88647EBCDB from hkps server hkps.pool.sks-keyservers.net [...] gpg: key 0xFF3E7D88647EBCDB: public key "Dr Duh <firstname.lastname@example.org>" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1)
You may get an error gpgkeys: HTTP fetch error 1: unsupported protocol – this means you need to install a special version of curl which supports gnupg:
sudo apt-get install gnupg-curl
Unplug and replug the Yubikey. Check the card’s status:
$ gpg --card-status Application ID ...: D2760001240102010006055532110000 Version ..........: 2.1 Manufacturer .....: Yubico Serial number ....: 05553211 Name of cardholder: Dr Duh Language prefs ...: en Sex ..............: unspecified URL of public key : [not set] Login data .......: email@example.com Signature PIN ....: not forced Key attributes ...: 4096R 4096R 4096R Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 3 Signature counter : 0 Signature key ....: 07AA 7735 E502 C5EB E09E B8B0 BECF A3C1 AE19 1D15 created ....: 2016-05-24 23:22:01 Encryption key....: 6F26 6F46 845B BEB8 BDF3 7E9B 5912 A795 E90D D2CF created ....: 2016-05-24 23:29:03 Authentication key: 82BE 7837 6A3F 2E7B E556 5E35 3F29 127E 7964 9A3D created ....: 2016-05-24 23:36:40 General key info..: pub 4096R/0xBECFA3C1AE191D15 2016-05-24 Dr Duh <firstname.lastname@example.org> sec# 4096R/0xFF3E7D88647EBCDB created: 2016-05-24 expires: never ssb> 4096R/0xBECFA3C1AE191D15 created: 2016-05-24 expires: never card-no: 0006 05553211 ssb> 4096R/0x5912A795E90DD2CF created: 2016-05-24 expires: never card-no: 0006 05553211 ssb> 4096R/0x3F29127E79649A3D created: 2016-05-24 expires: never card-no: 0006 05553211
sec# indicates master key is not available (as it should be stored encrypted offline).
Paste the following text into a terminal window to create a recommended GPG agent configuration:
$ cat << EOF > ~/.gnupg/gpg-agent.conf enable-ssh-support pinentry-program /usr/bin/pinentry-curses default-cache-ttl 60 max-cache-ttl 120 write-env-file use-standard-socket EOF
If you are using Linux on the desktop, you may want to use
/usr/bin/pinentry-gnome3 to use a GUI manager.
Replace ssh-agent with gpg-agent
gpg-agent provides OpenSSH agent emulation.
To launch the agent for use by ssh use the
gpgconf --launch gpg-agent commands.
Add these to your shell rc file (
alias gpg=gpg2 export GPG_TTY="$(tty)" export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)" gpgconf --kill gpg-agent gpg-agent --daemon --enable-ssh-support
In Debian, SSH_AUTH_SOCK can be found in
but if you have gnome-keyring activated it will be in
This is why we use
gpgconf to determine where it is automatically.
And source your file:
Then launch your gpg-agent:
sudo killall gpg-agent gpg-agent --daemon --enable-ssh-support
About gpg-agent and Gnome-Keyring
There are some known problem about using
gpg-agent with the gnome-keyring.
Here is what the GnuPG Wiki says about it :
Some versions of Gnome Keyring hijack the connection to GPG Agent (they intercept all the communication between gpg or gpgsm and gpg-agent) by setting the GPG_AGENT_INFO environment variable to point to the Gnome Keyring process. Gnome Keyring then filters all communication with gpg-agent. Unfortunately, Gnome Keyring’s implementation of that internal GnuPG protocol is incomplete. Thus although many operations work, in particular, working with smart cards results in errors
To solve this problem, you can disable gnome-keyring.
Copy the original desktop files for GNOME Keyring to ~/.config/autostart
cd /etc/xdg/autostart cp gnome-keyring-gpg.desktop gnome-keyring-ssh.desktop ~/.config/autostart
You might not have
gnome-keyring-gpg.desktop, in this case you can just create
X-GNOME-Autostart-enabled=falseto each of these files :
echo "X-GNOME-Autostart-enabled=false" >> ~/.config/autostart/gnome-keyring-gpg.desktop echo "X-GNOME-Autostart-enabled=false" >> ~/.config/autostart/gnome-keyring-ssh.desktop
If you want to disable GNOME-Keyring system-wide, you can make the above change directly in the original desktop files (/etc/xdg/autostart/gnome-keyring-*.desktop).
You might encounter another problem. If you use
killall gpg-agent to kill all
gpg agents and then try to start another agent manually with
gpg-agent, you will see this error message :
gpg-agent --enable-ssh-support --daemon gpg-agent: a gpg-agent is already running - not starting a new one
This problem is due to systemd managing the gpg-agent and the
not working properly.
There is a debian bugs explaining that users who don’t want systemd to manage their gpg-agent in this way for all future sessions should do:
systemctl --user mask --now gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socket
Doing this means that gpg-agent will fall back to its manual mode of operation. (This decision can be reversed by the user with “unmask” instead of “mask”)
Some links :
Adding comment as I had the same issue with ed25519 keys. The issue is indeed gnome-keyring
I was generating my ssh keys with ssh-keygen and added an additional argument “-o” which generated the keys in a new format for openSSH. The problem was that my gnome-keyring did not support such keys as the keys had Ed255519 signature scheme. Gnome-keyring does not support that since 3.20. I reverted to RSA and no more problems!.
Xmodulo.com : How to disable gnome-keyring.
Debian Wiki : This link explains how to manually disable the internal gpg-agent and ssh-agent for gnome-keyring version < 3.16.0-3
Use your authentication key with Github or Gitlab
Here we test our setup with Github. We will start by adding our ssh key to our Github account.
To display your ssh key use:
If you do not see your ssh key, you might still have ssh-agents running in the background.
Then use the output to add ssh key to your Github account. Once this is done test your connection with:
ssh email@example.com -T Hi Sammy! You\'ve successfully authenticated, but GitHub does not provide shell access.
Add your new ssh key to your servers
Copy your ssh key if you haven’t already. You might need to restart your ssh-agent and re-add you ssh keys to connect to your server :
sudo killall gpg-agent eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_rsa
You need to add your private key to the agent for it to work.
Adding the keys to the server
First connect to your server :
On your server, first as a security precaution, temporarily allow password authentication. If anything goes wrong, you will still have access to your server.
Then add your ssh keys in
sudo vim ~/.ssh/authorized_keys
Test the connection
Finally activate your gpg-agent to test your connection.
sudo killall gpg-agent gpg-agent --daemon --enable-ssh-support source ~/.zshrc
Connect your security key and test to see its ssh key:
Test your connection
You will be asked for your security key PIN. This is a good indication that the correct SSH key is used.
If the connection does not work:
sudo killall gpg-agent gpg-agent --daemon --enable-ssh-support
Secure your server
Disable password authentication
Optionally you could remove your other ssh keys from
Yubikey: requiring touch to authenticate
By default the Yubikey will perform key operations without requiring a touch from the user. To require a touch for every SSH connection, use the Yubikey Manager (you’ll need the Admin PIN):
sudo apt-get install yubikey-manager ykman openpgp touch aut on
In case you have an error, try removing and reinserting your Yubikey
To require a touch for the signing and encrypting keys as well:
ykman openpgp touch sig on ykman openpgp touch enc on
The Yubikey will blink when it’s waiting for the touch.