Skip to content

Instantly share code, notes, and snippets.

@ewjoachim
Created February 26, 2021 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ewjoachim/427a9867bc758f4cbd5981fd793d48ff to your computer and use it in GitHub Desktop.
Save ewjoachim/427a9867bc758f4cbd5981fd793d48ff to your computer and use it in GitHub Desktop.

Integrate Yubikey with libpam

Note: All examples use Ubuntu 19.10

Objectives:

Add additonal security

If used as a second auth factor, this would secure the laptop a bit more. This might also make the laptop unusable if the key is lost.

Optionnally replace primary factor for logging in

The aim is to speedup unlocking the laptop by allowing the yubikey to unlock it instead of the password. This can be acceptable only if pin is required after plugging the key, otherwise someone getting ahold of both the key and the computer would not even get a password challenge. Also, this means it's super important to never leave the key plugged and unlocked out of sight.

Optionnally replace primary factor for sudo

This can be more boradly acceptable, given we could have passwordless sudo anyway.

Specific tools

  • Yubikey Manager can be used to easily configure the yubikey, enabling or disabling OTP, GPG, challenge-response etc.:
$ sudo add-apt-repository ppa:yubico/stable && sudo apt-get update
$ sudo apt-get install yubikey-manager-qt

libpam modules

In the following section, we will configure libpam modules. We're using the keyword sufficient to indicate that the authentication factor is sufficient for logging in. If you want to make it an additional factor to existing ones, use required instead. This documentation does not replace a bit of reading man pam.

GPG, via libpam-poldi

How to

$ sudo apt install libpam-poldi

Find out your key id with:

$ gpg --card-status | grep "Application ID" | cut -d' ' -f4

Write to /etc/poldi/localdb/users:

<key id> <unix user>

e.g.:

D2760001240102010006080724670000 joachim

Have the gpg agent write additional information to a file:

$ gpg-connect-agent "/datafile /tmp/gpg-pam" "SCD READKEY --advanced OPENPGP.3" /bye
$ sudo mv /tmp/gpg-pam /etc/poldi/localdb/keys/<key id>

(replacing <key-id> with your key id)

Create a file to add a PAM rule for using poldi, at /etc/pam.d/common-yubikey-poldi:

#%PAM-1.0

auth sufficient pam_poldi.so

(refer to the final section for more details on the libpam part)

Pros

  • Requires the PIN when using for the 1st time after plugging the key (because it's based on GPG)

Cons

  • poldi seems to "work" but the doc is awful, and it seems quite outdated (no update to the package since 2016)
  • While integration with sudo "works" (but is visually wrong), gdm is all funky and buggy. It does seem to require the PIN after a reboot, but not after the key is removed.

U2F, via libpam-u2f

How to

Install with:

$ sudo apt install libpam-u2f

Configure with

$ pamu2fcfg > $HOME/.config/Yubico/u2f_keys
$ # (nothing is prompted but you have 15 seconds to touch the yubikey sensor)

Libpam file (/etc/pam.d/common-yubikey-u2f) looks like:

#%PAM-1.0

auth sufficient pam_u2f.so cue

(refer to the final section for more details on the libpam part)

Pros

  • Simple, works, you need to touch the yubikey to authenticate.

Cons

  • Can be used as soon as the key is plugged into the laptop, no PIN code or any protection.

libpam-yubico

Install with:

sudo apt install libpam-yubico

We'll follow the spets outlined in:

$ zless /usr/share/doc/libpam-yubico/Authentication_Using_Challenge-Response.adoc.gz

To define a challenge-response on slot 2 of your yubikey, instead of the ykpersonalize call, it's easier to use Yubikey Manager: Applications > OTP > Slot 2 > Configure > Challenge response > Generate > Save.

Generate a challenge-response file and rename it:

$ mkdir ~/.yubico
$ ykpamcfg -2 -v
$ ls ~/.yubico/
challenge-1234567
$ mv ~/.yubico/challenge-123456 <unix user>-123456

Libpam file (/etc/pam.d/common-yubikey) looks like:

#%PAM-1.0

auth sufficient pam_yubico.so mode=challenge-response chalresp_path=/home/<unix user>/.yubico/

(refer to the final section for more details on the libpam part)

Pros

  • Simple, works, you don't even need to touch the yubikey to authenticate.

Cons

  • Can be used as soon as the key is plugged into the laptop, no PIN code or any protection.

Common configuration

Once you have created /etc/pam.d/common-yubikey*, you can choose what you want to do with it:

Enable for sudo in command line or interactive (with a popup)

Edit /etc/pam.d/sudo, just before the other includes, add:

@include common-yubikey<module of your choice>

For "popup" sudo (like when you call systemctl without sudo), do the same with /etc/pam.d/polkit-1.

Enable for global authentication usage

In /etc/pam.d/common-auth, before all other directives, add:

@include common-yubikey<module of your choice>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment