From Fedora Project Wiki

Introduction: Using Solo Keys with Fedora

Solokeys are hardware tokens. More specifically they are open-source hardware and firmware security keys based on the FIDO2 open standard. More information can be found in the official FAQ's and the Official Documentation.

In this guide we introduce solo keys and how to use them. There use cases we 'll mention are, using your keys for web authentication, upgrading your key's firmware, using your keys to authenticate on a Fedora system and using Resident Keys to generate static responses. We 'll describe all of them but we 'll focus on the steps required to use a solo USB-c key to authenticate in a laptop running Fedora MATE 32.

Using the keys for Web authentication

A key usage of FIDO2 keys is to use them as a 2nd Factor authentication for websites. Fedora versions up to 31 include package u2f-hidraw-policy and allows solokeys to work by default. When upgrading to Fedora MATE 32 the systemd package was listed as a replacement therefore systemd is now responsible for having the udev rules in place for the solokeys to work out of the box.

You can use this yubico demo website to test that your keys work properly. Select the WebAuthn test.

Note that because of how key generation works for "regular" usage of a FIDO2 key as 2FA for a website nothing is saved in the solokey and therefore it can support an unlimited number of websites.

Upgrading the firmware of your security keys.

The solokeys come in two versions. The solo secure and the solo hacker. The difference is that the solo secure keys have a locked bootloader that can only receive firmware signed from the solo company. Those are the keys suggested for general users.

Upgrading firmware for solo secure keys

We 'll use the command line to upgrade our key. The solo team provide an source python package to facilitate the upgrade. First we need to install it.

# Install the solo-python package
$ pip install --user solo-python
...
# Let's verify that the package can see out key
$ solo ls
:: Solos
207D36705548: SoloKeys Solo 3.0.0

For the solo key to be upgraded it has to be booted in bootloader mode. For older keys we enter the key by having the key button pressed and we keep it pressed until the LED starts blinking. On newer keys we can enter the key and then use the command solo program aux enter-bootloader to reboot the key in bootloader mode.

# We check that out key is visible.
$ solo ls
Not using FIDO2 interface.
:: Solos
207636905548: SoloKeys Solo Bootloader 2.0.0
# We can now perform the update
$ solo key update
Not using FIDO2 interface.
Wrote temporary copy of firmware-4.0.0.json to /tmp/tmppa1gysdm.json
sha256sums coincide: b1822355eb1151f004cd7886ba338deee8c84488299ec3a8e5448a1057cd8455
using signature version <=2.5.3
erasing firmware...
updated firmware 100%             
time: 7.57 s
bootloader is verifying signature...
...pass!

Congratulations, your key was updated to the latest firmware version: 4.0.0

Your solo secure key is now up to date.

Also note that there is a Github Issue for supporting firmware upgrades through LVFS, that may eventually lead to a way to upgrade from a Graphical User Interface but at the moment this is not ready.

Upgrading bootloader and firmware for solo hacker keys

If you have a solo hacker key you can upgrade both the firmware and the bootloader.

This process can brick your solokey!
This section is just an example of the process that works. THERE IS NO GUARANTEE that you will not experience problems! Read carefully the whole section and be sure to know what each command is doing and whether it is appropriate for your situation.

Key resources for this process are the official solo documentation. More specifically the bootloader section and the programming section.

In order to upgrade the bootloader we need to boot our key in a special mode called DFU mode. This mode uses STMicroelectronics VID/PID pairs rather than the ones from Solo and therefore is not recognized by default. A quick way to add the desired udev rules can be seen below:

# Go to the appropriate directory
$ cd /etc/udev/rules.d
# Get the required udev rules directly from the solo repository
$ sudo wget https://raw.githubusercontent.com/solokeys/solo/master/udev/70-solokeys-access.rules
...
$ ls -la
...
-rw-r--r--. 1 root root  758 Apr 26 00:29 70-solokeys-access.rules

Now we can proceed with upgrading our solo hacker key. First however we need to get the latest firmware and bootloader version from the solo releases.

Writing firmware from DFU mode erases everything in the solokey.
It is important that the firmware we write includes a working bootloader. Otherwise we will end up with a bricked device!

Since we intend to keep our hardware key configured as a hacker key we get the latest version of the bundle-hacker-*.hex If we wanted to convert our key to a secure key, which CANT be undone, we would get bundle-secure-non-solokeys-*.hex For more information read the solo documentation. The upgrade process looks as follows:

# Download the latest bootloader+firmware official release.
$ wget https://github.com/solokeys/solo/releases/download/4.0.0/bundle-hacker-4.0.0.hex
...
# Plug the key
$ solo ls
# Reboot the key in bootloader mode:
$ solo program aux enter-bootloader
# Instruct the key to go in DFU mode
$ solo program aux enter-dfu
Not using FIDO2 interface.
Please powercycle the device (pull out, plug in again)
# We plug in and out the key, then verify it is in DFU mode:
$ lsusb
...
Bus 001 Device 009: ID 0483:df11 STMicroelectronics STM Device in DFU Mode
# Then we program the key:
$ solo program dfu bundle-hacker-4.0.0.hex
...
# After the update process finishes we get off DFU mode:
$ solo program aux leave-dfu
Rewriting option bytes...
Warning: OSError with write_page
Please powercycle the device (pull out, plug in again)

You solo key should now be upgraded. Note again that this is a SAMPLE process and not a reference process. Make sure the steps are appropriate your device and it's current software versions. There is NO GUARANTEE that the process as listed above will not cause problems for your device.

Using solo keys as another authentication option for a computer running Fedora MATE.

Sample setup

In this section we will speak about how to use solo keys as another means of authentication on a computer running Fedora MATE. This guide will be specific to Fedora MATE because each Desktop Environment uses it's own session and login manager which means the steps below will have to be adjusted for other Fedora Spins.

First we need to install some required software.

# Install necessary libraries
$ sudo dnf install pamu2fcfg pam-u2f

Then we need to generate mappigs for the solo keys we want to register. In this example we also show how to register a key for another user. Whenever we want to register a key we should have that key plugged in before the pamu2fcfg command.

# Generate key mappings
# Generate mapping for 1st Solo key
$ pamu2fcfg > ~/u2f_keys
# Add new line (because next command will not)
$ echo >> ~/u2f_keys
# Generate mapping for 2nd Solo key
$ pamu2fcfg >> ~/u2f_keys
# Add new line (because next command will not)
$ echo >> ~/u2f_keys
# Add entry for another user:
$ pamu2fcfg -u $OTHER_USER_USERNAME >> ~/u2f_keys

Unfortunately the file we have generated does not have the correct format. We have to edit using a text editor. As we can see in the Central Authorization Mapping section of this yubico pam-u2f documentation page the config file needs to have the following format:

<username1>:<KeyHandle1>,<UserKey1>:<KeyHandle2>,<UserKey2>:...
<username2>:<KeyHandle1>,<UserKey1>:<KeyHandle2>,<UserKey2>:...

Hence we edit the ~/u2f_keys file we created so that it ends up having the format above. We then copy the file to the location /etc/u2f_mappings. We are now ready to use this file in our PAM configuration files, located in /etc/pam.d/, to allow authentication through our registered solo keys.

Let's identify the files we need to change first.

  • lightdm: Since Fedora MATE uses lightdm as it's session manager this is the file we need to change.
  • mate-screensaver: This file controls logging back in when we lock the screen.
  • polkit-1: This file controls elevating user priviliges to administrator privileges. For example for using the MATE User Manager application to add another user.
  • sudo: This file controls authentiation for the sudo command. The user calling sudo must have appropriate permissions.
  • su: This files allows authentication for the su command. The user called must have the solo key used registered as well. Using a key that way may be convenient in a shared computer but can also be a security risk. Use appropriately based on your needs.

The key thing we need to do is to add the following line:

auth        sufficient    pam_u2f.so authfile=/etc/u2f_mappings cue

on the files above. Note that on the the lightdm file it needs to be after the line specifying the pam_selinux_permit.so module.

There is a danger of locking yourself out of your system when making such changes!
To prevent that you can take precautions such as:
  • Make a backup of the configuration files before modifying them so that it's easier to undo your changes if something goes wrong.
  • Make sure to have a root session active so that you can undo any changes if something breaks the authentication workflow. I suggest switching to a new text console with Ctrl+Alt+F2 and authenticating there as root. You can then go back to the main graphical console Ctrl+Alt+F1 and proceed with your changes. If you experiance authentication problems go to the text console and undo your changes.

Below we see a diff of all the modified files:

$ diff lightdm lightdm.bk0 
3d2
< auth       sufficient  pam_u2f.so authfile=/etc/u2f_mappings cue
$ diff mate-screensaver mate-screensaver.bk0 
4d3
< auth       sufficient   pam_u2f.so authfile=/etc/u2f_mappings cue
$ diff polkit-1 polkit-1.bk0 
3d2
< auth       sufficient   pam_u2f.so authfile=/etc/u2f_mappings cue
$ diff sudo sudo.bk0 
2d1
< auth       sufficient   pam_u2f.so authfile=/etc/u2f_mappings cue
$ diff su su.bk0 
2d1
< auth            sufficient      pam_u2f.so authfile=/etc/u2f_mappings cue


Alternative Configuration options

  1. You can, if you want, make the security key required for authentication instead of it just be another way to authenticate. This is the option that increases your security as the key is then used as 2nd Factor Authentication (2FA). In order to do so you need to use required instead of sufficient in the pam configuration file changes. If you use a solo key as 2FA it is advised to register a second and keep it in a secure location. This way if your first key gets lost or damaged you will not be locked out of your system.
  2. In the setup we described the solo key needs to already be inserted in order for it to be used for authentication. If you want to be prompted for the security key then you need to add the interactive option in the pam config files. Hence the line you add will be like:
    auth        sufficient    pam_u2f.so authfile=/etc/u2f_mappings cue interactive
    
  3. If you set up your system to allow passwordless logins with the solo keys you will have a problem with unlocking the gnome keyring, on systems where it is present. This means that after you log in to your session you will be asked for your password in order to unlock the keyring. By default the gnome keyring set up to use the user's default password to secure the keys stored there. However if you authenticate with a solo key then the gnome-keyring can't be provided with your password in order to get unlocked. I don't know of a good way around this problem and I won't mention any bad ways that may solve this "problem" by breaking the security design of your Fedora installation.


Using FIDO2 Resident Keys.

By (ab)using the hmac-secret FIDO extension one can get static responses from the solo keys. From the command line a key can be generated as:

# Make sure to note the hex encoded credential id.
$ solo key make-credential --host $YOUR_HOST --user $ANY_USER
...
<credential_id>

You can then geenerate static responses by:

$ solo key challenge-response --host $YOUR_HOST $credential_id $any_challenge
Touch your authenticator to generate a reponse...
<static_response>

The Resident Keys functionality has several limitations:

  • Solo Keys can only store 50 Resident Keys
  • You cannot list the keys stored on the device.
  • If you generate a new credential with the same (host, user_id) pair, it will likely overwrite the old credential, and you lose the capability to generate the original responses too.
  • The response depends on a secure key in the solo hardware as well as the credential and the challenge hence it cannot be reproduced outside of the solo key because the secure key cannot be extracted.
  • You cannot make a backup of those keys, hence make sure you store elsewhere the static responses if you need to.

Additional information on resident keys can be found on the solo-python readme, and this github post.