Sudo with Solokey
Having sudo
privileges enabled for your normal workstation user
account is both a convenience and a security concern. The Pluggable
Authentication Module for Linux (PAM) allows us to strengthen the
requirements for using sudo
, to include several authentication
methods beyond just asking for a password. This chapter will install
pam_u2f, which enables PAM authentication via FIDO2/U2F compatible
hardware tokens like the Solokey. Each time sudo
asks for
authentication, it will prompt for a Solokey button press and a
password to be entered.
Some of this guide was adapted from these other guides:
Thank you to the Fedora documentation team!
Open a root session as an anti-lockout measure
To prevent yourself from being locked out of your own system during the setup process, it is recommended to start a new terminal in a root session, and to keep it open. That way if you lock yourself out, you still have a way you can fix it.
## Open root session and leave it alone in another window ....
sudo su
Consider adding a root password
If you use sudo
a lot, you might not actually know the real root
password of your system (or one might not even be set). As a backup,
you may want to set a secure long random passphrase for the root
user and keep it safe (you will rarely need it).
Reset the root password with a random string:
(set -e
LENGTH=26
PASSWORD=$(tr -dc 'A-Za-z0-9!@#$%^&*()[]~+-_=?<>.,;:' < /dev/urandom | head -c ${LENGTH})
echo -e "\nSave this ${LENGTH} character long password somewhere safe: ${PASSWORD}\n"
read -e -p "Do you want to reset the root password with this value (y/N)? " answer
(test "${answer,,}" == "y" || test "${answer,,}" == "yes") && \
sudo sh -c "echo 'root:${PASSWORD}' | chpasswd && echo Done." || \
echo "Cancelled."
)
Test that the root password works without using sudo
:
su
Register Solokeys
It is recommended that you register at least two solokeys: a primary key, and a backup key. That way, if you lose one of the keys, you can still use the other one.
Do the next steps as your normal workstation user account, which is
the account that should already have sudo
privileges.
Create a tempory file to capture solo key registrations:
TMP_KEYS=$(mktemp)
- Plug in the first solokey, then run:
pamu2fcfg >> ${TMP_KEYS} && \
echo >> ${TMP_KEYS}
It may ask you to enter the PIN of the solokey:
Enter PIN for /dev/hidraw1:
-
When the solokey lights up, press the button.
-
Unplug the first solokey and repeat the last command for the second solokey.
-
Unplug the second solokey and repeat for additional solokeys.
-
When you’ve written all the keys to
${TMP_KEYS}
, reformat and install them into their final destination:
echo "${USER}:$(cat ${TMP_KEYS} | \
cut -d ":" -f 2 | tr '\n' ':')" | sed 's/:$//' | \
sudo tee /etc/u2f_authorized_keys
Create custom PAM modules for U2F
You will create two new PAM modules: u2f-required
and
u2f-sufficient
. They will both include these required settings:
- The
authfile
path to our authorized key list file. - The
cue
literal to show thePlease touch the device
prompt message for each authentication. (If you omit this, it will print nothing, which can be confusing).
The only difference between the two PAM modules is that one is required, and the other is merely sufficient.
required
means to enable 2FA: solokey + password required.sufficient
means to disable 2FA: solokey OR password is sufficient.
cat << EOF | sudo tee /etc/pam.d/u2f-required
#%PAM-1.0
auth required pam_u2f.so authfile=/etc/u2f_authorized_keys cue
EOF
cat << EOF | sudo tee /etc/pam.d/u2f-sufficient
#%PAM-1.0
auth sufficient pam_u2f.so authfile=/etc/u2f_authorized_keys cue
EOF
The PAM modules you just created (/etc/pam.d/u2f-required
and
/etc/pam.d/u2f-sufficient
) can be used for extending any of the
other pam modules found in /etc/pam.d
, by adding an appropriate
include
line at the right place. This can affect many more system
authentication methods than just sudo
, so be careful, but only
sudo
will be covered for now.
Configure PAM hook for sudo
As root
, edit the file /etc/pam.d/sudo
, and insert a new line
directly after the #%PAM-1.0
header. A PAM module follows rules in
top down order, as they are listed. Therefore your solokey rule needs
to be the first authentication mechanism, and the existing password
flow is the second authentication method.
#%PAM-1.0
auth include u2f-required
auth include system-auth
account include system-auth
password include system-auth
session optional pam_keyinit.so revoke
session required pam_limits.so
session include system-auth
Line 2 (auth include u2f-required
) is the only line that was added
to this file. Everything else in this file was here originally and is
left intact.
If you change u2f-required
to u2f-sufficient
, then it will disable
2FA allowing solokey press OR user password as sufficient!
Test sudo
When testing sudo, always open a new terminal for each test. This is to avoid the auth caching mechanism (which is reset for new terminals).
sudo su
The PAM system should now ask for you to touch your solokey (or press the button), and afterward prompt for your password.
Please touch the device. [sudo] password for ryan: