Ssh – Expired password and SSH key based login with UsePAM yes

pampasswordsshusers

There is a SLES 11 machine. The users logs in via SSH and pubkey (mixed, some user uses password, some use ssh key)

The sshd_config has:

UsePAM yes
PasswordAuthentication yes
PubkeyAuthentication yes

The problem: If the password expires for a user that uses pubkey login, then the user will be prompted to change password.

The question: How can we set the PAM or sshd config to allow users to log in if they have a valid SSH key and they're password expired? – Without popping up "change your password".

UPDATE#1: The solution can't be: "UsePAM no"

SERVER:~ # cat /etc/pam.d/sshd 
#%PAM-1.0
auth        requisite   pam_nologin.so
auth        include     common-auth
account     requisite   pam_nologin.so
account     include     common-account
password    include     common-password
session     required    pam_loginuid.so
session     include     common-session
SERVER:~ # 

UPDATE#2: The solution can't be: set the users password to never expire

UPDATE#3:

SERVER:/etc/pam.d # cat common-account
#%PAM-1.0
...
account required    pam_unix2.so    
account required    pam_tally.so
SERVER:/etc/pam.d # 

Best Answer

The order of operations that causes the expired password prompt is as follows:

  • SSH runs the PAM account stage, which verifies that the account exists and is valid. The account stage notices that the password has expired, and lets SSH know.
  • SSH performs key-based authentication. It doesn't need PAM for this, so it doesn't run the auth stage. It then sets up the SSH login session and runs the PAM session stage.
  • Next, SSH remembers that PAM told it the password had expired, prints a warning message, and asks PAM to have the user change the password. SSH then disconnects.

All of this is SSH's doing, and I don't see any SSH options to configure this behavior. So unless you want to build a custom version of SSH and/or PAM, the only option I see is to prevent PAM from reporting the expired password to SSH. If you do this, it will disable expired password checks over SSH entirely, even if the user is logging in over SSH with a password. Other (non-SSH) methods of login will still check password expiration.

Your current pam.d/sshd file has a account include common-account entry. I presume there's a common-account file which contains a reference to pam_unix.so. This is the line that checks for an expired password.

You probably don't want to touch the common-account file itself, since it's used for other login methods. Instead, you want to remove the include from your pam.d/sshd file. If there are other functions in common-account besides pam_unix.so, you probably want to put them directly into pam.d/sshd.

Finally, remember that this is a modification to the security of your system and you shouldn't just blindly trust me to give you good advice. Read up on how PAM works if you're unfamiliar with it. Some starting places might be man 7 PAM, man 5 pam.conf, and man 8 pam_unix.

Related Question