Open zypA13510 opened 5 years ago
Here is what I did on Centos 8
dnf install epel-release
dnf install pam_yubico
Disable auth substack password-auth
in /etc/pam.d/sshd
#auth substack password-auth
Enable ChallengeResponseAuthentication
ChallengeResponseAuthentication yes
Add AuthenticationMethods
AuthenticationMethods publickey,keyboard-interactive
First of all: Thanks @zypA13510 for your short tutorial. This helped me setting up MFA with SSH keypairs on my Ubuntu 20.04.4 LTS VM. To make MFA optional, I added nullok
to the line in file /etc/pam.d/sshd
:
auth required pam_yubico.so id=[ID] key=[KEY] nullok debug debug_file=/var/run/pam-debug.log
auth required pam_permit.so
If a user has the file ~/.yubico/authorized_yubikeys
in place, he will be asked for the Yubikey OTP after logging in via SSH key. If the file is not in place, a SSH login using only the SSH key is sufficient.
Unfortunately, this mechanism does not work anymore on Ubuntu 22.04.1 LTS. After providing the SSH key for an account without ~/.yubico/authorized_yubikeys
in place, the server responds with No supported authentication methods available (server sent: keyboard-interactive)
. The debug log looks the following:
debug: ../pam_yubico.c:838 (parse_cfg): called. debug: ../pam_yubico.c:839 (parse_cfg): flags 1 argc 5 debug: ../pam_yubico.c:841 (parse_cfg): argv[0]=id=[ID] debug: ../pam_yubico.c:841 (parse_cfg): argv[1]=key=[KEY] debug: ../pam_yubico.c:841 (parse_cfg): argv[2]=nullok debug: ../pam_yubico.c:841 (parse_cfg): argv[3]=debug debug: ../pam_yubico.c:841 (parse_cfg): argv[4]=debug_file=/var/run/pam-debug.log debug: ../pam_yubico.c:842 (parse_cfg): id=[ID] debug: ../pam_yubico.c:843 (parse_cfg): key=[KEY] debug: ../pam_yubico.c:844 (parse_cfg): debug=1 debug: ../pam_yubico.c:845 (parse_cfg): debug_file=5 debug: ../pam_yubico.c:846 (parse_cfg): alwaysok=0 debug: ../pam_yubico.c:847 (parse_cfg): verbose_otp=0 debug: ../pam_yubico.c:848 (parse_cfg): try_first_pass=0 debug: ../pam_yubico.c:849 (parse_cfg): use_first_pass=0 debug: ../pam_yubico.c:850 (parse_cfg): nullok=1 debug: ../pam_yubico.c:851 (parse_cfg): authfile=(null) debug: ../pam_yubico.c:852 (parse_cfg): ldapserver=(null) debug: ../pam_yubico.c:853 (parse_cfg): ldap_uri=(null) debug: ../pam_yubico.c:854 (parse_cfg): ldap_bind_user=(null) debug: ../pam_yubico.c:855 (parse_cfg): ldap_bind_password=(null) debug: ../pam_yubico.c:856 (parse_cfg): ldap_filter=(null) debug: ../pam_yubico.c:857 (parse_cfg): ldap_cacertfile=(null) debug: ../pam_yubico.c:858 (parse_cfg): ldapdn=(null) debug: ../pam_yubico.c:859 (parse_cfg): user_attr=(null) debug: ../pam_yubico.c:860 (parse_cfg): yubi_attr=(null) debug: ../pam_yubico.c:861 (parse_cfg): yubi_attr_prefix=(null) debug: ../pam_yubico.c:862 (parse_cfg): url=(null) debug: ../pam_yubico.c:863 (parse_cfg): urllist=(null) debug: ../pam_yubico.c:864 (parse_cfg): capath=(null) debug: ../pam_yubico.c:865 (parse_cfg): cainfo=(null) debug: ../pam_yubico.c:866 (parse_cfg): proxy=(null) debug: ../pam_yubico.c:867 (parse_cfg): token_id_length=12 debug: ../pam_yubico.c:868 (parse_cfg): mode=client debug: ../pam_yubico.c:869 (parse_cfg): chalresp_path=(null) debug: ../pam_yubico.c:899 (pam_sm_authenticate): pam_yubico version: 2.26 debug: ../pam_yubico.c:914 (pam_sm_authenticate): get user returned: root debug: ../pam_yubico.c:187 (authorize_user_token): Dropping privileges debug: ../util.c:115 (check_user_token): Cannot open file: /root/.yubico/authorized_yubikeys (No such file or directory) debug: ../pam_yubico.c:1029 (pam_sm_authenticate): Internal error while looking for user tokens debug: ../pam_yubico.c:1220 (pam_sm_authenticate): done. [Authentication service cannot retrieve authentication info]
Just for comparison, the log file from my Ubuntu 20.04.4 LTS using the same scenario:
debug: pam_yubico.c:933 (parse_cfg): called. debug: pam_yubico.c:934 (parse_cfg): flags 1 argc 5 debug: pam_yubico.c:936 (parse_cfg): argv[0]=id=[ID] debug: pam_yubico.c:936 (parse_cfg): argv[1]=key=[KEY] debug: pam_yubico.c:936 (parse_cfg): argv[2]=nullok debug: pam_yubico.c:936 (parse_cfg): argv[3]=debug debug: pam_yubico.c:936 (parse_cfg): argv[4]=debug_file=/var/run/pam-debug.log debug: pam_yubico.c:937 (parse_cfg): id=[ID] debug: pam_yubico.c:938 (parse_cfg): key=[KEY] debug: pam_yubico.c:939 (parse_cfg): debug=1 debug: pam_yubico.c:940 (parse_cfg): debug_file=5 debug: pam_yubico.c:941 (parse_cfg): alwaysok=0 debug: pam_yubico.c:942 (parse_cfg): verbose_otp=0 debug: pam_yubico.c:943 (parse_cfg): try_first_pass=0 debug: pam_yubico.c:944 (parse_cfg): use_first_pass=0 debug: pam_yubico.c:945 (parse_cfg): always_prompt=0 debug: pam_yubico.c:946 (parse_cfg): nullok=1 debug: pam_yubico.c:947 (parse_cfg): ldap_starttls=0 debug: pam_yubico.c:948 (parse_cfg): ldap_bind_as_user=0 debug: pam_yubico.c:949 (parse_cfg): authfile=(null) debug: pam_yubico.c:950 (parse_cfg): ldapserver=(null) debug: pam_yubico.c:951 (parse_cfg): ldap_uri=(null) debug: pam_yubico.c:952 (parse_cfg): ldap_bind_user=(null) debug: pam_yubico.c:953 (parse_cfg): ldap_bind_password=(null) debug: pam_yubico.c:954 (parse_cfg): ldap_filter=(null) debug: pam_yubico.c:955 (parse_cfg): ldap_cacertfile=(null) debug: pam_yubico.c:956 (parse_cfg): ldapdn=(null) debug: pam_yubico.c:957 (parse_cfg): ldap_clientcertfile=(null) debug: pam_yubico.c:958 (parse_cfg): ldap_clientkeyfile=(null) debug: pam_yubico.c:959 (parse_cfg): user_attr=(null) debug: pam_yubico.c:960 (parse_cfg): yubi_attr=(null) debug: pam_yubico.c:961 (parse_cfg): yubi_attr_prefix=(null) debug: pam_yubico.c:962 (parse_cfg): url=(null) debug: pam_yubico.c:963 (parse_cfg): urllist=(null) debug: pam_yubico.c:964 (parse_cfg): capath=(null) debug: pam_yubico.c:965 (parse_cfg): cainfo=(null) debug: pam_yubico.c:966 (parse_cfg): proxy=(null) debug: pam_yubico.c:967 (parse_cfg): token_id_length=12 debug: pam_yubico.c:968 (parse_cfg): mode=client debug: pam_yubico.c:969 (parse_cfg): chalresp_path=(null) debug: pam_yubico.c:970 (parse_cfg): mysql_server=(null) debug: pam_yubico.c:971 (parse_cfg): mysql_port=0 debug: pam_yubico.c:972 (parse_cfg): mysql_user=(null) debug: pam_yubico.c:973 (parse_cfg): mysql_database=(null) debug: pam_yubico.c:1009 (pam_sm_authenticate): pam_yubico version: 2.27 debug: pam_yubico.c:1024 (pam_sm_authenticate): get user returned: root debug: pam_yubico.c:221 (authorize_user_token): Dropping privileges debug: pam_yubico.c:1149 (pam_sm_authenticate): No tokens found for user debug: pam_yubico.c:1337 (pam_sm_authenticate): done. [The return value should be ignored by PAM dispatch]
It seems to me, that the nullok
option is handled differently. Does anyone experience the same issues?
Note: Whats bothering me the most is that the older Ubuntu 20.04.4 LTS release gets the 2.27 version of pam_yubico
, whereas the newer Ubuntu 22.04.1 LTS release gets the version 2.26 from the PPA repository.
EDIT: My simple (but hopefully temporary) workaround is to setup empty ~/.yubico/authorized_yubikeys
files for every user, who should not authenticate with a Yubikey OTP.
It seems to me, that the
nullok
option is handled differently. Does anyone experience the same issues?Note: Whats bothering me the most is that the older Ubuntu 20.04.4 LTS release gets the 2.27 version of
pam_yubico
, whereas the newer Ubuntu 22.04.1 LTS release gets the version 2.26 from the PPA repository.
Well, it seems that I stumbled upon an old issue with version 2.26.; see https://github.com/Yubico/yubico-pam/issues/194 and https://github.com/Yubico/yubico-pam/commit/f300115a64d413cefe4bf5d3f905269e8c605bdb. I think the real issue is, that the PPA does not provide the current version 2.27 for Ubuntu 22.04...
After struggling for quite some time despite following the doc and various sources on the Internet, I have finally discovered the way to configure pam_yubico as the 2nd factor along with SSH keys for authentication.
The culprit is that sshd skips PAM auth altogether when publickey authentication is used and accepted. The solution comes from this post, in
/etc/ssh/sshd_config
, you need to enableChallengeResponseAuthentication
and also explicitly specifyAuthenticationMethods publickey,keyboard-interactive
. The final result looks like this:Also,
common-auth
stack (aka.password-auth
/system-auth
) needs to be commented out in/etc/pam.d/sshd
unless publickey+yubikey+password is desired.I believe this information may be helpful for future users and it could be integrated into YubiKey and SSH via PAM.