27 Jul 2019 - tsp
Multi factor authentication is a method to increase the probability that someone who is authenticated (i.e. who is asserting that he represents or owns a given identity) is really the one who he is claiming to be.
Most of the time users are authenticated via a single factor like a password and identified by some publically knowable method like a username or mail adress (one can also use biometry for identification - but not for authentication!). The main risk with using only a password - which basically is a secret a person knows - is that this password might be stolen and might in the worst case be used on more than one service (note that this is a bad idea anyways). In this case anyone could claim that he is in fact the given entity.
One can use different ways of claiming identity:
One can combine an arbitrary amount of factory. Today most of the time two or three factors are used - hence the names two factor authentication (2FA) or three factor authentication / 3D secure (3FA). One has for example to proof one’s identity by using a username and password as well as an posession token.
One should either use smartcards (see the article about TAN methods for more detail) or hardware tokens (TOTP/HTOP, U2F tokens, Yubikeys in offline mode, etc.) as a posession factor. Another way would be to use keyfiles (like one does for SSH or GPG most of the time).
Yubikeys or U2F tokens in general are hardware bearer tokens. They encapsulate a private and public key pair that’s used as a root source for derived keys. U2F is the general standard that is implemented by many such tokens and webauthn is the name of the API used by webservices. U2F uses a different key for each different service - since they are derived from the root key there can be an infinite amount of services that use the U2F hardware key. Since each service gets to use a different key the user cannot be recognized as being the same by different services - since not knowing who a key belongs to if it’s lost and with which services it’s used these keys also have no markings or serial numbers when being delivered. They cannot be identified by being read out (the root keypair is not readable) and also the derived keys are not extractable from the device. All authentication is done using a challenge response mechanism by which the authenticating service is simply requesting authentication from the device together with a challenge. This challenge is used together with the AppId to calculate a HMACed response that is returned - together with a random nonce - to the service. The service is capable of validating if the correct (per service) private key has been used to sign the app id + nonce pair to check identity of the key. The service has to store only the derived and read public key of the device (that’s also an per-service public key).
Since the keys of the U2F tokens are not readable the tokens cannot be copied. Note that these tokens are not suiteable as password replacements. They are used during multi-factor authentication as an additional factor.
Yubikeys are available in different formfactors and different versions (note: all links are Amazon affilate links - that means this pages author profits from qualified purchases):
This is the simplest way to use the yubikey. You only require a decent browser
that is capable of supporting webauthn (for example www/chromium or www/firefox),
one of the mentioned keys above that support U2F and the
port or package.
The u2f-devd package contains some rules for different hardware U2F tokens that
react on the USB attach event, change the group of the HID device files to
and allow the group read and write access to the hid device. At the time of
writing the package supports Yubikey, Happlink, Neowave Keydo, HyerSecu Hyper FIDO,
Feitian ePass and BioPass, JaCarta U2F, U2F Zero, VASCO SeccureClick, Bluink, Thetis,
Nitrokey, Google Titan, Tomu, Chopstx U2F and SoloKeys. All share the same behaviour
because all implement the same U2F standard. The package also creates the u2f group
if not present before.
After installing the package
pkg install security/u2f-devd
or the port
cd /usr/ports/security/u2f-devd make install clean
one only has to add all users that should be capable of using the U2F security key to the u2f group. This can be done via
sudo pw groupmod USERNAME -m u2f
This has to be done as root or via
sudo or course. If one’s using a different
usermanagement system like an LDAP directory the modifications have to be made there.
After adding the currently logged in user one has to logout and re-login to
have the changes take effect.
As above the
security/u2f-devd package or port is a requirement.
To use your yubikey for local authentication without using the cloud one requires a Yubikey with firmware revision 2.2 or above. The key also has to support challenge response authentication via HMAC-SHA1 mode - this is not supported by the U2F only keys! (I.e. you should use a YubiKey 5 or higher).
The only requirement of supporting PAM authentication is
This package or port can easily be installed
pkg install security/pam_yubico
cd /usr/ports/security/pam_yubico make install clean
afterwards one should configure the yubikey to perform authentication via CRAM
on slot 2. To do that and enable all required mechanisms one can use
ykpersonalize -2 -ochal-resp -ochal-hmac -ohmac-lt64 -oserial-api-visible
The flags perform the following actions:
-2selects the second slot (the first default slot being used for webauthn / U2F)
cahl-respenables the keys challenge response mode.
chal-hmacenables the HMAC-SHA1 method for CRAM
hmac-lt64allows short challenges to be used on the key during CRAM.
serial-api-visibleallows the system to query the device identity. Note that this is required when one doesn’t want to use the YubiCloud, i.e. when one wants to operate in offline mode. This of course allows re-identification of the device on different systems which is required to link the device to a given user account.
If you get the
Yubikey core error: no yubikey present error message
you are either not member of the
u2f group or don’t own a yubikey that
can be used for challenge response authentication.
After that one can store the YubiKeys challenge and expected response in the
users local yubico challenge file. This is done using
ykpamcfg. The idea
is the same as using
authorized_keys for SSH authentication using public keys.
The pam module will read the challenges from
~/.yubico/ and verifies if the
device returns the correct response.
As the user who wants to register it’s own device:
ykpamcfg -2 -v
This automatically stores all necessary information into the users
Then one can add the
pam_yubico module to the PAM configurations one wants to
use with the hardware keys. To require a hardware token via SSH for example
one would edit
/etc/pam.d/sshd. Each PAM configuration file consists of four
To require a user to use the yubikey one should add the method as
different verbs have different properties:
One should add the
pam_yubico module above other
sufficient modules except
they should succeed without a hardware token like kerberos authentication of public key
auth requisite pam_yubico.so mode=challenge-response
This is sufficient to get challenge-response authentication up and running. Note that of
course users have to be members of the
u2f group again on the machine that the
key will be attached to (not necessary on the machine that one logs into - for example
when using via SSH).
If one wants to use the Yubikey as a requisite for SSH when using passwords but allow
kerberos authentication without the key a
/etc/pam.d/sshd file might look like the
auth sufficient pam_krb5.so try_first_pass forwardable debug auth requisite pam_yubico.so mode=challenge-response auth required pam_unix.so no_warn try_first_pass account required pam_nologin.so account optional pam_krb5.so account required pam_group group=wheel account required pam_login_access.so account required pam_unix.so session required pam_permit.so password required pam_unix.so no_warn try_first_pass