I got my U2F key for use with online accounts. It is cheaper than the popular Yubikey and it works well. Did you know you can use it for sudo or pam authentication? Here is how.
First, install the pam module and tool
sudo apt install libpam-u2f pamu2fcfg
Once installed, configure u2f mapping for the current user
❯ mkdir -p ~/.config/Yubico
❯ pamu2fcfg > ~/.config/Yubico/u2f_keys
Next, configure the /etc/pam.d/sudo and /etc/pam.d/sudo-i. Add the following above the “@include common-auth” line. The second parameter tells pam that u2f authentication is sufficient. If you try to run sudo remotely and you cannot access the u2f dongle, PAM will prompt for password after 10s. If you do not wish to allow password authentication, change sufficient to required.
auth sufficient pam_u2f.so cue userpresence=1
Next, check that sudoers is configured to require password authentication. Previously, I have my user configured with the NOPASSWD option, and pam will not prompt for authentication.
To test, you may need to wait until sudo timeout is reached. Default setting is 30 minutes. Or use another terminal program if you don’t want to wait.
❯ sudo -i
Please touch the device.
[email protected]:~#
You can also enable U2F authentication for other pam services. Check out the instructions from Yubikey.
Now sudo is secured. It’s a good idea to also secure su. Edit /etc/pam.d/su the same way as you sudo config. Copy ~/.config/Yubico/u2f_keys to /root/.config/Yubico/u2f_keys. When I run su, pam asked me to touch my u2f key.
❯ su -
Please touch the device.
[email protected]:~#
Lastly, disable pkexec or any other tools that allow a user to gain root access.
chmod 000 /usr/bin/pkexec
Before you go
Review your crontab, there may be scripts or commands that require sudo. To allow some programs to run without authentication, while enforcing authentication for unspecified commands, specify that in /etc/sudoers. For example, the following allows password-less execution of ip and some-script.sh, and require authentication for sudo -i (run bash).
some-user ALL=NOPASSWD: /bin/ip,/home/some-user/some-script.sh,/usr/bin/tcpdump,/usr/bin/ip, PASSWD: /bin/bash