Security keys such as the Yubikey from Yubico have become much more popular in recent times, showing an increased focus on security best practices. Many people are already aware of Multi-Factor Authentication or MFA, since many secure online services (e.g. banks, government portals) have mandated the use of a physical device or one-time access codes before using their services. To learn more about MFA, please check out the Wikipedia article on MFA.
Since you’re here, you know what MFA is so let’s look at what I needed to achieve. Simply:
Upon USB security key insertion or removal, detect that event and “do something” in response.
– My requirements 🙂
My environment:
- Pop OS 21.04 Linux (based on Ubuntu)
- Yubikey USB security key
What I’m not going to cover:
- How to configure your Yubikey for use in Linux. To learn more, please see the official Yubico documentation
- Which Linux distributions use or don’t use
udev
– that’s on you
Get Info About Security Key
For all this to work, we’ll rely on udev
. Using the built-in tools that are provided with various Linux distributions, we first need to get some info about your security key. Your output will vary greatly depending on events happening in your system and also on the model of security key you are using.
- Disconnect/remove your security key from your system
- Open a terminal and start monitoring
udev
events:
udevadm monitor --property
Successfully starting the monitor will show this:
~ ❯
~ ❯ udevadm monitor --property
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent
Note: In the output below, I’ve removed some info and replaced it with [removed].
- Insert your security key and note the extensive output shown in your terminal window. The specific section looks like this on my system:
UDEV [52954.592536] add /devices/pci0000:40/0000:40:01.1/0000:41:00.0/0000:42:08.0/0000:48:00.3/usb9/9-4/9-4:1.0/0003:1050:0407.001C/input/input40/event6 (input)
ACTION=add
DEVPATH=/devices/pci0000:40/0000:40:01.1/0000:41:00.0/0000:42:08.0/0000:48:00.3/usb9/9-4/9-4:1.0/0003:1050:0407.001C/input/input40/event6
SUBSYSTEM=input
DEVNAME=/dev/input/event6
SEQNUM=28039
USEC_INITIALIZED=52954592318
ID_INPUT=1
ID_INPUT_KEY=1
ID_INPUT_KEYBOARD=1
ID_VENDOR=Yubico
ID_VENDOR_ENC=Yubico
ID_VENDOR_ID=1050
ID_MODEL=[COPY_THIS_VALUE]
ID_MODEL_ENC=[removed]
ID_MODEL_ID=[removed]
ID_REVISION=[removed]
ID_SERIAL=[removed]
ID_TYPE=hid
ID_BUS=usb
ID_USB_INTERFACES=:030101:030000:0b0000:
ID_USB_INTERFACE_NUM=00
ID_USB_DRIVER=usbhid
.INPUT_CLASS=kbd
ID_PATH=pci-0000:48:00.3-usb-0:4:1.0
ID_PATH_TAG=pci-0000_48_00_3-usb-0_4_1_0
XKBLAYOUT=au
BACKSPACE=guess
XKBMODEL=pc105
XKBVARIANT=
XKBOPTIONS=
ID_SECURITY_TOKEN=1
ID_FOR_SEAT=input-pci-0000_48_00_3-usb-0_4_1_0
.LOCAL_ifNum=00
LIBINPUT_DEVICE_GROUP=3/1050/407:usb-0000:48:00.3-4
MAJOR=13
MINOR=70
DEVLINKS=[removed]
TAGS=:uaccess:power-switch:seat:
CURRENT_TAGS=:uaccess:power-switch:seat:
- Three things are of particular interest here:
ACTION
isadd
SUBSYSTEM
isinput
ID_MODEL
isYubiKey_[some_stuff_here]
– note down the value of this property now, as you’ll need it shortly
- Remove your security key and again note the extensive output shown in the terminal. The relevant block looks similar to before but with one main difference:
ACTION
isremove
- Hit Ctrl-C to stop the udev monitoring
Now that we have the necessary info about our security key, we can proceed.
The “Do Something” Part
The “do something” part of this article will be different for everyone, meaning the scripts below are examples only. Here are the components of this setup:
- Script called
yubikey
, located in my home directory:
#!/bin/bash
if [ "$1" == "removed" ]
then
echo "Oi, Yubikey has been removed!" > /home/me/yubikey_status.txt
else
echo "K, Yubikey found. Secure all the things!" > /home/me/yubikey_status.txt
fi
- Text file named
yubikey_status.txt
in my home directory:
unknown
- The
watch
command can be used to monitor file contents:
watch cat ~/yubikey_status.txt
Reacting to a security key removal event will likely be accompanied with an action such as locking the screen, sending an email or displaying a message. For now, this is what we’ll see:
Every 2.0s: cat /home/me/yubikey_status.txt
unknown
Detecting Security Key Insertion/Removal
udev
will be used to handle the USB insertion/removal events, using custom udev
rules stored in /etc/udev/rules.d
.
Privilege escalation via sudo
(or similar) will be required to create and edit these files.
To learn more about how these files are named, please see the official udev documentation.
- Create a file named
/etc/udev/rules.d/90-yubikey.rules
, containing the following content:
ACTION=="add", SUBSYSTEM=="input", ENV{ID_MODEL}=="[ID_MODEL_COPIED_EARLIER_GOES_HERE]", RUN+="/home/me/yubikey inserted"
ACTION=="remove", SUBSYSTEM=="input", ENV{ID_MODEL}=="[ID_MODEL_COPIED_EARLIER_GOES_HERE]", RUN+="/home/me/yubikey removed"
These udev
rules complete the following actions:
- Watches for both
add
andremove
events - Matching events must occur in the
INPUT
subsystem - The matching events must occur for devices matching the specified
ID_MODEL
- When a matching event occurs, the
~/yubikey
script executesinserted
command-line parameter if the device was addedremoved
command-line parameter if the device was removed
- The
~/yubikey
script will write content to the~/yubikey_status.txt
file depending on the value of the$1
parameter i.e. the first parameter on the command line
Reloading udev
Configuration
We can dynamically reload the udev rules by running the following command:
sudo udevadm control --reload
Testing
- Run the
watch
command above if it’s not already running - Insert your security key
- If everything has been configured correctly and your
udev
rules have been reloaded, you’ll see thewatch
command output change as follows:
Every 2.0s: cat /home/me/yubikey_status.txt
K, Yubikey found. Secure all the things!
- Conversely, removing the security key will run the script again, causing the output to change as follows, as the contents of the
~/yubikey_status.txt
file changes:
Every 2.0s: cat /home/me/yubikey_status.txt
Oi, Yubikey has been removed!
Wrapping Up
That’s all there is to it. Hopefully this was useful for someone.