Authentication with U2F in NetBSD
NetBSD U2FI wanted to log in to my laptop without typing a password.
Just with my USB keys.
I also wanted to run sudo
or doas
without doing so.
NetBSD comes with PAM and U2F libraries in the base installation, to my surprise.
So, this is how I configured PAM to use the keys.
PAM configuration
As always, the ArchWiki have enough information to proceed with BSD systems. The Yubico docs are good too, even if the key comes from a different vendor. Assuming that the key implements FIDO U2F, of course.
The man pages will help you too: read pamu2fcfg(1)
and pam_u2f(8)
before doing anything.
Steps
First step is to open a terminal emulator and login as root.
Just in case PAM rules are messed up or destroyed, you have a root session to fix the system.
It’s also good practice to copy every file, before modify it, to /root
so you can restore a good configuration if needed.
To begin, I created a file for U2F certificates.
# mkdir /usr/share/u2f/
# pamu2fcfg -o pam://hostname -i pam://hostname -u username > /usr/share/u2f/u2f_keys
Here you should replace hostname
with your actual hostname, and username
with your actual username.
If you have more keys to add, you do the same without stating the username.
# pamu2fcfg -o pam://hostname -i pam://hostname -n >> /usr/share/u2f/u2f_keys
It’s good practice to have a back up key. More on that later.
It’s important to make sure that the file have only one line per user. Only one line per user, and only the first key in the line should contain the username.
Then, I created a file with a PAM rule for U2F in /etc/pam.d/system
.
But first, backup.
# cp -vp /etc/pam.d/system /root
I added this rule at the end of all sufficient
rules.
/etc/pam.d/system
auth sufficient pam_u2f.so cue origin=pam://hostname appid=pam://hostname authfile=/usr/share/u2f/u2f_keys
Again, replace hostname
with your actual hostname.
Here, we are telling PAM that the key es sufficient to authenticate a user.
cue
will print to stdout a message like Please touch the device so the user know what to do.
authfile
should have the path to certificates file that was just created.
appid
and origin
are the relying party of U2F authentication.
In theory, the default is origin=pam://hostname
, and appid
is the same than origin
.
In practice, depending on the version of your pam_u2f library, it may or may not work without explicitly specifying it.
The docs have that info covered. Also, other parameters may be useful to you.
It’s possible to add debug
as a parameter at the end of that line in case you need debugging or troubleshooting.
The rule states sufficient
, so the USB key will be sufficient, but the password will be enough too.
That is only one factor, because that was I wanted.
If I don’t have the keys, typing my password also works.
If you want two factors, password plus key, you should replace sufficient
with required
.
And that’s it.
Open a new terminal emulator and test doas login
to see if you are required the key to run doas
.
Also, the key should be required by login
if you try your username.
Note that this doesn’t cover X display managers, nor DE Keychains.
Keychains are encrypted, so they really need a passphrase.
And X display managers may use different PAM config files. Or not.
I use Mate DE, and it asks me the key to unlock the screen by just adding that new rule to /etc/pam.d/system
.
But other DEs may require to modify a different file.
This also works on Linux, but filenames and paths may vary from distro to distro. If you are a victim of Systemd’s home encryption: that will need a passphrase. Although subsequent authentications may not require it. Your millage may vary.
The important thing is: backup PAM files before modifying them. Also, have a terminal emulator with root session ready to fix the system, in case your logins are broken.
So, why did I do this?
I’m not really good at passwords. For a long time I had one password for everything with variants to make it harder to guess.
Of course, that’s not the right thing to do, as credential stuffing attacks already cover that. So, a few years ago I did the right thing: I started using a password manager.
My password manager stores unique, long and random passwords for everything. I case of a data breach, a password of mine is useless for other services. But this presents a new problem: A password manager itself requires a password. My computer’s disk encryption and system user also ask for passwords. And none of those can be stored in the password manager. After all, how can I access the password manager before my computer boots or before I open the password manager itself? So, I created a few random passphrases using Diceware. And I wrote them down in a safe place. Over the time I ended up learning those by repetition, but at the beginning the small handbook with passphrases was very useful.
Of course, I had to store than handbook safely. Just like everyone stores credit cards, passports and alike. Putting a post-it in the laptop with its password is a very bad idea, and defeats the purpose of disk encryption.
I hated typing those passphrases, but never though of a solution to this. They are inevitable I though.
Two factor authentication (2FA)
A few months later, I started to use my password manager to store 2FA TOTP.
And all these years that’s the way I did thing: passwords and 2FA in my password manager. Plus a few passphrases I remember, to log in.
Life was simple and I was happy. Although I hated typing those few passphrases.
Until a few months ago.
Is it really “second factor” if it’s stored in the same place as the 1st factor?
If you read KeePassXC docs you’ll see it states:
Storing TOTP codes in the same database as the password will eliminate the advantages of two-factor authentication. If you desire maximum security, we recommend keeping TOTP codes in a separate database that you only unlock when needed.
Probably storing 2FA TOTP in the same password manager is better than not having 2FA at all. But it’s not really giving you the advantages of true 2FA. There are not two factors: it’s just one factor applied twice.
This made me go into the rabbit hole of 2FA. I read about U2F keys and passkeys.
So, what is true 2FA?
You see, to authenticate a human there’re three types of factors that we are currently using:
- Something only you know.
- Something only you have.
- Something only you are.
Something only you know is usually a password or passphrase. A password manager is kind of a function that transform your master password into a specific password for a specific service. In a way, a database of a password manager is something only you have, since you need that file or webservice to run this function. But that is not used to authenticate you. If you ended up learning the password inside your password manager, the authenticator wouldn’t notice. So, it’s just one factor, with or without password manager.
Something only you have is usually an object. 2FA TOTP is based on the idea that the secret seed is stored in a mobile device, or similar. And only you have that device. So, when you type the six digits of TOTP, you are giving the authenticator proof that you have that object at that time.
Something only you are is usually your fingerprint or other biometrics. In my humble opinion, biometrics are not a good idea for authentication: they are not really secret and you cannot modify them when needed. Biometrics are good usernames but bad passwords, because they are not secret but they are kind of unique.
So a true 2FA should use two factors of two different types. Leaving outside biometrics, it should be something only you know and other factor only you have.
U2F
So, I bought two cheap USB keys that follow FIDO U2F standard. I know cheap is subjective. In this case cheap means 30€ approximately.
Why two? Because in case of damage or loss I wouldn’t be able to authenticate.
These keys are made so you can’t extract the secrets inside of it without destruction. And they are all unique. So you have to own at least two: a main key and a back up.
Websites and systems that allow U2F usually let you enroll multiple keys. So you can have multiple back ups.
Back ups should be stored securely, like credit cards, passports, etc. And the main key should be with you.
So, I enrolled my keys everywhere I could and started to be happy again.
Can you use it to authenticate in NetBSD or Linux?
As I said at the beginning: I’m really bad at passwords.
When I log in to my laptop, or type sudo
, or doas
it’s common for me to type my password multiple times because of typos.
Also I love mechanical keyboards, specially the noisy ones.
And these noises can leak sensitive information.
So, I configured PAM to unlock my laptop and run doas
, with USB key only.
No password.
Is it really secure?
The problem, of course, is that anyone with the key is root on my laptop.
I like to think of that like a car: anyone with the key can drive it. So you should watch the key. Also, it’s a really bad idea to park the car on a street, with the key plugged in.
One of the keys is stored securely, with other important stuff. The other key is with me, almost all the time.
If the laptop is turned off the keys are useless, because of disk encryption. But once it’s turned on, I should never leave the laptop alone with the key plugged in. That’s the equivalent of a post-it with the password stuck to the monitor.
I plug it in when I use it: usually a few minutes while I’m running stuff as root. Then I unplug it, specially if the laptop will be alone. When I come back I plug it to unlock the screen. If I don’t need to authenticate anymore, I unplug it again.
The thing is: don’t let the keys plugged in all the time. That defeats the purpose of the key.
Not watching the key and the laptop at the same time could be a security issue. It’s kind of my Horcrux.