Locking and unlocking your desktop with an USB device

Monday, Jan 7, 2019
Linux security

Goal

I recently ordered a Yubikey to secure some of my accounts. When it arrived and the key was linked to the desired accounts I started to look into using the key to sign myself in to Linux.

There is a great documentation by yubico how to use PAM to achieve this. I did not followed this guide because of that reasons:

  1. the key should be optional, not mandatory
  2. it should be revertible without an additional key for recovery purposes
  3. The password for the user should be typed at least once a day

Explanation of goals

key should be optional

I believe this is possible with PAM but may prove to be a bit tricky with (3)

no recovery hardware

You can link multiple keys to your account. When using the PAM module you should not consider doing this. Just do it.

Also, the link between the user account and the key is stored within the user’s home directory. Which is a design decision I totally understand. My home directory is encrypted and only readable once I log in. Therefore the logon process will have a hard time to read the link and reverting the link through a root user is hard unless you have noted your encryption key somewhere. I did, but I decided I do not want to try this. Right now, right on this machine. Maybe sometime. Call me lazy.

password should be typed once a day

At my workplace I am kind of an alien. While we do use a lot of Linux servers my work machine is the only Linux workstation in place (at least that I know of). The other machines are a mic of Apple and Windows machines connected to an AD and a LDAP. Both directory servers require a password change within a specified time range. When I logon to servers connected to those directory servers I have to type that password and to not forget it I want to have it to type at least once a day. As I turn off my machine when my work is finished, typing it the first time while using an USB key to lock/unlock the screen seems to be a good fit.

Solution

I started to research how to lock and unlock the screen first. I use KDE neon and soon I discovered loginctl (which seems not necessarily to be specific to KDE). It turned out that loginctl can lock a session, list sessions and unlock a session.

Changes to the connected hardware can be monitored using udev.

My solution path was to look for changes to a specific USB device and run scripts on add/remove.

lock script

The lock script is the simplest component of the solution as it blindly just locks all sessions:

#!/bin/sh

/bin/loginctl lock-sessions

The script has to be executable by root (and I propose just for root) and be placed in a well known location. Like /usr/local/bin or /opt/lockunlock/. Feel free and up to your taste. Maybe follow the usual standards.

unlock script

The unlock script is a bit more complicated:

#! /bin/bash

# get the session
# caveat here: two sessions from my user will not work
mysession=$(/bin/loginctl --no-legend list-sessions | /bin/grep andres | /bin/grep seat | /usr/bin/awk '{print $1}')

# no session found? exit sucessfully
if [ "x" == "x${mysession}" ]; then
  exit 0
fi

# automatically unlock the session
sudo -u andres /bin/loginctl unlock-session "${mysession}"

Just in case there are more than one active sessions for my user, the unlock script will fail. I decided I can go with that, an alternative would be to store the current session on lock and restore that one.

create udev rules for key

udev rules are a big topic. Basically udev rules allow you to react to hardware changes. Such as adding or removing an USB kek. So for my yubikey setup the rules look like this:

ACTION=="remove", \
  SUBSYSTEMS=="usb", \
  ATTRS{idProduct}=="0407", \
  ATTRS{idVendor}=="1050", \
  ATTRS{serial}=="xxxxxxxxxxxxxxxxx" \
  RUN+="/usr/local/bin/lockscreen.sh"

ACTION=="add", \
  SUBSYSTEMS=="usb", \
  ATTRS{idProduct}=="0407", \
  ATTRS{idVendor}=="1050", \
  ATTRS{serial}=="xxxxxxxxxxxxxxxxx" \
  RUN+="/usr/local/bin/unlockscreen.sh"

Notes

program the password into Yubikey

I know I could use my Yubikey to type in the password on the other sites and such be able to completely forget the password after a change. But what happens when I have to logon to a computer without having my security key along?

Caveats

My solution assumes a single (interactive) user machine. There is no configuration file or something like this to look for different active sessions for different users based on different keys. Right now. With a little bit of imagination and some additional work this would be possible.