3 of 3

PAM and Account PolicyLesson 3 of 3

Why can't this user log in?

Work through password, account state, shell, PAM restrictions, sshd rules and SELinux labels using the logs.

  • journalctl _COMM=sshd
  • /var/log/secure
  • sshd -T
  • sshd -t
  • ausearch -m user_auth
  • last
  • lastb
  • getent passwd
  • namei -l
  • restorecon
  • visudo -c
  • sudo -l -U
  • /etc/nologin
  • /etc/security/access.conf

55 min3 exercises

After this lesson you can

  • Read sshd and PAM messages in /var/log/secure and the journal and map each to a cause.
  • Check the effective sshd configuration with sshd -T and the drop-in order.
  • Diagnose key-based login failures from permissions and SELinux labels, and restrictions from pam_access and /etc/nologin.

The idea

“I can’t log in” is a symptom with at least a dozen causes, and the fastest way to the right one is to let the system tell you. Every login attempt is logged twice: by the service that handled it (sshd, login, su) and by the PAM modules it called. Both write to /var/log/secure on RHEL (and to the journal), with enough text to name the stage that refused.

sudo tail -f /var/log/secure                    # watch while the user retries
sudo journalctl _COMM=sshd -S "10 min ago"      # sshd entries from the journal
sudo ausearch -m user_auth,user_acct -ts recent # audit records of auth and account decisions
last -n 10                                      # recent successful logins
sudo lastb -n 10                                # recent failed logins

Ask the user to retry while you watch. A message written at that moment is worth more than any theory.

Which stage refused?

A login passes through these checks, in order. The first that fails ends the attempt.

#StageFails withEvidenceCheck
1Does the user exist?invalid user Xsshd loggetent passwd X
2sshd rulesnot allowed because not listed in AllowUsers, DenyUsers, PermitRootLogin nosshd logsshd -T, drop-ins
3Authentication: passwordFailed password, authentication failurepam_unix(...:auth)faillock --user, the password itself, passwd -S
3Authentication: keyAuthentication refused: bad ownership or modes, or silence then password promptsshd log, ssh -vPermissions, label, key content
4PAM accountexpired, account locked, pam_nologin: Refused, pam_access: access deniedpam_unix(...:account)chage -l, /etc/nologin, access.conf
5ShellConnection opens and closes at onceThis account is currently not available.getent passwd field 7
6Sessionpam_limits, pam_selinux, home missingpam_*(...:session)ls -ld ~, getsebool, limits

sshd: read the effective configuration

Editing /etc/ssh/sshd_config is not enough to know what sshd does. On RHEL it includes /etc/ssh/sshd_config.d/*.conf, and for most options the first value wins. Packaged defaults live in 50-redhat.conf; put your local settings in a file that sorts earlier, such as 01-local.conf.

sudo sshd -t                           # syntax check; prints nothing when OK
sudo sshd -T | grep -iE 'permitrootlogin|passwordauthentication|allowusers|allowgroups|pubkeyauthentication'
ls /etc/ssh/sshd_config.d/
sudo systemctl reload sshd             # not restart: keeps existing sessions

sshd -T prints the configuration as sshd actually parsed it, including defaults. If a setting you edited is not what -T shows, a drop-in earlier in the order overrides it, or the daemon was not reloaded.

Key login: three families of fault

If key login falls back to a password prompt, one of the following is wrong on the server:

  1. Ownership and modes. With StrictModes yes (default), sshd refuses a key if the home directory, ~/.ssh or authorized_keys is writable by group or others, or not owned by the user. Required: home not writable by others (755 or 750), .ssh 700, authorized_keys 600.
  2. SELinux labels. sshd runs confined; files must be ssh_home_t (for .ssh and authorized_keys). Copying files in as root from elsewhere leaves wrong labels. The log shows nothing useful; ausearch -m avc does. Repair with restorecon -Rv ~/.ssh.
  3. The key itself. Wrong public key, truncated line, a from= or command= option, or the file is not in a location named by AuthorizedKeysFile.

On the client, ssh -v user@host shows which keys are offered and the server’s reply; -vvv adds the details.

Restrictions outside sshd

MechanismFileEffect
pam_nologin/etc/nologin existsNon-root logins refused with its text
pam_access/etc/security/access.confAllow/deny by user, group, origin: -:u4:ALL
pam_time/etc/security/time.confAllow only at certain times
pam_limits/etc/security/limits.d/*.confResource limits, can cause session failures for extreme values
pam_listfile, pam_wheelthe service’s /etc/pam.d/FILELists and group requirements (su requires wheel in many setups)
shellgetent passwd field 7/sbin/nologin or /bin/false refuses interactive login

sudo is a separate decision after login: sudo -l -U alex lists what a user may run; sudo visudo -c checks the syntax of all sudoers files. A syntax error in /etc/sudoers breaks sudo for everybody; edit with visudo, never with an editor directly.

Try it

Reading a failed attempt

sudo journalctl _COMM=sshd -n 6 --no-pager
Nov 04 13:02:11 node2 sshd[2201]: Failed password for alex from 192.168.50.11 port 40122 ssh2
Nov 04 13:02:19 node2 sshd[2203]: User carol not allowed because account is locked
Nov 04 13:02:25 node2 sshd[2205]: pam_nologin(sshd:account): Refused user dave
Nov 04 13:02:31 node2 sshd[2207]: Authentication refused: bad ownership or modes for directory /home/erin
Nov 04 13:02:37 node2 sshd[2209]: User frank from 192.168.50.11 not allowed because not listed in AllowUsers
Nov 04 13:02:44 node2 sshd[2211]: Failed password for invalid user bob from 192.168.50.11 port 40130 ssh2

Every line names its cause. Notice that “Failed password for invalid user bob” is a nonexistent account, and the same text without “invalid user” is a real account with a wrong password. Do not read the first as a password problem.

The home directory and the label

namei -l /home/erin/.ssh/authorized_keys
ls -Z /home/erin/.ssh
f: /home/erin/.ssh/authorized_keys
dr-xr-xr-x root root /
drwxr-xr-x root root home
drwxrwxr-x erin erin erin
drwx------ erin erin .ssh
-rw------- erin erin authorized_keys
unconfined_u:object_r:user_home_t:s0 authorized_keys

(Representative output.) Two faults in one view: the home directory erin is drwxrwxr-x (group writable, which StrictModes refuses), and the file’s type is user_home_t instead of ssh_home_t. Fix the first with chmod 755 /home/erin (or 750), the second with restorecon -Rv /home/erin/.ssh, and test again. If SELinux were the only fault, the log would show no “bad ownership” line at all, only a failed key and a fallback to a password prompt.

Account state at a glance

Three commands that answer most account questions:

getent passwd labuser1
passwd -S labuser1
chage -l labuser1 | sed -n 1,4p
labuser1:x:30033:30033::/home/labuser1:/sbin/nologin
labuser1 P 2026-11-04 7 90 14 5
Last password change					: Nov 04, 2026
Password expires					: Feb 02, 2027
Password inactive					: Feb 07, 2027
Account expires						: Jan 01, 2020

(Real output from a test account.) Three separate things are wrong with this account: the shell is /sbin/nologin, the account expired in 2020, and the password has an inactivity limit. passwd -S alone says P (fine), which is why you need all three commands. After each change, test the login again, because the next fault only shows up once the first is fixed.

A routine for any login failure

  1. Reproduce it yourself (ssh -v, or su - user) while watching /var/log/secure.
  2. Read the exact message and place it in the table above.
  3. Confirm with one command (getent, passwd -S, chage -l, sshd -T, namei -l, ls -Z, ausearch).
  4. Change one thing, retry, and read the log again.
  5. When it works, check that the fix is persistent (a file, not a runtime tweak) and that you have not relaxed security to get there.

Going further

Locked out as root. If PAM or sshd configuration prevents every login, the console and the recovery path from the boot lessons (rd.break, rescue media, authselect apply-changes) are the way back. Having a tested recovery path is part of changing authentication. Beyond the exam: with SSSD and IdM, failures involve the sssd cache, Kerberos tickets and clock skew (sssctl user-checks USER, klist); the local checks above still apply first, and sssctl user-checks shows how the PAM stack sees the user.

Practice

0 of 3 done

Do these on your own system. They get harder. Check each result, then tick it off.

  1. Warm-up

    Match the message to the cause

    For each log line, name the cause and the check that confirms it:

    sshd[2201]: Failed password for alex from 192.168.50.11 port 40122 ssh2
    sshd[2201]: Failed password for invalid user bob from 192.168.50.11 port 40130 ssh2
    sshd[2203]: User carol not allowed because account is locked
    sshd[2205]: pam_nologin(sshd:account): Refused user dave
    sshd[2207]: Authentication refused: bad ownership or modes for directory /home/erin
    sshd[2209]: User frank from 192.168.50.11 not allowed because not listed in AllowUsers
    Check your result
    • 1: wrong password for an existing user (faillock --user alex, expiry with chage -l).
    • 2: the user does not exist (getent passwd bob).
    • 3: the account is locked (passwd -S carol, usermod -U).
    • 4: /etc/nologin exists (ls -l /etc/nologin, remove or wait for maintenance end).
    • 5: home directory is group/world writable (ls -ld /home/erin, chmod 755 or 750).
    • 6: AllowUsers/AllowGroups in the effective configuration (sshd -T | grep -i allow).
    Hint

    sshd names the stage in the text: invalid user means no such account; not allowed because ... is a rule; Authentication refused is a permission problem with a file or directory; pam_*(...) names the PAM module and group that refused.

    Solution
    sudo grep sshd /var/log/secure | tail -20
    getent passwd bob
    sudo passwd -S carol
    ls -l /etc/nologin
    ls -ld /home/erin
    sudo sshd -T | grep -iE 'allowusers|allowgroups|denyusers'
  2. Practice

    The key is right but the server says no

    Setup (server node2):

    sudo useradd -m keyuser
    sudo -u keyuser mkdir -m 755 /home/keyuser/.ssh
    echo "ssh-ed25519 AAAA...your public key... keyuser@lab" | sudo tee /home/keyuser/.ssh/authorized_keys
    sudo chmod 664 /home/keyuser/.ssh/authorized_keys
    sudo chmod 775 /home/keyuser
    sudo chcon -t user_home_t /home/keyuser/.ssh /home/keyuser/.ssh/authorized_keys

    ssh keyuser@node2.lab.example asks for a password or says Permission denied (publickey). Find all three causes using ssh -v on the client and the log, namei -l and ls -Z on the server, and fix them with the minimum change. Then log in with the key.

    Check your result
    • ssh -o PreferredAuthentications=publickey keyuser@node2.lab.example id works.
    • On node2: ls -ld /home/keyuser shows no group/other write; .ssh is 700, authorized_keys is 600; ls -Z shows ssh_home_t for both.
    Hint

    The log says Authentication refused: bad ownership or modes for the permission faults (StrictModes yes is the default). The label fault leaves no such message: sshd simply cannot read the file, and ausearch -m avc shows a denial. restorecon -Rv ~keyuser/.ssh repairs labels from policy.

    Solution
    ssh -v keyuser@node2.lab.example 2>&1 | grep -iE 'offering|denied|authenticat' | head
    sudo journalctl _COMM=sshd -n 5 --no-pager
    namei -l /home/keyuser/.ssh/authorized_keys
    ls -Z /home/keyuser/.ssh
    sudo chmod 755 /home/keyuser
    sudo chmod 700 /home/keyuser/.ssh && sudo chmod 600 /home/keyuser/.ssh/authorized_keys
    sudo restorecon -Rv /home/keyuser/.ssh
    ssh keyuser@node2.lab.example id
  3. Challenge

    Five users, five reasons

    Setup (lab VM; keep a root session open): create five users u1..u5 with a known password and cause one different fault for each, without telling yourself which is which:

    for u in u1 u2 u3 u4 u5; do sudo useradd -m $u; echo "$u:Lab-Pass-12345" | sudo chpasswd; done
    sudo usermod -L u1
    sudo chage -E 2020-01-01 u2
    sudo usermod -s /sbin/nologin u3
    echo '-:u4:ALL' | sudo tee -a /etc/security/access.conf
    sudo chage -d 0 -M 1 -I 0 u5 && sudo chage -d 2020-01-01 u5

    (the pam_access line only takes effect if the account stack includes pam_access.so; add it with authselect features or a custom profile, or use the equivalent DenyUsers u4 in an sshd drop-in). Try su - uN or ssh uN@localhost for each, and for every one name the cause, the single command that proves it, and the fix. Make sure the final state lets all five log in and you have changed no more than needed.

    Check your result
    • u1: passwd -S u1 is L → usermod -U u1.
    • u2: chage -l u2 Account expires in the past → chage -E -1 u2.
    • u3: getent passwd u3 shell /sbin/nologin → usermod -s /bin/bash u3.
    • u4: rule in access.conf or DenyUsers → remove it.
    • u5: password expired and inactive period over → chage -I -1 -M 99999 -d $(date +%F) u5 (or set a new password).
    • Each su - uN -c id succeeds.
    Hint

    Four checks cover almost everything: getent passwd (shell), passwd -S (lock), chage -l (expiry and aging), and the logs journalctl _COMM=sshd, /var/log/secure. The message text tells which PAM group refused: pam_unix(sshd:account): expired is account, authentication failure is auth.

    Solution
    for u in u1 u2 u3 u4 u5; do echo "== $u"; getent passwd $u | cut -d: -f1,7; sudo passwd -S $u; sudo chage -l $u | sed -n '2,4p'; done
    sudo grep -E 'u[1-5]' /var/log/secure | tail -15
    sudo usermod -U u1
    sudo chage -E -1 u2
    sudo usermod -s /bin/bash u3
    sudo sed -i '/^-:u4:ALL/d' /etc/security/access.conf
    sudo chage -I -1 -M 99999 -d $(date +%F) u5
    for u in u1 u2 u3 u4 u5; do sudo su - $u -c 'id -un'; done