Comprehensive Guide: Diagnosing and Resolving All Types of Unix Account Lockout Scenarios


2 views

Account lockouts in Unix/Linux systems can occur through multiple channels. Here are the primary methods:

# Common lockout indicators in /etc/shadow (second field):
* : Account disabled
! : Password locked
!! : Account never had password
$6$... : Normal encrypted password

The most common lockout scenario involves password expiration policies:

# Check password aging status
chage -l username

# Common expiration-related files:
/etc/login.defs  # Password aging defaults
/etc/default/useradd  # Account creation defaults

PAM modules like pam_tally2 or pam_faillock can lock accounts:

# Check failed attempts (pam_tally2)
pam_tally2 --user=username

# Reset counter
pam_tally2 --user=username --reset

# For systems using faillock:
faillock --user username
faillock --user username --reset

Administrators can explicitly lock accounts:

# Using usermod
usermod -L username  # Lock
usermod -U username  # Unlock

# Using passwd
passwd -l username  # Lock
passwd -u username  # Unlock

SSH has its own lockout mechanisms:

# Check SSH deny rules
grep username /etc/ssh/sshd_deny
grep DenyUsers /etc/ssh/sshd_config

Some systems enforce additional restrictions:

# Check account accessibility
groups username
id username

# Verify PAM stack
ls -l /etc/pam.d/
cat /etc/pam.d/system-auth

Here's a comprehensive check script:

#!/bin/bash

USERNAME=$1

echo "=== Account Status Check for $USERNAME ==="

# Shadow file check
echo -n "Shadow status: "
grep "^$USERNAME:" /etc/shadow | cut -d: -f2 | cut -c1-3

# Password aging
echo "Password aging:"
chage -l $USERNAME

# Failed attempts
if which pam_tally2 &>/dev/null; then
    echo "Failed attempts (pam_tally2):"
    pam_tally2 --user=$USERNAME
fi

if which faillock &>/dev/null; then
    echo "Failed attempts (faillock):"
    faillock --user $USERNAME
fi

# Account locks
echo "Account locked (usermod/passwd):"
passwd -S $USERNAME

# SSH restrictions
echo "SSH restrictions:"
grep $USERNAME /etc/ssh/sshd_config

# Group memberships
echo "Group memberships:"
groups $USERNAME

MAC systems can prevent logins:

# Check SELinux context
semanage login -l | grep $USERNAME

# Verify AVC denials
ausearch -m avc -ts recent | grep $USERNAME

When facing an account lockout:

  1. Check /etc/shadow password field
  2. Review chage -l output
  3. Check PAM failure counters
  4. Verify manual locks (usermod/passwd)
  5. Inspect SSH restrictions
  6. Confirm group memberships
  7. Check SELinux/AppArmor contexts

Unix/Linux systems provide multiple layers of account security that can independently or cumulatively lock users out. The main mechanisms include:

  • Password aging policies (/etc/shadow)
  • Failed login attempt limits (pam_tally2/pam_faillock)
  • Manual account locking (usermod -L or passwd -l)
  • SSH key authentication failures
  • SELinux/AppArmor restrictions

Use this systematic approach to identify all active lock conditions:

# 1. Check account status in /etc/shadow
sudo grep username /etc/shadow

# 2. Verify PAM failure counters
sudo pam_tally2 --user=username
# Or on newer systems:
sudo faillock --user username

# 3. Examine manual locks
sudo passwd -S username

# 4. Check secondary authentication systems
sudo ls /etc/security/access.conf
sudo ls /etc/security/time.conf

# 5. Verify PAM stack configuration
sudo cat /etc/pam.d/system-auth
sudo cat /etc/pam.d/sshd

1. Password Expiration

When /etc/shadow shows a password expiration:

username:$6$...:18648:5:90:7::18690:

The fields indicate password last changed (18648), minimum days (5), maximum days (90), and warning period (7). The account will lock after day 18648+90.

Solution:

sudo chage -E -1 username  # Remove expiration
sudo chage -d $(date +%Y-%m-%d) username  # Reset password age

2. Failed Attempt Lockouts

For pam_tally2 locked accounts (common on RHEL/CentOS):

# View failures
sudo pam_tally2 --user=username

# Reset counter
sudo pam_tally2 --user=username --reset

For pam_faillock (modern systems):

# View status
sudo faillock --user username

# Unlock
sudo faillock --user username --reset

3. Manual Account Locks

Check for explicit locks with:

sudo passwd -S username
# Output: username L 04/10/2023 0 99999 7 -1

The "L" indicates manual lock. Unlock with:

sudo usermod -U username
# Or:
sudo passwd -u username

PAM Stack Conflicts

Multiple PAM modules can interfere:

auth required pam_faillock.so preauth
auth sufficient pam_unix.so nullok try_first_pass
auth [default=die] pam_faillock.so authfail

Ensure your PAM configuration doesn't have duplicate or conflicting modules.

SSHD-Specific Issues

Check for these in /etc/ssh/sshd_config:

MaxAuthTries 3
PermitRootLogin prohibit-password
UsePAM yes

Excessive MaxAuthTries values with UsePAM=yes can create multiple lock conditions.

This bash script checks all common lock conditions:

#!/bin/bash
username=$1

echo "Checking lock status for $username"

# Shadow checks
echo -n "Shadow status: "
shadow_entry=$(sudo grep "^$username:" /etc/shadow)
if [[ -z "$shadow_entry" ]]; then
    echo "User not found"
    exit 1
fi

IFS=':' read -ra shadow_fields <<< "$shadow_entry"
if [[ "${shadow_fields[1]}" == "!"* || "${shadow_fields[1]}" == "*" ]]; then
    echo "LOCKED (password disabled)"
fi

if [[ "${shadow_fields[7]}" != "" && "${shadow_fields[7]}" != -1 ]]; then
    echo "LOCKED (account expired)"
fi

# PAM checks
if command -v pam_tally2 &> /dev/null; then
    echo -n "PAM tally: "
    sudo pam_tally2 --user=$username
fi

if command -v faillock &> /dev/null; then
    echo -n "Faillock: "
    sudo faillock --user $username
fi

# Manual lock check
echo -n "Passwd status: "
sudo passwd -S $username

Run with sudo privileges to get comprehensive lock status.