Least-privilege accounts and sudo on Linux
Enforce strong passwords, account lockout, password aging, secure sudo drop-ins and a tight umask to apply least privilege on Linux systems.
Most Linux compromises escalate through weak or over-privileged accounts: shared admin passwords, dormant system users with a login shell, or NOPASSWD: ALL sudo rules. Applying least privilege means every account has exactly the access it needs and nothing more. This guide covers password quality, lockout, aging, account auditing, scoped sudo and a safe default umask. It pairs well with access and authentication hardening.
Enforce strong passwords with pam_pwquality
Password complexity is enforced by pam_pwquality. Configure it in /etc/security/pwquality.conf:
# /etc/security/pwquality.conf
minlen = 14
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
retry = 3
minlen sets the minimum length. The *credit values, when negative, require at least that many digits (dcredit), uppercase (ucredit), lowercase (lcredit) and other (ocredit) characters. retry limits prompts per passwd invocation. Make sure the module is referenced in the PAM stack (/etc/pam.d/common-password on Debian/Ubuntu, /etc/pam.d/system-auth on RHEL/Fedora).
Lock accounts after failed logins with pam_faillock
Throttle brute-force attempts with pam_faillock. Configure it in /etc/security/faillock.conf:
# /etc/security/faillock.conf
deny = 5
unlock_time = 900
fail_interval = 900
After five failures within the interval the account is locked for 900 seconds. Inspect and reset counters with:
faillock --user alice
faillock --user alice --reset
Set password aging policy
Define system-wide defaults in /etc/login.defs:
# /etc/login.defs
PASS_MAX_DAYS 90
PASS_MIN_DAYS 1
PASS_WARN_AGE 7
These apply to newly created users. Apply aging to existing accounts and audit them with chage:
chage -M 90 -m 1 -W 7 alice
chage -l alice
Audit and disable unused accounts
Find risky accounts. Any UID 0 account other than root is a backdoor, and empty password fields are critical:
awk -F: '($3==0){print}' /etc/passwd
awk -F: '($2==""){print $1}' /etc/shadow
Lock and disable interactive logins for service or dormant accounts:
usermod -L backupsvc
usermod -s /usr/sbin/nologin backupsvc
On RHEL/Fedora the nologin shell is /sbin/nologin. Locking sets a ! in /etc/shadow; combining it with a nologin shell prevents both password and key-based logins.
Apply least privilege with sudo
Never edit /etc/sudoers directly. Use scoped drop-in files under /etc/sudoers.d/ and always validate before saving:
visudo -f /etc/sudoers.d/web-deploy
visudo -c
Grant only the specific commands an operator needs, and avoid NOPASSWD and ALL=(ALL) ALL:
# /etc/sudoers.d/web-deploy
deploy ALL=(root) /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx
Defaults logfile="/var/log/sudo.log"
Restrict the administrative group to a known set of people. On Debian/Ubuntu this is sudo; on RHEL/Fedora it is wheel:
getent group sudo
getent group wheel
Be cautious with Defaults requiretty, which can break automation, and prefer logging every invocation. See also mandatory access control to confine what privileged processes can do.
Set a secure default umask
A 027 umask denies group-write and all other access on new files. Set it in /etc/login.defs and a profile drop-in:
# /etc/login.defs
UMASK 027
# /etc/profile.d/secure-umask.sh
umask 027
Verify your work
Confirm each control quickly:
grep -E 'minlen|credit|retry' /etc/security/pwquality.conf
grep -E 'deny|unlock_time' /etc/security/faillock.conf
awk -F: '($3==0){print}' /etc/passwd
sudo -l -U deploy
umask
If sudo -l shows only the scoped commands, no UID 0 accounts beyond root appear, and your password and lockout policies are in place, your accounts follow least privilege. Review these settings against your compliance benchmarks regularly.