~ ✍️
RSS image

« Back to index

Linux default user login with fingerprint or Yubikey

Apr 30 2023

I recently bought a new Thinkpad with a fingerprint reader and I thought why not try to log me in with the fingerprint reader instead of providing user and password.

Additionally, I also wanted to set a default user that is preselected for my system so I only need to enter my password if the previous fingerprint authentication failed. As a bonus, also use my Yubikey as a preferred login method :)

My auth flow for my daily driver:

  1. First try the fingerprint reader
  2. If that fails try the Yubikey that requires touching the key
  3. In case both of the previous methods fail try auth with a regular password
  4. If password authentication for the default user is also unsuccessful specify user and password again

This post shows how to configure this flow for my arch GNU/Linux system. We will use PAM (pluggable authentication modules) that provide authentication services for applications. I have used Linux now for at least 7 years but never really had close contact with PAM and this is a quite interesting topic I will probably look into further.

The basic idea of PAM that different modules can provide authentication methods for a service. The service just interacts with PAM and the module will return if the authentication was successful or not. This allows a system administrator to configure different authentication methods independent of the services that will use it. On some systems you will provide a username and password, on others you can use biometric data or smartcards. The userland applications are detached from the actual implementation of the authentication.

We will use a module for fingerprint reading called pam_fprintd.so and another for YubiKey authentication called pam-u2f.

My machine has Arch Linux installed and is only minimally configured. I still log in via the tty as I use Hyprland as my Wayland compositor. If you are running a distro with a desktop environment such as GNOME, KDE, or Xfce you will have a display manager configured that handles the login. In case you want to set up fingerprint or YubiKey authentication your display manager probably can be configured to use the same pam modules.

When changing the pam defaults take care that this might compromise the security of your system as you will circumvent authentication with username and password with this method.

Setup default user

First I wanted to set my user as the default user when logging in so I only have to provide my credentials. The login on the tty is handled by getty which is started by Systemd using the following target:

/etc/systemd/system/getty.target.wants/getty@tty1.service

This Systemd service file contains an entry that starts getty when the tty1 is opened. To provide a default user we can modify the startup of the getty application to use a specific user. Replace the <user> within the ExecStart entry with yours.

ExecStart=-/usr/bin/agetty --skip-login --login-options <user> --noclear - $TERM

In case login fails it allows us to choose another username which is nice in case you need to log in with another user instead of the default one.

Testing pam entries

Before we make any modification in files within /etc/pam.d make sure to create a backup of any files modified. If any error is made within these modules this might lock you out of your system. Also having a shell open with a root login might be a good idea and the entries should be well-tested before rebooting.

The pamtester utility can help with testing the pam rules before rebooting. contains a modified version of the pamtester. The arch user repository seems to build from this source here: https://sourceforge.net/projects/pamtester/. I am always a bit weary of using software from Sourceforge and the GitHub repository so you might want to use the GitHub version.

With the following command we can test the pam rule for the system-local-login file we will modify later. Just replace your <user>:

pamtester -I tty=`tty` system-local-login <user> authenticate

Configuring fingerprint reader

See also https://wiki.archlinux.org/title/Fprint for configuring fprintd.

Generally, if you need to interact with a fingerprint reader device you can install the fprintd package.

sudo pacman -Sy extra/fprintd

Some applications also require libfprint which in newer versions installs a library called libfprint-2.

suco pacman -Sy extra/libfprint

Afterwards, you can register your fingerprint using the following command:

fprintd-enroll <user>

This will prompt you to touch the fingerprint scanner 5 times and your data is stored in /var/lib/fprint if you want to back it up.

Check with fprintd-verify if the scanner can recognize your enrolled fingerprint.

Creating the PAM entry for fingerprint scanning

When installing fprintd a pam module called pam_fprintd.so will automatically be available for you.

Add the following entry at the top of the file /etc/pam.d/system-local-login:

auth	sucifficient pam_fprintd.so

The /etc/pam.d folder contains configuration files specifying what should happen when a service tries to authenticate. Different files correspond to different programs that need authentication such as /etc/pam.d/sudo for the sudo command or /etc/pam.d/useradd for the useradd command. In each of these files, you can carefully configure what authentication methods should be used and which users are allowed to run a command or service. Depending on your system some of these files might be a bit different.

To configure my local login we modified the /etc/pam.d/system-local-login. By adding the auth sufficient pam_fprintd.so line at the top we say that if the fingerprint scanner authentication is successful it is sufficient for login for the user. Pam also lets you configure multiple required authentication methods and also defines methods for resetting credentials and restricting access to specific users or certain conditions, as well as will log certain authentication events. Make sure to not change any other lines, keep the rest of the file as before so that the default auth flow works as before.

After modifying /etc/pam.d/system-local-login we can try to log in and should be presented with a fingerprint scanner authentication request.

Be sure to have a root shell open in case you mess something up here and have backups of the modified files as you might otherwise not be able to log in anymore (which also happened to me).

In addition, I added the same line for the sudo command.

Creating the PAM entry for YubiKey authentication

Check the arch wiki pam entry for more information.

The pam module for YubiKey authentication I used is called pam-u2f and is developed by Yubico. They also have some documentation in their pam-2uf git repo.

sudo pacman -Sy `community/pam-u2f`

Similar to the fingerprint scanner you will first need to register your YubiKey using the pamu2fcfg command. This will create a file in your ~/.config/Yubico/u2f_keys folder. Be sure to set the hostname value to your specific hostname as we will set this also afterward when configuring the PAM module.

pamu2fcfg -o pam://hostname -i pam://hostname > ~/.config/Yubico/u2f_keys

Afterward we can add a second entry in the /etc/pam.d/system-local-login file below our fingerprint scanner to use the YubiKey authentication in case fingerprint reading fails. Keep the rest of the file as before.

auth	sufficient	pam_fprintd.so
auth	sufficient	pam_u2f.so origin=pam://hostname appid=pam://hostname cue [cue_prompt=Touch your yubikey for login]

The line auth sufficient pam_u2f.so origin=pam://hostname appid=pam://hostname cue [cue_prompt=Touch your YubiKey for login] configures our pam_u2f module. Make sure to use the same hostname here when registering your key. I also added the cue and [cue_prompt=] parts where you can set the cue that is printed in the console that you need to use your YubiKey for authentication.

Run the pamtester again and reboot which should now prompt first the fingerprint scanner and if this fails with the YubiKey prompt.