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 
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

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


SERVER:/etc/pam.d # cat common-account
account required    pam_unix2.so    
account required    pam_tally.so
SERVER:/etc/pam.d # 
  • You might be able to accomplish this by removing pam_unix.so from the session section of /etc/pam.d/sshd (and replace it with pam_lastlog.so if it's not there. I'm not sure if pam_unix.so/session is the one doing this or not, but it feels like the right place. – Patrick Oct 9 '14 at 18:35
  • 1
    set the user account for never to be expired :) – Raza Oct 9 '14 at 18:42
  • @Raza: Thanks :) great idea, but cannot be a solution :( – thequestionthequestion Oct 9 '14 at 18:44
  • try ForcedPasswdChange No this is for SSH1 – Raza Oct 9 '14 at 18:46
  • 1
    I realized that ForcedPasswdChange No will not work after expiration. you are looking for a solution that will allow expired user to login – Raza Oct 9 '14 at 18:57

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.

  • Nice explanation of the order of operations, thanks. – M_dk Jul 27 '15 at 10:43

An option was added to pam_unix.so (around Feb-2016) called no_pass_expiry (source code change here or man page here). Basically it tells pam_unix to ignore an expired password if something other than pam_unix was used for auth, e.g. if sshd performed the auth.

As a result, if you have a version of pam_unix.so that contains that option, you should be able to configure PAM to:

  1. Still warn but don't require a change to an expired password if an SSH key was used to authenticate via ssh
  2. Require a password change of an expired password if a login/password via pam_unix.so was used to authenticate via ssh
  3. Not impact any other auth sequence (e.g. via the login service).

For example, I configured a RHEL 7 server to do the above by simply updating /etc/pam.d/sshd and adding pam_unix.so no_pass_expiry to both the account and password types, e.g.

account    required    pam_nologin.so
account    sufficient  pam_unix.so no_pass_expiry
account    include     password-auth
password   sufficient  pam_unix.so no_pass_expiry
password   include     password-auth
  • Just tried this and it works. You can check if your PAM support this option or not by searching "no_pass_expiry" exist or not inside the "man 8 pam_unix" man page. – Tomofumi Sep 3 '18 at 3:56
  • You might not want to change your PAM or sshd_config for compliance reasons.
  • You might be using PasswordAuthentication no in sshd_config
  • You might have randomized passwords.
  • You might even have implemented CIS compliance.
  • Still your users get the prompt

Then root can tweak the password changed date:

for user in `grep ":x:[0-9]\{4\}" /etc/passwd|cut -d: -f1`; do chage -d today $user; done

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.