Secure 2FA with hardware token
So I got myself a YubiKey 5C FIPS, which is a very nice 2FA device which can store SSH Keys, PGP Keys and various Credentials.
The device itself is very nice and can be plugged into my phone or laptop through USB-C and is now part of my physical key ring.
It supports multiple usage modes. In general, CTAP2 is fully passwordless authentication (what you want from such a key) - where you only need to authorize against the hardware key with a PIN, while CTAP1 is only the 2FA so you still need to enter an account-specific passphrase.
Configure CTAP2
If needed for the first time, for example chromium asked me to configure my key with a PIN which is used for CTAP2.
This is used as a First-Factor for every authentication using the key.
To change this factor, one can run ykman fido access change-pin
and enter the current pin to change it to a new one.
Firefox
Testing the device on Firefox however had a few problems as the demo at webauthn.io did not work directly (on ESR as well as in Firefox Nightly). This is due to Firefox not having CTAP2 support enabled by default - which is needed to support entering a PIN as userVerification for the account in the demo.
There are two options to solve this:
- disable “Require User Verification” at the advanced settings of the demo (https://github.com/duo-labs/webauthn.io/issues/13)
- enable CTAP2 in about:config in firefox (https://bugzilla.mozilla.org/show_bug.cgi?id=1530370)
Enabling CTAP2 is what I want to have it work with other services too - but for now this is only available in the Firefox Nightly version. After this, it works fine for my YubiKey 5 but might not work that well for the Version 4 (yet - see bugzilla above). It directly worked fine out of the box on Chromium.
- Plug the device in
- set a PIN
- register on webauthn.io
- authenticate
Very nice.
Android
Unfortunatley I could not yet use my Yubikey using Mozilla Fennec Android from F-Droid, as Firefox is using a proprietary library on Android. This issue can be followed here: https://gitlab.com/relan/fennecbuild/-/issues/34
But it works fine using Firefox on Android (from Aurora Store) with latest microG as stated in the above GitLab thread.
K-9 Mail
Signing and encrypting messages using K9-Mail only works if PGP/INLINE is set - but I did not investigate that further..
Luks-Crypt
To use the device with luks to avoid entering the long passphrase on boot I only needed to enter:
sudo systemd-cryptenroll /dev/sda3 --fido2-device=auto --fido2-with-client-pin=yes
sed -i 's/luks,discard$/luks,discard,fido2-device=auto/' /etc/crypttab
update-initramfs -u # returns "ignoring unknown option 'fido2-device'"
# dracut fixes this
sudo apt install dracut
sudo apt install fido2-tools
cat << EOF | sudo tee /etc/dracut.conf.d/11-fido2.conf
## Spaces in the quotes are critical.
# install_optional_items+=" /usr/lib/x86_64-linux-gnu/libfido2.so.* "
## Ugly workround because the line above doesn't fetch
## dependencies of libfido2.so
install_items+=" /usr/bin/fido2-token "
# Required detecting the fido2 key
install_items+=" /usr/lib/udev/rules.d/60-fido-id.rules /usr/lib/udev/fido_id "
EOF
dracut -f
where /dev/sda3
is my encrypted harddisk.
After a reboot - the pc now asks for the key phrase.
I had some problems because I missed step, which made me use the kernel parameter to get into recovery shell adding rd.break=initqueue
to kernel params and running /usr/lib/systemd/systemd-cryptsetup attach root /dev/sda3
then exiting.
Credits/Source: https://www.guyrutenberg.com/2022/02/17/unlock-luks-volume-with-a-yubikey/
SSH
To store a SSH-Key on the device one can run
ssh-keygen -t ed25519-sk -O resident
this stores the key on the yubikey.
To import the key to the device - run: cd ~/.ssh && ssh-keygen -K
.
This stores a copy of the stored keys on the local disk after prompting for the authenticator PIN as the first factor.
To use this key, touching the token is required everytime as a 2FA everytime you use it.
Credits/Source: https://www.guyrutenberg.com/2022/04/02/creating-fido2-ssh-keys-using-ssh-keygen/
SSH using OpenPGP using TermBot on Android
To use this on Android, ConnectBot does not yet support OpenPGP or FIDO Keys. The TermBot fork does by deriving a SSH key from the OpenPGP signature key. It correctly prompts for the input PIN but somehow does not work to authenticate.
So the next thing I try will be to investigate how I can enable the 2FA for a few services and see if those are supported easily. My university is switching to Cisco Duo for 2FA so I am really interested in how that turns out for all our university accounts - but at least I do not need a Third-Party App from Cisco on my mobile phone for 2FA.
Concluding Webauthn support still needs a few years to be supported by all libraries and services one would need. The standard was published in 2016 so the adoption seems to take those years, but is probably a lot better than it was a few years ago.
We will see if this is widely supported in five years everywhere. I also hope that one can use the smartphone as a 2FA using NFC by then and spare those individual authentication apps per service.