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
vdenotaris
  • 123
  • 2
  • 8

1 Answers1

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.

cornelinux
  • 229
  • 1
  • 7
  • 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