Yubico / yubico-pam

Yubico Pluggable Authentication Module (PAM)
https://developers.yubico.com/yubico-pam
BSD 2-Clause "Simplified" License
692 stars 117 forks source link

ssh authentication hangs #190

Open mr-scripting opened 5 years ago

mr-scripting commented 5 years ago

Hello, I'm trying to enable yubico-pam on linux machines using an openldap proxy and AD as the LDAP database. It seems that the authentication simply hangs when I try to authenticate with the yubikey.

debug: pam_yubico.c:252 (authorize_user_token_ldap): called
debug: pam_yubico.c:291 (authorize_user_token_ldap): try bind with: cn=openldap,cn=users,dc=example,dc=com:[xxxxxxxx]
debug: pam_yubico.c:322 (authorize_user_token_ldap): LDAP : look up object base='cn=teste3,cn=Users,DC=example,DC=com' filter='(null)', ask for attribute 'YUBIKEYID'
debug: pam_yubico.c:360 (authorize_user_token_ldap): LDAP : Found 1 values for YUBIKEYID - checking if any of them match ':xxxxxxxxx'
debug: pam_yubico.c:368 (authorize_user_

It doesn't log anything else and the ssh session time just disconnects.

I'm able to login without the entry /etc/pam.d/sshd

auth required pam_yubico.so mode=client id=17 ldap_uri=ldaps://openldap.example.com:636 [ldap_bind_user=cn=openldap,cn=users,dc=example,dc=com] ldap_bind_password=xxxxxx ldap_cacertfile=/etc/ssl/certs/cacert.pem [ldapdn=cn=Users,DC=example,DC=com] user_attr=cn yubi_attr=YUBIKEYID debug debug_file=/var/run/pam-debug.log

I'm using nslcd as the ldap client authentication.

The Domain Controller logs the ldap query as well:

Internal event: A client issued a search operation with the following options. 

Client:
172.16.1.11:50626 
Starting node:
cn=teste3,cn=Users,dc=example,dc=com 
Filter:
 (objectClass=*)  
Search scope:
base 
Attribute selection:
yubiKeyId 
Server controls:

Visited entries:
1 
Returned entries:
1 
Used indexes:

Pages referenced:
2 
Pages read from disk:
0 
Pages preread from disk:
0 
Clean pages modified:
0 
Dirty pages modified:
0 
Search time (ms):
0 
Attributes Preventing Optimization:
none 
User:
cn=openldap,cn=users,dc=example,dc=com

I have used the LDAP schema from the GITHUB project bellow: https://github.com/mludvig/yubikey-ldap

Is this a newbie configuration issue or something else?

mr-scripting commented 5 years ago

So I tried without the Ldap proxy in the middle and it still fails. Is there any way to get more detailed output from the debug file? How can I see what if the module is processing or not the token received from the LDAP server? Thanks.

mr-scripting commented 5 years ago

I have used strace and was able to see that yubico_pam was trying to connect to https://api4.yubico.com/wsapi/2.0/verify?id=17&nonce=hcahqomivxyuwhiusfcrjrothtabguko&otp=xxxxxxxxxxxxxxxxx&timestamp=1

After adding a proxy it was able to connect and now it returns:

debug: pam_yubico.c:360 (authorize_user_token_ldap): LDAP : Found 1 values for YUBIKEYID - checking if any of them match ':ccccccjgclnu'
debug: pam_yubico.c:368 (authorize_user_token_ldap): LDAP : Checking value 1: :xxxxxxxx
debug: pam_yubico.c:380 (authorize_user_token_ldap): Token Found :: xxxxxxxxxx
debug: pam_yubico.c:1154 (pam_sm_authenticate): Token is associated to the user. Validating the OTP...
debug: pam_yubico.c:1156 (pam_sm_authenticate): ykclient return value (0): Success
debug: pam_yubico.c:1157 (pam_sm_authenticate): ykclient url used: https://api4.yubico.com/wsapi/2.0/verify?id=17&nonce=hcahqomivxyuwhiusfcrjrothtabguko&otp=xxxxxxxxxxxxxxxx&timestamp=1
debug: pam_yubico.c:1220 (pam_sm_authenticate): done. [Success]

Now I'm able to press the yubikey on the first password prompt, it validates the otp and then it prompts for the LDAP password and I'm able to login. However after pressing the yubikey it outputs access denied in the console. Is there a way of not showing the access denied?

Also, is it really necessary to allow the communication to the API server on the internet?

Thanks in advance.

klali commented 5 years ago

Hey,

Glad you solved the immediate problem, sorry I didn't manage to give you any pointers in time.

For OTP validation if you want to use the YubiCloud, hosted by Yubico you need to allow it to access those machines (api.yubico.com, api2.yubico.com, api3.yubico.com, api4.yubico.com and api5.yubico.com). If you want to you can setup your own validation service (using the project yubikey-val and python-pyhsm) and use the urllist parameter to point at addresses of your choosing.

"access denied" is never output by the module itself so it must come from somewhere else, what does the rest of your pam stack look like?

mr-scripting commented 5 years ago

Hello Klali, thanks for replying.

Here's my common-auth:

auth required pam_yubico.so \
     mode=client id=17 ldap_uri=ldaps://openldap.example.com:636 \
     ldap_cacertfile=/etc/ssl/certs/cacert.pem ldap_bind_user=cn=openldap,cn=users,dc=example,dc=com \
     [ldap_bind_password=xxxxxxxxxxx]  [ldapdn=cn=users,DC=example,DC=com] user_attr=cn \
     yubi_attr=YUBIKEYID proxy=http://xxxxxxxxxx:xxxxx \
     debug debug_file=/var/log/pam_yubico
auth [success=2 default=ignore] pam_ldap.so minimum_uid=1000
auth [success=1 default=ignore] pam_unix.so try_first_pass
# here's the fallback if no module succeeds
auth    requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth    required                        pam_permit.so

If I remove the yubico-pam module everything works.

mr-scripting commented 5 years ago

I guess my problem was not reading the documentation correctly on this last issue.

To log in, you now need to enter both your Unix password and enter an OTP using your YubiKey. When prompted for the password, enter the Unix password first and then (without pressing enter) push the button on your YubiKey.

My final common-auth configuration:

auth [success=3 default=ignore] pam_unix.so
auth requisite pam_yubico.so \
     mode=client id=17 ldap_uri=ldaps://openldap.example.com:636 \
     ldap_cacertfile=/etc/ssl/certs/cacert.pem ldap_bind_user=cn=openldap,cn=users,dc=example,dc=com \
     [ldap_bind_password=xxxxxxx]  [ldapdn=cn=users,DC=example,DC=com] user_attr=cn \
     yubi_attr=YUBIKEYID proxy=http://xxxxxx:xxxxx \
     debug debug_file=/var/log/pam_yubico
auth [success=2 default=ignore] pam_ldap.so minimum_uid=1000
# here's the fallback if no module succeeds
auth    requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth    required                        pam_permit.so

I plan to use ssh keys for the linux local users and yubikey for the ldap users.

Is there a way of using the yubikey for the local users as well and maintaining the ldap yubico pam entry? Maybe adding a new entry with a local validation file?

Thanks.