Skip to content

Latest commit

 

History

History
324 lines (227 loc) · 10.9 KB

Linux.md

File metadata and controls

324 lines (227 loc) · 10.9 KB

SSH authentication using a GPG smart card on Linux

This document covers the procedure for configurating a YubiKey as a GPG smartcard for SSH authentication. The benefit is a good model for two-factor authentication, something you have and something you know. In this example, there is a token and a passphrase.

The YubiKey 5 Series is used here. The YubiKey 4 or YubiKey NEO will also work, although the YubiKey NEO is limited to 2048-bit RSA keys, and the YubiKey 4 does not support ECC keys.

The same instructions should work on other GPG smart card implementations, although they were developed using the Yubikey implementation

Examples below are using a Fedora 33 x86_64 and Ubuntu 15.04 x86_64 fresh install. There are other tutorials for other operating systems and keys available online. See the CREDITS section below for alternate tutorials, examples, etc.

Configuring Authentication with GNOME-Shell

To configure authentication using the previously generated GnuPG key, the GNOME-Shell needs some adjustments. With help from several resources, configure the system to allow gpg-agent to take over SSH authentication.

Certain software must be installed, including utilities for the YubiKey libyubikey (libyubikey-dev on Ubuntu), gnupg2 (which is probably already installed), and gnupg2-smime (gpgsm on Ubuntu).

Fedora:

sudo dnf install ykpers libyubikey gnupg gnupg2-smime

Ubuntu:

sudo apt-get install gnupg-agent gnupg2 pinentry-gtk2 scdaemon \
   libccid pcscd libpcsclite1 gpgsm yubikey-personalization \
   libyubikey-dev libykpers-1-dev

Optional: Install the YubiKey NEO Manager GUI. If running Ubuntu, you can install the YubiKey NEO manager and other YubiKey software from the Yubico PPA.

Enable your YubiKey's Smartcard interface (CCID)

This will enable the smartcard portion of your YubiKey:: This is only required for the YubiKey NEO.

ykpersonalize -m82

If you have a dev key, Reboot your YubiKey (remove and reinsert) so that ykneomgr works.

Configure GNOME-Shell to use gpg-agent and disable ssh-agent

Turn off ssh-agent inside gnome-keyring-daemon.

For Fedora this can be achieved by creating a new file /etc/X11/xinit/Xclients.d/Xclients.gnome-session.sh or appending to the existing one. Add the following code portion:

if [[ $(gconftool-2 --get /apps/gnome-keyring/daemon-components/ssh) != "false" ]]; then
  gconftool-2 --type bool --set /apps/gnome-keyring/daemon-components/ssh false
fi

Configure GPG to use its agent (only for smartcard):

echo "use-agent" >> ~/.gnupg/gpg.conf

Enable ssh-agent drop in replacement support for gpg-agent:

echo "enable-ssh-support" >> ~/.gnupg/gpg-agent.conf

Disable pcscd to avoid conflicting with GPG/scdaemon's built in CCID:

systemctl disable pcscd.socket --now
systemctl disable pcscd.service --now
systemctl mask pcscd.socket
systemctl mask pcscd.service

Allow admin actions on your YubiKey (if your gnupg version is < 2.0.11):

echo "allow-admin" >>  ~/.gnupg/scdaemon.conf

Intercept gnome-keyring-daemon and put gpg-agent in place for ssh authentication (Ubuntu)

Open Startup Applications

Uncheck "GPG Password Agent" and "SSH Key Agent"

Startup Apps

Edit /usr/share/upstart/sessions/gpg-agent.conf so that the pre-start script contains the following:

eval "$(gpg-agent --daemon --enable-ssh-support --sh)" >/dev/null
initctl set-env --global GPG_AGENT_INFO=$GPG_AGENT_INFO
initctl set-env --global SSH_AUTH_SOCK=$SSH_AUTH_SOCK
initctl set-env --global SSH_AGENT_PID=$SSH_AGENT_PID

Add the following lines to the post-stop script section:

initctl unset-env --global SSH_AUTH_SOCK
initctl unset-env --global SSH_AGENT_PID

Disable the other system gpg-agent:

mv /etc/X11/Xsession.d/90gpg-agent ~/bak/90gpg-agent

Note: We could have used the Xsession gpg-agent and trashed the upstart one, but there is an open bug report for 90gpg-agent. Also, the upstart script has the capability of exporting the environment variables globally with initctl set-env --global.

Intercept gnome-keyring-daemon and put gpg-agent in place for ssh authentication (Fedora)

If running gnome, this problem may be solved by running the following to disable gnome-keyring from autostarting its broken gpg-agent and ssh-agent implementation:

mv /etc/xdg/autostart/gnome-keyring-gpg.desktop /etc/xdg/autostart/gnome-keyring-gpg.desktop.inactive

mv /etc/xdg/autostart/gnome-keyring-ssh.desktop /etc/xdg/autostart/gnome-keyring-ssh.desktop.inactive

Next, place the following in ~/.bashrc to ensure gpg-agent starts with --enable-ssh-support :

# Start gpg-agent if it's not running
if ! pidof gpg-agent > /dev/null; then
    gpg-agent --homedir $HOME/.gnupg --daemon --sh --enable-ssh-support > $HOME/.gnupg/env
fi
if [ -f "$HOME/.gnupg/env" ]; then
    source $HOME/.gnupg/env
fi
gpg-connect-agent updatestartuptty /bye > /dev/null 2>&1

Now go to next step (Reload GNOME-Shell) :)

Reload GNOME-Shell So that the gpg-agent stuff above takes effect.

Rebooting the machine works the best. After reboot, make sure that the output of the following command is false:

gconftool-2 --get /apps/gnome-keyring/daemon-components/ssh

Setting PINs

There is a regular PIN, which is used to unlock the token for Signing, Encryption or Authentication. Additionally, there is an admin PIN, which is used to reset the PIN and/or the Reset Code for the key itself.

Complete these steps for PIN and then Admin Pin

default pins are 123456 and 12345678 respectivly

gpg2 --card-edit
..snip..

gpg/card> admin
Admin commands are allowed

gpg/card> passwd
gpg: OpenPGP card no. D27600012401020000050000158A0000 detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 3

Enter the Current Admin PIN

current admin PIN

Then enter the New Admin PIN twice

new admin PIN

PIN

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 1

Enter the Current PIN

current PIN

Then enter the New PIN twice

new PIN

NOTE: If the Admin PIN has not been entered, it may be required before changes are applied.

Generating an SSH Key using GnuPG

There are several ways to generate an SSH Key using GnuPG. A common way is to link the new authentication key to an already existing key:

gpg2 --edit-key 8A8F1D53
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  3072R/8A8F1D53  created: 2012-10-06  expires: never       usage: SC
                   trust: ultimate      validity: ultimate
sub  3072R/2F15E06B  created: 2012-11-23  expires: 2022-11-21  usage: S
sub  3072R/EB8B4EBD  created: 2012-11-24  expires: 2022-11-22  usage: E
sub  3072R/6BB325E9  created: 2012-11-24  expires: 2022-11-22  usage: A
[ultimate] (1). Clint Savage <[email protected]>
[ultimate] (2)  Clint Savage <[email protected]>
[ultimate] (3)  Clint Savage <[email protected]>

gpg>

Once in the edit-key dialog, create a key on the card:

gpg> addcardkey
Signature key ....: 91BC 60CC B9EC 8E73 923A  FC6D 58CD 88A6 2F15 E06B
Encryption key....: 0CC3 DC3E 0D17 6111 A62B  F656 63C6 4DA9 EB8B 4EBD
Authentication key: 9EBF A9FE 8AE1 0FEB 1699  CE9A 779F 43D5 EC6F CC13

Please select the type of key to generate:
   (1) Signature key
   (2) Encryption key
   (3) Authentication key
Your selection? 3

IT WILL PROMPT YOU TO ENTER THE ADMIN PIN, AND THEN THE REGULAR PIN. Don't fat finger this part!

gpg: WARNING: such a key has already been stored on the card!

Replace existing key? (y/N) y
What keysize do you want for the Authentication key? (3072)
Key is protected.

You need a passphrase to unlock the secret key for
user: "Clint Savage <[email protected]>"
3072-bit RSA key, ID 8A8F1D53, created 2012-10-06

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 10y
Key expires at Mon 21 Nov 2022 05:29:00 PM MST
Is this correct? (y/N) y
Really create? (y/N) y
gpg: Note that the key does not use the suggested creation date

pub  3072R/8A8F1D53  created: 2012-10-06  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
sub  3072R/2F15E06B  created: 2012-11-23  expires: 2022-11-21  usage: S
sub  3072R/EB8B4EBD  created: 2012-11-24  expires: 2022-11-22  usage: E
sub  3072R/6BB325E9  created: 2012-11-24  expires: 2022-11-22  usage: A

[ultimate] (1). Clint Savage <[email protected]>
[ultimate] (2)  Clint Savage <[email protected]>
[ultimate] (3)  Clint Savage <[email protected]>

Upon completion of the key, be sure to save the record to the card and gpg key:

gpg> save

Verify SSH key is managed via gpg-agent

Assuming everything above is configured correctly, a simple test is performed with the SmartCard inserted:

ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDL/XmU......BL0luE= cardno:00050000158A

FILES

The github repository contains all the files to make the changes above. Please feel free to read through them.

CREDITS

A special thanks to the following people and/or links.