Main page
Biometric authentication is a faster, more secure, and unarguably cooler method of authentication than plain old passwords. This article goes through the process of setting up a fingerprint scanner on FreeBSD and using it for biometric authentication.
I have only tested this on the AMD Framework 13 (as that's the only laptop I own which has a fingerprint scanner), so YMMV on other laptops, but in theory any scanner supported under Linux* (and that's most) should Just Workโข on FreeBSD following this guide.
*Except for ELAN scanners. More on that later.
Fingerprint scanner support is provided by the libfprint
library.
It provides an API for fingerprint scanning devices, as well as the userspace drivers for a range of different fingerprint scanners.
Most scanners are connected via USB, even if they're internal, so all that's really needed from the OS is for it to provide a USB interface to the device though a libusb
implementation, and the libfprint
userspace drivers sit on top of that.
This is where we hit our first snag on FreeBSD, but I'll get back to that.
A separate fprintd
daemon is used to manage the fingerprint scanner (including a D-Bus interface and management commands), and also provides the pam_fprintd
authentication module for PAM.
In the past, you had the now-obsolete pam_fprint
module which didn't need fprintd
or D-Bus.
OpenBSD still has something similar with sysutils/login_fingerprint
, but unfortunately, at the moment, you're stuck with fprintd
and D-Bus on FreeBSD.
Now that you're up to speed with the general architecture, let's get to actually getting things to work!
Currently, the security/libfprint
port in FreeBSD is very outdated, and doesn't support the 2nd version of the API or any new fingerprint scanners (including the Framework ones).
I'm working on a new port (new versions of libfprint
use Meson instead of GNU configure and include what was previously in the also now-obsolete security/fprint_demo
), but until that's done you'll have to build it yourself.
The main issue you'll encounter doing so is the build script not being able to find the udev
library, needed for fingerprint scanners connected via SPI (i.e. those from ELAN).
I believe it is named something different on FreeBSD than it is on Linux, so a patch probably needs to be made against meson.build
.
For now, you can just disable it with -Dudev_rules=disabled -Dudev_hwdb=disabled
.
In all, this is what you need to do to build and install libfprint
:
git clone "https://gitlab.freedesktop.org/libfprint/libfprint.git"
cd libfprint
meson setup build -Dudev_rules=disabled -Dudev_hwdb=disabled
ninja -Cbuild install
To test things out, there are some example programs you can run in the build/examples
directory buuuuut...
libusb_get_parent
...the next thing you'll run into is that libfprint
won't detect any scanners.
This is because it uses the g_usb_device_get_parent
function from devel/libgusb
, which always returns NULL
on FreeBSD, because it relies on libusb_get_parent
from the system's libusb
implementation, which FreeBSD doesn't implement yet (see PR224454).
I've implemented this in D46992, which is currently awaiting review.
You'll have to apply this patch to your libusb
library, rebuild it, and then rebuild libgusb
for libfprint
to be able to detect your fingerprint scanner correctly.
On certain revisions of Framework laptops, specifically those who's fingerprint scanner is on firmware version 01000320, libfprint
will still refuse to work, and will tell you to update your firmware.
This is a bit annoying and tricky to do.
On Linux, this is done using fwupd
, but this has not yet been fully ported to FreeBSD (though work seems to be well underway, see D29332).
In the meantime, you can just use a Linux live ISO. Do make sure fwupd
is up to date though as support for the AMD Framework's fingerprint scanner was only added in newer versions (see fwupd#3637).
Then, you can just follow the instructions at Updating Fingerprint Reader Firmware on Linux for all Framework Laptops | Framework.
If it says something about a transfer timing out, that's alright, it's still transferring in the background. Just wait a couple minutes and then reboot, and it should all work fine.
fprintd
As mentioned earlier, you need to build and install fprintd
.
It's a similar story to libfprint
: the security/fprintd
port is outdated on FreeBSD, so you need to build it yourself.
It's also a Meson project, so the process is pretty simple, you just need to pass -Dlibsystemd=basu
to the setup command as FreeBSD doesn't have systemd:
git clone "https://gitlab.freedesktop.org/libfprint/fprintd.git"
cd fprintd
meson setup build -Dlibsystemd=basu
ninja -Cbuild install
Then, we can create a service for fprintd
in /usr/local/etc/rc.d/fprintd
:
#!/bin/sh
# PROVIDE: fprintd
# REQUIRE: DAEMON dbus
# BEFORE: LOGIN
#
# Add the following lines to /etc/rc.conf to enable fprintd:
#
# fprintd_enable="YES"
#
. /etc/rc.subr
name=fprintd
rcvar=${name}_enable
: ${seatd_enable="NO"}
command="/usr/sbin/daemon"
procname="/usr/local/libexec/${name}"
pidfile="/var/run/${name}.pid"
command_args="-s notice -T ${name} -p ${pidfile} ${procname} -t"
load_rc_config ${name}
run_rc_command "$1"
And start it with:
service fprintd start
This is all assuming you've already set up D-Bus and the dbus
service is running.
You can naturally set it to start automatically in your /etc/rc.conf
by adding the fprintd_enable="YES"
line, and that's all.
Phew ๐ฎโ๐จ
fprintd
provides the fprintd-enroll
command (to be run as root!) to enroll fingerprints:
fprintd-enroll <username> [-f finger]
Finally, you need to add the following to the PAM configuration file for the system
service (/etc/pam.d/system
):
auth sufficient pam_unix.so no_warn try_first_pass nullok
auth sufficient /usr/local/lib/security/pam_fprintd.so
If you'd like a MFA setup, you can also set both authentication factors to be required
or requisite
, rather than sufficient.
See the pam.conf(5)
manpage for details.
This should now allow you to log in using your fingerprint!
doas
configurationYou can use the same policy for the doas
PAM service as for the system
service by creating the /usr/local/etc/pam.d/doas
file:
auth include system
That'll work, but it'll continuously prompt you for your password, even if like 1 ms elapsed since you last authenticated.
Vanilla doas
only supports the persist
option in its config on OpenBSD, not on FreeBSD.
You can install the security/opendoas
port which does let you use the persist
option on FreeBSD.
Do be advised that this might not be as secure as persist
is on OpenBSD, however.
The only issue is that the timeout is hardcoded to 5 minutes, which is a tad long.
You can just sed -i '' 's/5 \* 60/10/g'
files with occurrences of 5 * 60
to set the timeout to 10 seconds instead.
You're probably going to want user applications to have permission to verify fingerprints without needing to be root.
You can do this by creating a new Polkit rule in something like /usr/local/etc/polkit-1/rules.d/10-fprintd.rules
:
polkit.addRule(function(action, subject) {
if (action.id === "net.reactivated.fprint.device.verify") {
return polkit.Result.YES
}
})
To apply these changes, just restart the dbus
service:
service dbus restart
swaylock
swaylock
is a popular screen locker for wlroots
Wayland compositors.
It doesn't support fprintd
by default, however.
Fortunately, there is a swaylock-fprintd
fork of swaylock
which does.
This port is slightly broken on FreeBSD.
In fingerprint/meson.build
, you need to change the /usr/share/dbus-1
prefixes to /usr/local/share/dbus-1
.
Then, in the /usr/local/etc/pam.d/swaylock
PAM service file it installs, you need to include the unix-selfauth
service instead of login
.
Finally, you can run swaylock
with --fingerprint
, and it should work fine (there's no need to add fprintd
in its PAM service file):
swaylock --fingerprint
HTH! ๐
I will keep this article up to date as I work on the new libfprint
and fprintd
ports.