2

In order to allow the 2FA in my domain, I setup a LinOTP server to manage the map between tokens and users (from LDAP) in my realm.

So, I configured the PAM stack to integrate this authentication method also for SSH sessions:

# /etc/pam.d/sshd
# =========================================================

#%PAM-1.0

auth       required     pam_sepermit.so

# OTP Check
auth    [success=1 default=ignore]  pam_python.so\
    /lib/security/pam_linotp.py nosslhostnameverify nosslcertverify\
    url=https://mylinotpsrv.local/validate/simplecheck realm=MYDOMAIN debug
auth    requisite       pam_deny.so

auth       substack     password-auth
auth       include      postlogin

# Used with polkit to reauthorize users in remote sessions
-auth      optional     pam_reauthorize.so prepare
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth

# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so

# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      password-auth
session    include      postlogin

# Used with polkit to reauthorize users in remote sessions
-session   optional     pam_reauthorize.so prepare

Then, I tried to open a connection: ssh vdn@MYDOMAIN.LOC@192.168.0.12, and:

  • the OTP (provided, in my case, by Google Authenticator) is correctly validated;
  • the username/pwd correspondence is correctly checked.

But, when the double-check above is done, I obtain an error: Write Error: Broken Pipe.

The logs are as follows:

/var/log/secure
====================================================================================================

Mar  9 15:25:09 mflinux01 sshd[8215]: Set /proc/self/oom_score_adj to 0
Mar  9 15:25:09 mflinux01 sshd[8215]: Connection from 192.168.0.13 port 33926 on 192.168.0.12 port 22
Mar  9 15:25:09 mflinux01 sshd[8215]: Postponed keyboard-interactive for vdn@MYDOMAIN.LOC from 192.168.0.13 port 33926 ssh2 [preauth]
Mar  9 15:25:17 mflinux01 sshd[8215]: Postponed keyboard-interactive/pam for vdn@MYDOMAIN.LOC from 192.168.0.13 port 33926 ssh2 [preauth]
Mar  9 15:25:20 mflinux01 sshd[8217]: pam_sss(sshd:auth): authentication success; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.0.13 user=vdn@MYDOMAIN.LOC
Mar  9 15:25:20 mflinux01 sshd[8220]: pam_krb5[8220]: got error -1 (Unknown code ____ 255) while obtaining tokens for cern.ch
Mar  9 15:25:20 mflinux01 sshd[8215]: Postponed keyboard-interactive/pam for vdn@MYDOMAIN.LOC from 192.168.0.13 port 33926 ssh2 [preauth]
Mar  9 15:25:20 mflinux01 sshd[8215]: Accepted keyboard-interactive/pam for vdn@MYDOMAIN.LOC from 192.168.0.13 port 33926 ssh2
Mar  9 15:25:20 mflinux01 sshd[8215]: fatal: PAM: pam_setcred(): Failure setting user credentials

/var/log/message
====================================================================================================
Mar  9 15:25:01 mflinux01 systemd: Created slice user-988.slice.
Mar  9 15:25:01 mflinux01 systemd: Starting user-988.slice.
Mar  9 15:25:01 mflinux01 systemd: Started Session 12 of user pcp.
Mar  9 15:25:01 mflinux01 systemd: Starting Session 12 of user pcp.
Mar  9 15:25:03 mflinux01 systemd: Removed slice user-988.slice.
Mar  9 15:25:03 mflinux01 systemd: Stopping user-988.slice.
Mar  9 15:25:09 mflinux01 pam_linotp[8217]: start pam_linotp.py authentication: 1, ['/lib/security/pam_linotp.py', 'nosslhostnameverify', 'nosslcertverify', 'url=https://192.168.0.14/validate/simplecheck', 'realm=MYDOMAIN', 'debug']
Mar  9 15:25:09 mflinux01 pam_linotp[8217]: got no password in authtok - trying through conversation
Mar  9 15:25:16 mflinux01 pam_linotp[8217]: got password: 932410
Mar  9 15:25:16 mflinux01 pam_linotp[8217]: calling url https://192.168.0.14/validate/simplecheck {'realm': 'MYDOMAIN', 'user': 'vdn@MYDOMAIN.LOC', 'pass': '932410'}
Mar  9 15:25:17 mflinux01 pam_linotp[8217]: :-)
Mar  9 15:25:17 mflinux01 pam_linotp[8217]: user successfully authenticated
Mar  9 15:25:20 mflinux01 sshd: Please note: pam_linotp does not support setcred

By looking for a solution on the web, I also setup the /etc/ssh/ssh_config and /etc/ssh/sshd_config adding ClientAliveInterval 120 and ServerAliveInterval 120, but the error persists.

Take into account that, by removing auth requisite pam_deny.so from the PAM stack, the OTP is of course not properly validated (it is always right), but after the username/pwd check, the SSH authentication works.

Do you have any clue about the resolution of this problem?

Note: all the Linux machines in my environment are based on CentOS 7.


UPDATE:

As follows, you can find the current version of password-auth PAM conf:

#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        [default=1 success=ok] pam_localuser.so
auth        [success=done ignore=ignore default=die] pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        sufficient    pam_sss.so forward_pass
auth        sufficient    pam_krb5.so use_first_pass
auth        required      pam_deny.so

account     required      pam_unix.so broken_shadow
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     [default=bad success=ok user_unknown=ignore] pam_sss.so
account     [default=bad success=ok user_unknown=ignore] pam_krb5.so
account     required      pam_permit.so

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    sufficient    pam_sss.so use_authtok
password    sufficient    pam_krb5.so use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     optional      pam_oddjob_mkhomedir.so umask=0077
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
session     optional      pam_sss.so
session     optional      pam_krb5.so
3

The authentication was successful, which you see at the :-). So obviously it is your remaining stack.

If you say, that it works, when you remove pam deny, then you obviously have a problem in

auth       substack     password-auth

[success=1 default=ignore] means that in case of success the next (1) entry is skipped. So when removing pam_deny the password-auth entry is skipped. So take a look at this subtrack!

Update:

Probably it fails due to the lines

auth        sufficient    pam_sss.so forward_pass
auth        sufficient    pam_krb5.so use_first_pass
auth        required      pam_deny.so

the OTP is not successfully validated by sssd nor kerberos. Thus you will run into pam_deny.

3
  • PS: To get a complete overview over all OSS OTP solutions, you might also take a look at privacyIDEA. ;-) – cornelinux Mar 10 '16 at 13:22
  • Thanks. You updated my question in order to add more info. – vdenotaris Mar 10 '16 at 15:28
  • regarding success=1 default=ignore. The documented behavior of pam_succeed_if with this stanza is that if the check is true, then the next 1 rule is used; otherwise, the next 1 rule is skipped. You can use different integers to affect multiple rules. – Dan Pritts Oct 21 '20 at 22:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.