Pam_u2f module don't work after the first log-in using Yubikey

Hi ! I’m trying to use my Yubikey for session login and unlock session using pam_u2f.so module (in “required” mode). I will show you my conf files at the end of the message, juste let me explain my probleme first !
My probleme is : the first login (just after boot) works perfectly. However, every time I return to the login page (for any reason, like “lock-session”, “computer sleeping”, etc.), I can’t log in. D:
Here’s what I have tried to debug :

  • Remove the pam_u2f.so, to be sure the probleme come from it => i can log-in again :), pam_u2f.so is the reason why i can’t log-in
  • I found that link cve-details , then i tried the suggested mitigation => didn’t change anything
  • i put SELinux in “permissive” mode (but the best would be to find a solution without disabling SELinux) => didn’t change anything, SELinux isn’t the problem
  • i used the “nouserok” pam_u2f.so option, (nouserok = if your user don’t have a file with keys OR if there is no key for your user in the file THEN pam_u2f.so return OK :+1: ) in order to see if the module read the file. The result is, i can’t log-in => that means pam_u2f.so can read the file with the key BUT for some reason, the verification with the Yubikey don’t work (even if it work for the very first log-in)
  • The single log i can have is (from cat /var/log/secure), this log happen when i can’t log-in in the “login window”, not the “unlock window” (i have no logs when i try to log-in using unlock window :/, maybe there is more logs somewhere) :
Mar 11 15:21:56 fedora sddm-helper[6110]: pam_kwallet5(sddm:auth): pam_kwallet5: pam_sm_authenticate

I’m out of idea and solutions, if someone can help with that problem, i would be very very happy :smiley: !

here is my pam conf :
Added /etc/pam.d/u2f-required

#%PAM-1.0
auth       required     pam_u2f.so

Included the u2f-required file in /etc/pam.d/kde (for unlocking window session) and /etc/pam.d/sddm (for the log-in window)
In both cases, i added the u2f-required line, just after the postlogin line

....
auth        include       postlogin
auth        include       u2f-required
...

And the key file is in standard location : /home/<USER>/.config/Yubico/u2f_keys
with the following rights (can’t be modified by the user, but he can read it) :

-rw-r--r--.  1 root           root            208 10 mars  17:16 u2f_keys

If you have any questions, feel free to ask !

I have no idea what the problem might be, but I’d suggest using pamtester to test your authentication stacks and configuring debug options for pam_u2f. (See man pam_u2f for details about the options.)


Edit: Having root-owned files in a normal user’s home directory doesn’t sound right. It is possible that the pam_u2f library is checking for correct ownership (and permissions). I’d suggest running sudo chown -R $USER: ~/.config/Yubico and chmod 600 ~/.config/Yubico/u2f_keys.

Hi! Thank for answering, i will try pamtester tonight or tomorrow and I’ll come back to share what I find :slight_smile:

Regarding the u2f_keys file, I tried using an “authfile” in /etc/u2f_mapping (I did this with my ArchLinux setup and it worked perfectly), but it didn’t work on Fedora. That is why i tried another approach (just in case). Anyway, when I do my debugging, I’m testing both solutions.

So for me there is no problem about the file location. It seems like the most important is a file that can be read by pam_u2f.so module

hi again,
Juste an update, i haven’t solved the problem yet, but i have news (it is SURPRISING) :

  • the bug occurs only when i’m at home, not in work (the ONLY different, for me, is the wifi connection)
  • when i’m at home, if i turn ON the “airplane mode”, it work. When i turn it OFF, it stops work.

(Unfortunatly, i had forgotten to save pam logs, i will post them when i comeback home)

Knowing this, i looked at the NetworkManager .nmconnection files and the only differences i found are in “[Wifi-secure]” block :

Some contexte before => The desktop env is KDE Plasma (using KWallett with NetworkManager)

# cat home.nmconnection => my home, where the bug occur
...
[wifi-security]
auth-alg=open
key-mgmt=wpa-psk
leap-password-flags=1
psk-flags=1
wep-key-flags=1
...
# cat work.nmconnection => wifi conf at work
...
[wifi-security]
key-mgmt=sea
psk-flags=1
...
# cat somewhere.nmconnection => Something i tried
...
[wifi-security]
auth-alg=open
key-mgmt=wpa-psk
psk=xxxxxxxxxxxxx # password
...

When i get back home, i’m going to modify my home.nmconnection in order to see if it fix the bug.

That said, i can’t believe the Wifi connection could affect the pam_u2f.so auth module. If anyone knows how this could be possible—or if I’m completely off track—I’m really curious to understand what’s happening. :thinking:

Yes, some security keys can be configured to use online resources as part of the authentication process.

Excerpted from How to use a YubiKey with Fedora Linux (emphasis added):

Add the YubiKey to local system authentication through PAM (Pluggable Authentication Modules). You can either do this using the default online or an alternative offline method. The online method uses the Yubico servers to validate the OTP tokens and thus requires an online connection while the offline method uses challenge-response.


I would suggest crafting a custom PAM service file under /etc/pam.d with “debug” added to the pam_u2f module and testing it with pamtester. You can leave sudo journalctl -f running in a second terminal as you test the PAM service and it should provide some feedback about what is or isn’t happening. Good luck. :slightly_smiling_face:

Yes, some security can use online resources, BUT with my Yubikey its 100% offline, it work in airplane mode (that why i used pam_u2f instead pam_yubico).
That why i don’t understand what is happening :thinking: (maybe something with KWallet idk, bc according to the home.nmconnection, nm ask KWallet for password)

I will comeback with some logs when i can :+1:
About the previous messages. Just to be sure, when i’m testing a login authentification. Is the following command correct ?
# pamtester login USER authenticate ? :thinking:

That looks right (substituting USER with your actual username of course).

Edit: That would test the auth stack in /etc/pam.d/login (the “login” service is the one that runs when you sign in on a TTY). For testing purposes, you can create a copy of some service file under /etc/pam.d and use that filename as the first parameter to pamtester.

1 Like

I have logs, using pamtester :

  • With airplane mode => OFF :

Check if Yubikey connected =>

root@fedora:/etc/pam.d# ykman fido info
PIN:                8 attempt(s) remaining
Minimum PIN length: 4

Test pam_u2f.so module => pamtester u2f-required xinjan authenticate (u2f-required file contain 1 line => “auth required pam_u2f.so debug nouserok” (nouserok to not be locked out of my system when debugging :slight_smile: :slight_smile: )

debug(pam_u2f): pam-u2f.c:95 (parse_cfg): called.
debug(pam_u2f): pam-u2f.c:96 (parse_cfg): flags 0 argc 2
debug(pam_u2f): pam-u2f.c:98 (parse_cfg): argv[0]=debug
debug(pam_u2f): pam-u2f.c:98 (parse_cfg): argv[1]=nouserok
debug(pam_u2f): pam-u2f.c:100 (parse_cfg): max_devices=0
debug(pam_u2f): pam-u2f.c:101 (parse_cfg): debug=1
debug(pam_u2f): pam-u2f.c:102 (parse_cfg): interactive=0
debug(pam_u2f): pam-u2f.c:103 (parse_cfg): cue=0
debug(pam_u2f): pam-u2f.c:104 (parse_cfg): nodetect=0
debug(pam_u2f): pam-u2f.c:105 (parse_cfg): userpresence=-1
debug(pam_u2f): pam-u2f.c:106 (parse_cfg): userverification=-1
debug(pam_u2f): pam-u2f.c:107 (parse_cfg): pinverification=-1
debug(pam_u2f): pam-u2f.c:108 (parse_cfg): manual=0
debug(pam_u2f): pam-u2f.c:109 (parse_cfg): nouserok=1
debug(pam_u2f): pam-u2f.c:110 (parse_cfg): openasuser=0
debug(pam_u2f): pam-u2f.c:111 (parse_cfg): alwaysok=0
debug(pam_u2f): pam-u2f.c:112 (parse_cfg): sshformat=0
debug(pam_u2f): pam-u2f.c:113 (parse_cfg): expand=0
debug(pam_u2f): pam-u2f.c:114 (parse_cfg): authfile=(null)
debug(pam_u2f): pam-u2f.c:115 (parse_cfg): authpending_file=(null)
debug(pam_u2f): pam-u2f.c:117 (parse_cfg): origin=(null)
debug(pam_u2f): pam-u2f.c:118 (parse_cfg): appid=(null)
debug(pam_u2f): pam-u2f.c:119 (parse_cfg): prompt=(null)
debug(pam_u2f): pam-u2f.c:204 (pam_sm_authenticate): Origin not specified, using "pam://Host-001"
debug(pam_u2f): pam-u2f.c:216 (pam_sm_authenticate): Appid not specified, using the value of origin (pam://Host-001)
debug(pam_u2f): pam-u2f.c:229 (pam_sm_authenticate): Maximum number of devices not set. Using default (24)
debug(pam_u2f): pam-u2f.c:252 (pam_sm_authenticate): Requesting authentication for user xinjan
debug(pam_u2f): pam-u2f.c:263 (pam_sm_authenticate): Found user xinjan
debug(pam_u2f): pam-u2f.c:264 (pam_sm_authenticate): Home directory for xinjan is /home/xinjan
debug(pam_u2f): pam-u2f.c:141 (resolve_authfile_path): Variable XDG_CONFIG_HOME is not set, using default
debug(pam_u2f): pam-u2f.c:290 (pam_sm_authenticate): Using authentication file /home/xinjan/.config/Yubico/u2f_keys
debug(pam_u2f): pam-u2f.c:296 (pam_sm_authenticate): Dropping privileges
debug(pam_u2f): pam-u2f.c:302 (pam_sm_authenticate): Switched to uid 1001
debug(pam_u2f): util.c:228 (parse_native_format): Read 208 bytes
debug(pam_u2f): util.c:232 (parse_native_format): Matched user: xinjan
debug(pam_u2f): util.c:255 (parse_native_format): KeyHandle for device number 1: II2JxWGlEKxmVuFwss30hngO==
debug(pam_u2f): util.c:257 (parse_native_format): publicKey for device number 1: nsIMZdoybME42/aAfPw4GYRHGupHgzAU3h7bg==
debug(pam_u2f): util.c:259 (parse_native_format): COSE type for device number 1: es256
debug(pam_u2f): util.c:261 (parse_native_format): Attributes for device number 1: +presence
debug(pam_u2f): util.c:771 (get_devices_from_authfile): Found 1 device(s) for user xinjan
debug(pam_u2f): pam-u2f.c:312 (pam_sm_authenticate): Restored privileges
debug(pam_u2f): pam-u2f.c:343 (pam_sm_authenticate): Touch request notifications will be emitted via '/var/run/user/0/pam-u2f-authpending'
debug(pam_u2f): pam-u2f.c:352 (pam_sm_authenticate): Unable to emit 'authentication started' notification: No such file or directory
run_manifest: found 1 hid device
run_manifest: found 0 nfc devices
debug(pam_u2f): util.c:1191 (do_authentication): Device max index is 1
debug(pam_u2f): util.c:1205 (do_authentication): Attempting authentication with device number 1
debug(pam_u2f): util.c:1010 (prepare_assert): Key handle: II2JxWGDlEKxmVuFwss30hngOw2JnSonw==
debug(pam_u2f): util.c:816 (get_authenticators): Working with 1 authenticator(s)
debug(pam_u2f): util.c:819 (get_authenticators): Checking whether key exists in authenticator 0
debug(pam_u2f): util.c:827 (get_authenticators): Authenticator path: /dev/hidraw1
**Some HEX data storm**

debug(pam_u2f): util.c:854 (get_authenticators): Key not found in authenticator 0
debug(pam_u2f): util.c:864 (get_authenticators): Key not found
debug(pam_u2f): util.c:1280 (do_authentication): Device for this keyhandle is not present
run_manifest: found 1 hid device
run_manifest: found 0 nfc devices
debug(pam_u2f): pam-u2f.c:401 (pam_sm_authenticate): done. [Authentication failure]
pamtester: Authentication failure

Looks like he can’t find a device

=> “airplane mode” ON

debug(pam_u2f): pam-u2f.c:95 (parse_cfg): called.
debug(pam_u2f): pam-u2f.c:96 (parse_cfg): flags 0 argc 2
debug(pam_u2f): pam-u2f.c:98 (parse_cfg): argv[0]=debug
debug(pam_u2f): pam-u2f.c:98 (parse_cfg): argv[1]=nouserok
debug(pam_u2f): pam-u2f.c:100 (parse_cfg): max_devices=0
debug(pam_u2f): pam-u2f.c:101 (parse_cfg): debug=1
debug(pam_u2f): pam-u2f.c:102 (parse_cfg): interactive=0
debug(pam_u2f): pam-u2f.c:103 (parse_cfg): cue=0
debug(pam_u2f): pam-u2f.c:104 (parse_cfg): nodetect=0
debug(pam_u2f): pam-u2f.c:105 (parse_cfg): userpresence=-1
debug(pam_u2f): pam-u2f.c:106 (parse_cfg): userverification=-1
debug(pam_u2f): pam-u2f.c:107 (parse_cfg): pinverification=-1
debug(pam_u2f): pam-u2f.c:108 (parse_cfg): manual=0
debug(pam_u2f): pam-u2f.c:109 (parse_cfg): nouserok=1
debug(pam_u2f): pam-u2f.c:110 (parse_cfg): openasuser=0
debug(pam_u2f): pam-u2f.c:111 (parse_cfg): alwaysok=0
debug(pam_u2f): pam-u2f.c:112 (parse_cfg): sshformat=0
debug(pam_u2f): pam-u2f.c:113 (parse_cfg): expand=0
debug(pam_u2f): pam-u2f.c:114 (parse_cfg): authfile=(null)
debug(pam_u2f): pam-u2f.c:115 (parse_cfg): authpending_file=(null)
debug(pam_u2f): pam-u2f.c:117 (parse_cfg): origin=(null)
debug(pam_u2f): pam-u2f.c:118 (parse_cfg): appid=(null)
debug(pam_u2f): pam-u2f.c:119 (parse_cfg): prompt=(null)
debug(pam_u2f): pam-u2f.c:204 (pam_sm_authenticate): Origin not specified, using “pam://fedora”
debug(pam_u2f): pam-u2f.c:216 (pam_sm_authenticate): Appid not specified, using the value of origin (pam://fedora)
debug(pam_u2f): pam-u2f.c:229 (pam_sm_authenticate): Maximum number of devices not set. Using default (24)
debug(pam_u2f): pam-u2f.c:252 (pam_sm_authenticate): Requesting authentication for user xinjan
debug(pam_u2f): pam-u2f.c:263 (pam_sm_authenticate): Found user xinjan
debug(pam_u2f): pam-u2f.c:264 (pam_sm_authenticate): Home directory for xinjan is /home/xinjan
debug(pam_u2f): pam-u2f.c:141 (resolve_authfile_path): Variable XDG_CONFIG_HOME is not set, using default
debug(pam_u2f): pam-u2f.c:290 (pam_sm_authenticate): Using authentication file /home/xinjan/.config/Yubico/u2f_keys
debug(pam_u2f): pam-u2f.c:296 (pam_sm_authenticate): Dropping privileges
debug(pam_u2f): pam-u2f.c:302 (pam_sm_authenticate): Switched to uid 1001
debug(pam_u2f): util.c:228 (parse_native_format): Read 208 bytes
debug(pam_u2f): util.c:232 (parse_native_format): Matched user: xinjan
debug(pam_u2f): util.c:255 (parse_native_format): KeyHandle for device number 1: II2JxWG9jqDJkSMsgpJvJFqEoxoX7i8==
debug(pam_u2f): util.c:257 (parse_native_format): publicKey for device number 1: nsIMZdoybME42/aAfPw4GYRH7VP5xBwlwDf6lA==
debug(pam_u2f): util.c:259 (parse_native_format): COSE type for device number 1: es256
debug(pam_u2f): util.c:261 (parse_native_format): Attributes for device number 1: +presence
debug(pam_u2f): util.c:771 (get_devices_from_authfile): Found 1 device(s) for user xinjan
debug(pam_u2f): pam-u2f.c:312 (pam_sm_authenticate): Restored privileges
debug(pam_u2f): pam-u2f.c:343 (pam_sm_authenticate): Touch request notifications will be emitted via ‘/var/run/user/0/pam-u2f-authpending’
debug(pam_u2f): pam-u2f.c:352 (pam_sm_authenticate): Unable to emit ‘authentication started’ notification: No such file or directory
run_manifest: found 1 hid device
run_manifest: found 0 nfc devices
debug(pam_u2f): util.c:1191 (do_authentication): Device max index is 1
debug(pam_u2f): util.c:1205 (do_authentication): Attempting authentication with device number 1
debug(pam_u2f): util.c:1010 (prepare_assert): Key handle: II2JxWG9jqDJkSMsgpYBBqDlEK==
debug(pam_u2f): util.c:816 (get_authenticators): Working with 1 authenticator(s)
debug(pam_u2f): util.c:819 (get_authenticators): Checking whether key exists in authenticator 0
debug(pam_u2f): util.c:827 (get_authenticators): Authenticator path: /dev/hidraw1
fido_tx: dev=0x564a1cf47ef0, cmd=0x06
fido_tx: buf=0x564a1cf47ef0, len=8
0000: 52 bf d7 86 4b 7b ab 1d
fido_rx: dev=0x564a1cf47ef0, cmd=0x06, ms=-1

** Some HEX data storm **

adjust_assert_count: cbor_type
adjust_assert_count: cbor_type
adjust_assert_count: cbor_type
cbor_decode_assert_authdata: buf=0x564a1cf5c110, len=37
debug(pam_u2f): util.c:851 (get_authenticators): Found key in authenticator 0
fido_dev_get_cbor_info_tx: dev=0x564a1cf47ef0
fido_tx: dev=0x564a1cf47ef0, cmd=0x10

** Some HEX data storm **

adjust_assert_count: cbor_type
adjust_assert_count: cbor_type
adjust_assert_count: cbor_type
cbor_decode_assert_authdata: buf=0x564a1cf5c1e0, len=37
fido_check_flags: flags=01
fido_check_flags: up=2, uv=0
fido_get_signed_hash: cose_alg=-7
debug(pam_u2f): pam-u2f.c:401 (pam_sm_authenticate): done. [Success]
pamtester: successfully authenticated

Now he find the device, i don’t understand what is happening :exploding_head:

I see you filed Issue #364 upstream. That is probably your best bet. Good luck. :slightly_smiling_face:

Yes ! it was solved very fast :sweat_smile: And thank you for trying to solve this issue with me :slight_smile:

TLDR : change NetworkManager variable value of “hostname-mode” from “dhcp” to “none” in order to not let DHCP server changing your hostname

The issue is the variable “hostname-mode” by default = “dhcp” in Fedora, that allow DHCP server to changes hostname, but the Yubikey use the current hostname when you create the keys.

It worked perfectly with Arch because the default value of “hostname-mode” is “none”.

More information about the issue and its resolution : pam_u2f fail to find Yubikey device when i'm connected to my wifi home · Issue #364 · Yubico/pam-u2f · GitHub

1 Like