A FIDO U2F security key is a small USB and/or NFC based device. It is a hardware security token with modules for many security related use-cases. There are several brands of FIDO compliant keys, including NitroKey, SoloKey v2, and YubiKey. FIDO, in contrast to proprietary protocols like Yubico OTP, is hardware token agnostic and the tools used are manufacturer independent.
This post introduces the FIDO protocol(s) and shows how to install and enable a FIDO U2F security key as an alternative authentication factor for logging into a terminal, GDM, or authenticating for sudo.
For YubiKeys, especially older ones without FIDO2/U2F support, see the previous post titled “How to use a YubiKey with Fedora Linux“.
This post will not cover storing OpenPGP keys or X.509 certificates because those features are hardware dependent and not part of the FIDO U2F standard.
Keep a backup security key
As soon as you start working with security tokens you have to account for the potential to lock yourself out of accounts tied to these tokens. As hardware security tokens are unique and designed to be extremely hard to copy you cannot just make a backup of it like you can with software vaults like KeePass or AndOTP. Consequently, all registrations you make with your primary key you should immediately repeat with a second backup key that you will store in a secure location, maybe even a safe.
In practice this means you will need to register both hardware tokens with your Linux and web accounts, generate OpenSSH private keys twice, and upload both OpenSSH public keys to the servers and services you use (for example, GitHub).
Should you lose a key, you’ll want to use your second key to sign in on every service the keys are registered with, remove the lost key, and register a new one. This is especially true for password-less logins using a FIDO2 protocol.
FIDO2, U2F and the FIDO Alliance
FIDO2 is a collection of standards maintained by the FIDO Alliance. The FIDO Alliance hopes to eventually get rid of passwords altogether and instead provide procedures to authenticate users securely through multiple factors but without the need for passwords.
The standard consists of the World Wide Web Consortium’s (W3C) Web Authentication (WebAuthn) and the FIDO Alliance’s Client-to-Authenticator Protocol (CTAP). WebAuthn is a standard API to request and process public key challenges for authentication. With this, browsers send a challenge to a client which then produces a response with a private key that the challenger then verifies using a previously exchanged public key. How the challenge answer is produced is unknown to the service and it is controlled by the CTAP. The user might be prompted for several verification methods like biometrics, PIN, or presence check (or some combination of these methods). These checks are the same for authentication as they are when registering the key with the service.
A access PIN to protect any interaction with the hardware token is optional and it is unset by default. Most keys will self-invalidate after eight sequential failed attempts at entering the access PIN. The only way to recover an invalidated key and set a new PIN is to reset the key. However, when a key is reset, all its service registrations will be lost!
A FIDO2 key also supports the FIDO U2F protocol (now renamed CTAP1). This protocol is designed for second- or multi-factor (but not password-less) authentication. Linux’s PAM authentication system can also be configured to use the U2F protocol. Although FIDO U2F is not designed for password-less authentication, the U2F PAM module does allow password-less authentication.
FIDO2 / U2F works by tying the security key to your user account. Most keys have a basic presence-check which is enabled / used by default. They typically perform a presence-check by lighting up and prompting you to touch the key. A FIDO2 PIN is optional and it will be unset by default. When the key is registered for signing in to your Linux account or for using sudo, it is sufficient to have the device and key physically present. A FIDO2 PIN is an important additional verification step to ensure that only you can use the key for authentication.
Wait! Now I have to keep track of an additional PIN? Isn’t this just a shorter password?The concerned reader
A FIDO2 PIN is not a password. It is a short, easy-to-remember phrase. This is not a problem because:
- You need physical access to the key and you need to know the PIN.
- Failing to enter the PIN eight times will invalidate the key which makes it hard to brute-force.
On the contrary, you can now use a secure password stored in a password manager that you don’t need to remember.
A 2016 case study by Google, titled “Security Keys: Practical Cryptographic Second Factors for the Modern Web“, shows security keys effectively protect users from password reuse, phishing and man-in-the-middle attacks.
User authentication using PAM
Local system authentication uses Pluggable Authentication Modules (PAM). The PAM module for U2F devices (and hence authentication) is pam_u2f. Whether your key supports FIDO2 or FIDO U2F will depend on its firmware version and hardware model.
The setup is as follows:
- Install the PAM module.
- Register a key with your user account.
- Use authselect to activate smart card support in PAM.
Authselect is a tool for configuring PAM with reproducible profiles. By using authselect’s profiles, manually altering configuration files under the /etc/pam.d directory can be avoided.
The required packages are available in the official repositories.
[…]$ sudo dnf install pam-u2f pamu2fcfg fido2-tools
Set a FIDO2 PIN on your key
The FIDO2 standard defines an optional PIN for access protection. There is no PUK or other way to restore a lost or invalidated PIN so make sure you have a backup approach for authentication. If the PIN is invalidated through sequential entry of invalid PINs, the only way to recover is to reset the key. However, resetting your key removes all its credentials and disconnects it from all previously registered services.
The fido2-tools package contains a tool to set the FIDO2 PIN of your key: fido2-token. Get a list of currently connected FIDO2 devices with fido2-token -L and set a new pin with fido2-token -C </path/to/device>:
[…]$ fido2-token -L /dev/hidraw1: vendor=0x1050, product=0x0407 (Yubico YubiKey OTP+FIDO+CCID) […]$ fido2-token -C /dev/hidraw1 Enter current PIN for /dev/hidraw1: Enter new PIN for /dev/hidraw1:
Register the security key with your local account(s)
Use the tool pamu2fcfg to retrieve a configuration line that goes into ~/.config/Yubico/u2f_keys. pam_u2f is a Yubico-provided, generic module for U2F keys, hence the Yubico specific default configuration path. Each configuration line in this file consists of a username and a key-specific credential / config part separated by colons. Be sure to only use one line per user.
fedora-user:owBYtPIH2yzjlSQaRrVcxB...Pg==,es256,+presence+pin[:another key for this user]
If the key is PIN protected you’ll be asked to enter the PIN for this operation. Use the following for the initial registration of your first key:
[…]$ mkdir -p ~/.config/Yubico […]$ pamu2fcfg --pin-verification > ~/.config/Yubico/u2f_keys
To add another key (for example, your backup key) to this single-user configuration, use the following command:
[…]$ pamu2fcfg --nouser --pin-verification >> ~/.config/Yubico/u2f_keys
pam_u2f also supports the use of a central authentication file. In that case, be sure to use one line per user and to keep all the keys of a given user on the same line. If two lines reference the same username only the last one will be used! Have a look at the pam_u2f man page for all available options.
Configure PAM with authselect
authselect is a tool for controling your system’s PAM configuration. It introduces profiles as an additional layer of abstraction. One authselect profile can change several PAM configuration files. Profiles have parameters that control additional features and behaviors like enabling FIDO U2F security keys. A detailed tour of authselect is planned for a future article.
Display the currently active authselect profile. With the SSSD (System Security Service Daemon) profile selected and U2F support enabled, the output might resemble the following:
[…]$ authselect current Profile ID: sssd Enabled features: - with-pam-u2f
Activate FIDO U2F support in PAM using authselect with the with-pam-u2f flag:
[…]$ sudo authselect select sssd with-pam-u2f
If you also want to use your fingerprint reader you have to enable both features:
[…]$ sudo authselect select sssd with-pam-u2f with-fingerprint
This activates the sssd profile with pam_u2f and fingerprint reader support. For example, when using sudo on a terminal with the above authselect profile configuration, you’ll first be asked for a fingerprint and if that fails for the U2F key. GDM, however, will use the U2F key first.
Unlocking the GNOME keyring daemon
When using biometrics, a U2F key, or any other method that does not require a passphrase to sign in to GNOME, the Login keyring cannot be unlocked automatically. This is because, by default, the keyring passphrase is set to the same value as your login passphrase. Normally, PAM passes your login passphrase to the keyring daemon. Since you are not entering a passphrase when authenticating via methods such as biometrics or U2F keys, there is no passphrase for PAM to pass to the keyring daemon. There is no straight forward solution to this problem.
If you use LUKS encryption for your home partition and operate a single-user system, you could remove the passphrase from your keyring. This will leave your gnome keyring unencrypted at the file level. But it will still be encrypted at the block level by LUKS. LUKS encryption is equivalent to the default file-based keyring encryption on a single-user system since the keyring’s encryption is only designed to protect its contents from offline access. The keyring will be decrypted / unlocked after login either way and any runtime application or malware can potentially access the keyring’s contents after it is unlocked. Since LUKS is also an offline protection mechanism, it can be considered an equivalent alternative to the keyring’s normal file-based encryption.
LUKS encryption and the keyring’s normal file-based encryption are not equivalent if your system is used by multiple users. In the case of a multi-user system with the keyrings protected only by LUKS, any user with authorization to decrypt the disk and boot the system will be able to access any other user’s keyring on that same system.
Removing the GNOME Login keyring passphrase is straight forward. Just set a new empty password and the keyring will be unlocked and it will be stored unencrypted at the file level. The graphical utility seahorse (also called Passwords and Keys) can be used to set a blank password on your GNOME Login keyring.
Lookout and other use-cases
Upcoming articles will explore how to use FIDO2/U2F keys for unlocking LUKS-encrypted disks using the U2F Dracut plugin.
OpenSSH 8.2+ supports the use of ed25519-sk security keys. This topic has already been touched upon in the previous article titled “How to use a YubiKey with Fedora Linux“.
Note that FIDO2/U2F is an authentication standard. There are other use-cases for security tokens (primarily established by Yubico) like (T)OTP, PIV (for x509 key management) or OpenPGP which are not covered in general but on a hardware by hardware basis.
I think removing the password from your GNOME keyring is always a bad idea, no matter the usecase.
Yes, a LUKS-encrypted drive / home partition protects against offline-attacks. But that’s it. Once you are logged in, you have no protection whatsoever.
Imagine running some bad script or malicious program in your own user context. It can read (and probably write) all your files under ~. So it can easily get a copy of your keyring file from ~/.local/share/keyrings/ and submit it to some external server or whatever. You wouldn’t even notice, as these files are so small…
This can happen no matter if you have a passphrase set or or onto the keyring file itself.
The difference is that a keyring file without any passphrase is readable by anyone, so an attacker would now have all your saved credentials. If the file itself was protected with a passphrase, so its contents being encrypted, even if someone got read access, the only way would be to brute-force the passphrase, which is considerably more work than just opening an unencrypted file.
It’s a misconception that a password-protected but already unlocked keyfile would be unencrypted and as such easily read some malicious software. The keyfile never gets saved unencrypted onto the drive unless you remove the passphrase. As long as it has a passphrase set, the file itself is always still encrypted, the unencrypted data itself is just stored in the RAM while the keyring is in unlocked state, never written to disk. So even if someone takes a copy of your keyring file while it was unlocked by a passphrase earlier, the file itself is still encrypted.
I have to object until proven wrong. If an attacker manages to infiltrate the system and gain user-level access the unlocked keyring is available through the dbus API org.freedesktop.secrets. Any (potentially malicious) process could read secrets from an unlocked keyring that way.
That’s correct; that’s why I was specifically speaking about copying the keyring-file(s).
If I were to write malware, that would be the first thing I’d try, because it’s the most simple one.
Copying the file(s) will surely be unnoticed, whereas querying data from an unlocked keyring might (depending on the way the user has configured the system) trigger some notification, or even confirmation dialog to allow access to the keyring / wallet.
Yes, it’s only a different approach of a malicious software trying to steal sensitive data, but wouldn’t you want to make it as hard as possible? There is no 100% perfect security, but shouldn’t you at least try to deny as many possible ways of accessing the data as possible?
I mean, this is not the right place to propose some not very well thought out changes to the way the keyring(-access) works, I know this… But some quick thoughts would be:
1. mandatory user-confirmation (OK / Deny Buttons, nothing too fancy) each and every time some application wants to access data from the keyring. Except:
2. an option for the user to generally allow specific processes from the (several) systemwide /bin and /sbin folders to access the keyring without any kind of user-confirmation (which would minimize the impact of 1 on the user experience, as only user-programs / scripts which reside in any other location would trigger the popup). This would assume that the system itself is uncompromised; if one would get root-access to your system, you surely have bigger problems than the GNOME keyring). This way, things like your email-client or accessing a network ressource or letting the ssh client access the private key passphrase and so on would still work, but some random script from the internet would not be able to query your unlocked keyring unnoticed…
Finally, because I forgot to say it in my first comment: thanks for your article, it’s well written and very understandable.
I follow your line of thought and I’m with you that it’s best to do as much as you can. The decision to propose to unlock the keyring is based on the convenience trade-off which helps in implementing this login technology. I think the benefits of the security key with good UX outweigh the risk of an unencrypted keyring, something which is more security-by-obscurity than security-by-design. If there would be a way to still encrypt the keyring while unlocking it without an extra password prompt it would be a no-brainer to keep it encrypted – e.g. by a pam module that uses the pam_u2f authentication also for unlocking the keyring which is exactly what happens right now with the pam password prompt and gnome keyring unlock modules.
I also forgot to thank you for your constructive comment. You caught me at a bad angle by saying “it’s always a bad idea”, because I think that the concept of “principle” mostly results in unwarranted disregard of viable approaches / use-cases / trade offs
You make a good point, but counter point, Im a malware maker, Im already on your machine, I could take the files and scrape the keys out of memory, or swipe the passkey as you logon. All of those would be as equally unnoticed as copying your keyring file.
As Alexander points out really the key ring encryption is to help with offline attacks, the only way it would help with online attacks would be to do the same thing most password managers let you do, aggressively expire your session and lock the keyring, and if youre doing that chances are you dont care your keyring doesnt automatically unlock, infact its probably a feature for you not a bug.
We could get into affirmative consent for key ring access, and keep trust lists, and all of that, and that would be a step up but ultimately we will still have a problem of this key has to be in memory some time.
But I will say, your head and heart are in the right place and thanks for being constructive.
Why couldn’t malware run a command like the following to retrieve passwords from an unlocked keyring?
The GNOME keyring seems like an absolutely horrible idea. Security keys that use public-private-key encryption and store the private key in a way that cannot be retrieved definitely seem like the way to go.
Ernest N. Wilcox Jr.
I’d prefer that the Fedora team take steps to accommodate and simplify the implementation of passwordless authentication using FIDO0 passkeys (the coming security technology) to login securely with my fingerprint scanner at boot time as well as to use it to enable me to log into websites where I have set up passwordless login. While passwordless authentication is not yet universally adopted, it will be the most secure login option available after its implementation is completed. By setting up a passkey on my computer, and using a FIDO0 compliant biometric fingerprint scanner, I should be able to log into any website with which I have an account and with which I have configured passwordless authentication, and that should include logging into my Fedora computer, and root authentication using sudo, etc. I have read that this protocol may become broadly mainstream within the coming year and I want to be able to use it in my Fedora workstation as easily as I can in my Windows systems.
You actually have made a mistake in this configuration you will fallback on “password” if the key is missing or fail and password only will allow the login.
in my case i do
sudo authselect select sssd #remove useless thing
After in both /etc/pam.d/system-auth and sudo nano /etc/pam.d/gdm-password
auth [success=done default=die] pam_u2f.so prompt cue interactive sufficient required
success=done mean if successful ignore other auth, default die mean if a user have not set it will fail, prompt cue interactive make it blink will to push enter key before starting (like that if the key is not there you have time to plug it),
sufficient also allow the log when he’s the only one, required make it mandatory if it fail it do not use password as fallback.
If I omit the option –with-pam-u2f all entries about pam_u2f disappear from /etc/pam.d and the key is not used anymore. Tested on Fedora 38 Workstation GNOME edition.
In my machine there are other profiles enabled. It is ok to remove them? i don’t use fingeprint reader and others don’t know why are there:
Profile ID: sssd
I kept them and if i remove yubikey i can also login with my password.
I am using a trustkey g310 for log into fedora on all my devices for as long as Lennard Poetterings article https://0pointer.net/blog/unlocking-luks2-volumes-with-tpm2-fido2-pkcs11-security-hardware-on-systemd-248.html was posted.
It is really only the fact that gnome-keyring does not transparently work with it that is a little anoying, but bearable.