Friday, 16 March 2018

Login to Ubuntu with Yubikey

DISCLAIMER: I am by no means responsible for anyone using this tutorial to lock herself out of their system, nor for any damage, data loss, etc. You get the idea, use this at your own risk.


With that out of the way, let's get to the fun part.

This tutorial will outline the steps I used in my current Xubuntu (Ubuntu with Xfce) 16.04 to enable my Yubikey as a hardware key as a requirement to log in.

I am using the default eCryptFS encryption method to encrypt a private folder (not my home folder) which also keeps unlocking when my user logs in.

This process worked on my Arch desktop too, which I took from this genius post: https://blog.jamesthebard.net/archlinux-and-u2f-login/ Big thanks and credit to him!
This tutorial will be mostly copy-paste, though I wish to do it with the Ubuntu specifics.

The login manager I am using is LightDM, I also removed the screensaver that comes with Xubuntu out of the box. On Arch I was able to use GDM with success.

$ sudo apt remove xscreensaver

I also changed my lock screen command from flock4 to dm-tool lock as LightDM will have the support to ask to touch the key.

Now let's install the Pam u2f package:

$ sudo apt install libpam-u2f

Next, we will generate the u2f mapping file. From a security standpoint, we should put it in a secure place like /var. For this procedure, you will need to have your Yubikey plugged in and when it lights up during the command execution, touch it.

$ pamu2fcfg -uikon

The parameter is -u plus your username. Replace ikon with your username.
This will give you something like this:

ikon:lotsofrandomcharacters,evenmorerandomcharacters%

Copy this line WITHOUT the percentage sign at the end and put it in a file at /var/yubico/yubikey_mappings (create the dir if needed)

Be sure to also secure it like:

# chown -R root:root /var/yubico && chmod 0700 /var/yubico && chmod 0600 /var/yubico/yubikey_mappings

Next, we will add the PAM related lines to /etc/pam.d/common-auth file:


  #
  # /etc/pam.d/common-auth - authentication settings common to all services
  #
  # This file is included from other service-specific PAM config files,
  # and should contain a list of the authentication modules that define
  # the central authentication scheme for use on the system
  # (e.g., /etc/shadow, LDAP, Kerberos, etc.).  The default is to use the
  # traditional Unix authentication mechanisms.
  #
  # As of pam 1.0.1-6, this file is managed by pam-auth-update by default.
  # To take advantage of this, it is recommended that you configure any
  # local modules either before or after the default block, and use
  # pam-auth-update to manage selection of other modules.  See
  # pam-auth-update(8) for details.
  
  auth  sufficient  pam_u2f.so debug authfile=/var/yubico/yubikey_mappings cue
  
  # here are the per-package modules (the "Primary" block)
  auth [success=1 default=ignore] pam_unix.so nullok_secure
  # here's the fallback if no module succeeds
  auth requisite   pam_deny.so
  # prime the stack with a positive return value if there isn't one already;
  # this avoids us returning an error just because nothing sets a success code
  # since the modules above will each just jump around
  auth required   pam_permit.so
  # and here are more per-package modules (the "Additional" block)
  auth optional pam_ecryptfs.so unwrap
  # end of pam-auth-update config
  

The line in the middle of the file (with pam_u2f.so) is what we need to add as the first entry, like above. sufficient is telling that it is not mandatory to fully authenticate us with the Yubikey, just yet. debug is also set so that we can see some logs when there is something fishy going on.

Let's reboot and test logging in. The login screen should already ask you to touch the device apart from your password.
Should it not let you login, you can still open a new terminal (you know, there is 8 by default in Linux) and you should still be able to login with your password.

If all went as expected you can go and edit the common-auth file and change sufficient to required and if feeling confident enough, remove the debug directive too.

The file should look like this now:


  #
  # /etc/pam.d/common-auth - authentication settings common to all services
  #
  # This file is included from other service-specific PAM config files,
  # and should contain a list of the authentication modules that define
  # the central authentication scheme for use on the system
  # (e.g., /etc/shadow, LDAP, Kerberos, etc.).  The default is to use the
  # traditional Unix authentication mechanisms.
  #
  # As of pam 1.0.1-6, this file is managed by pam-auth-update by default.
  # To take advantage of this, it is recommended that you configure any
  # local modules either before or after the default block, and use
  # pam-auth-update to manage selection of other modules.  See
  # pam-auth-update(8) for details.
  
  auth  required  pam_u2f.so  authfile=/var/yubico/yubikey_mappings cue
  
  # here are the per-package modules (the "Primary" block)
  auth [success=1 default=ignore] pam_unix.so nullok_secure
  # here's the fallback if no module succeeds
  auth requisite   pam_deny.so
  # prime the stack with a positive return value if there isn't one already;
  # this avoids us returning an error just because nothing sets a success code
  # since the modules above will each just jump around
  auth required   pam_permit.so
  # and here are more per-package modules (the "Additional" block)
  auth optional pam_ecryptfs.so unwrap
  # end of pam-auth-update config