๐ŸŽ New User? Get 20% off your first purchase with code NEWUSER20 ยท โšก Instant download ยท ๐Ÿ”’ Secure checkout Register Now โ†’
Menu

Categories

PAM Authentication Audit: Securing the Linux Login Stack

PAM Authentication Audit: Securing the Linux Login Stack

PAM (Pluggable Authentication Modules) is the layer between every Linux login and the password, key, or token that proves identity. A misconfigured PAM stack can lock out the entire ops team during a maintenance window or โ€” worse โ€” silently allow logins that should fail. Because PAM is configured per-service in /etc/pam.d/, and changes are applied without restart, the failure mode is fast and uncomfortable. This guide explains the stack, the audit commands that surface weak rules, and the modern replacements for legacy modules.

The PAM concept in 60 seconds

For each service (sshd, sudo, login, su, gdm, etc.), PAM evaluates four module groups in order: auth (verify identity), account (is this user allowed?), password (change credentials), session (set up environment). Each group is a sequence of modules with control flags: required, requisite, sufficient, optional, or the modern [default=โ€ฆ] bracket syntax.

ls /etc/pam.d/                       # one file per service
cat /etc/pam.d/sshd
grep -r pam_unix /etc/pam.d/         # find usages of a module
man pam_faillock                     # per-module documentation

Inventory: what is currently in your stack

sudo grep -rE '^[^#]' /etc/pam.d/ | grep -v '^[^:]*:#' | sort
sudo grep -rE 'pam_(unix|sss|ldap|krb5|tally|faillock|pwquality|cracklib)' /etc/pam.d/

The first command is a complete dump of every active PAM rule on the host โ€” paste it into your audit notebook. The second highlights authentication backends and policy modules.

Account lockout: the must-have policy

Without a lockout module, an attacker can brute-force a local account indefinitely. The modern replacement for the deprecated pam_tally2 is pam_faillock:

# /etc/security/faillock.conf
deny = 5
unlock_time = 900
even_deny_root
admin_group = wheel

Then in /etc/pam.d/system-auth (RHEL family) or by running pam-auth-update (Debian/Ubuntu). Verify with:

sudo faillock --user alice           # current count for a user
sudo faillock --user alice --reset   # clear after legitimate fail

Password quality enforcement

pam_pwquality rejects weak new passwords at the time they are set:

# /etc/security/pwquality.conf
minlen = 14
minclass = 4
maxrepeat = 3
maxsequence = 3
dictcheck = 1
enforce_for_root

pam_pwhistory remembers previous hashes so users cannot recycle the last N passwords. Both layered on top of the existing password stack via pam-auth-update on Debian/Ubuntu or by editing /etc/pam.d/system-auth on RHEL.

Time- and source-based access

pam_access in the account stack enforces who can log in from where:

# /etc/security/access.conf
+ : root      : 10.0.0.0/8 LOCAL
+ : ops admin : ALL
- : ALL       : ALL

pam_time restricts logins to specific hours per user. Both are useful on shared bastion hosts where you want a defence-in-depth layer above SSH AllowUsers.

Limits and session hardening

The session stack is where ulimits, cgroup placement, and umask are applied. The standard line:

session required pam_limits.so

โ€ฆ reads /etc/security/limits.conf and /etc/security/limits.d/ for every PAM-authenticated session. Without it, your carefully tuned ulimit drop-ins do nothing for SSH logins. Confirm presence:

grep pam_limits /etc/pam.d/sshd /etc/pam.d/login /etc/pam.d/system-auth

The audit script

#!/bin/bash
echo "== Lockout module present =="
grep -lE 'pam_(faillock|tally2)' /etc/pam.d/* || echo "FAIL: no lockout"
echo "== Password quality present =="
grep -lE 'pam_(pwquality|cracklib)' /etc/pam.d/* || echo "FAIL: no pwquality"
echo "== pam_limits in session stack =="
grep -lE '^session.*pam_limits' /etc/pam.d/* || echo "FAIL: no pam_limits"
echo "== Empty password allowed =="
grep -rE 'nullok' /etc/pam.d/ && echo "WARN: nullok found"
echo "== Faillock counters =="
faillock --user-list 2>/dev/null | head

Multi-factor authentication

Layer TOTP onto SSH key auth via pam_google_authenticator or pam_oath:

# /etc/pam.d/sshd โ€“ at top
auth required pam_google_authenticator.so

Combined with AuthenticationMethods publickey,keyboard-interactive in sshd_config, the server requires both a private key and a fresh code, defeating credential theft.

Recovery: the safety net

A typo in /etc/pam.d/sshd can lock you out instantly. Three precautions:

  1. Always keep an open root SSH session in a second terminal while editing PAM.
  2. Test the change against a fresh login โ€” do not trust the open session.
  3. Keep /etc/pam.d/ under version control, ideally with the rest of /etc/ in etckeeper:
    sudo apt install etckeeper
    sudo etckeeper init
    sudo etckeeper commit "before pam edit"

Common pitfalls

  • Using auth sufficient pam_unix.so nullok โ€” allows blank passwords. Remove nullok on every internet-facing host.
  • Editing per-service files (/etc/pam.d/sshd) when the change should be in the shared system-auth; the result is policy that applies to SSH but not su.
  • Forgetting even_deny_root in faillock โ€” root is the most attacked account, and root can clear its own counter trivially.
  • Running pam-auth-update on Debian without reading the diff โ€” it can quietly remove a custom module you added by hand.

PAM rewards investment. A properly audited stack with lockout, password quality, source restrictions, and MFA closes more attack vectors than every other Linux hardening combined. Spend an afternoon, document every line, and put it under change control.

Share this article:
Dargslan Editorial Team (Dargslan)
About the Author

Dargslan Editorial Team (Dargslan)

Collective of Software Developers, System Administrators, DevOps Engineers, and IT Authors

Dargslan is an independent technology publishing collective formed by experienced software developers, system administrators, and IT specialists.

The Dargslan editorial team works collaboratively to create practical, hands-on technology books focused on real-world use cases. Each publication is developed, reviewed, and...

Programming Languages Linux Administration Web Development Cybersecurity Networking

Stay Updated

Subscribe to our newsletter for the latest tutorials, tips, and exclusive offers.