← News
/PLAYBOOK · 2026-08-22

Linux Account Hardening in Practice: Least-Privilege sudo Configuration Guide

From weak-password brute force to sudo misconfig privilege escalation. Systematic Linux account hardening: PAM password policy, login-failure lockout, least-privilege sudoers, and audit. Full runnable commands and verification. For multi-user cloud servers and VPS.

Linux account hardening is the first line of defense against server intrusion. Least-privilege sudo configuration directly determines how hard privilege-escalation attacks are. This guide targets multi-user cloud servers and VPS ops: password policy, login-failure lockout, least-privilege sudoers authorization, and audit. All commands run as-is on RHEL-family (CentOS/Rocky/Alma) and Debian-family (Ubuntu/Debian).

Applicable Scenarios

Prerequisites

How It Works

Account hardening rests on three mechanisms: pam_pwquality enforces password strength (length, complexity, reuse); pam_faillock locks the account after a failure threshold to slow brute force; sudoers restricts privileged operations to a minimal command set. The layers are independent and complementary: even if a password is guessed, lockout slows brute force; even with a normal account, least-privilege sudoers sharply narrows escalation paths; audit logs make every privileged action traceable.

Procedure

Step 1: Password Policy Hardening

`# Password complexity (RHEL8+/Debian family)
cat > /etc/security/pwquality.conf.d/99-hardening.conf <<'EOF'
minlen = 14
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
minclass = 3
EOF
# Password aging (modify in /etc/login.defs)
sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs
sed -i 's/^PASS_MIN_LEN.*/PASS_MIN_LEN 14/' /etc/login.defs
sed -i 's/^PASS_WARN_AGE.*/PASS_WARN_AGE 7/' /etc/login.defs
# Check empty-password accounts and UID 0 accounts
awk -F: '($2 == "") {print "EMPTY PASSWORD: " $1}' /etc/shadow
awk -F: '($3 == 0 && $1 != "root") {print "UID 0: " $1}' /etc/passwd`

Step 2: Login-Failure Lockout (pam_faillock, RHEL 8+)

`# Write faillock config: lock after 5 failures for 15 minutes; unlock_time 15 minutes
cat > /etc/security/faillock.conf <<'EOF'
deny = 5
unlock_time = 900
even_deny_root
silent
EOF
# Wire faillock into system-auth / password-auth (RHEL8+ PAM modules automatically read faillock.conf)
# Verify configuration is loaded
pam-auth-update --enable 2>/dev/null || true   # Debian/Ubuntu require libpam-faillock`

Step 3: Least-Privilege sudoers

`# Create a dedicated authorization file with visudo (syntax check runs automatically)
visudo -f /etc/sudoers.d/ops
# Content example: ops group allowed only systemctl/log/process-management commands
# %ops ALL=(root) /usr/bin/systemctl, /usr/bin/journalctl, /usr/bin/ps, /usr/bin/top, /usr/bin/kill
# Enable I/O logging and command auditing
cat > /etc/sudoers.d/audit <<'EOF'
Defaults log_input, log_output
Defaults !requiretty
Defaults timestamp_timeout=5
Defaults syslog=authpriv
EOF
# Validate syntax
visudo -c`

Step 4: SSH-Side Hardening

`# Disable direct root SSH login; elevate via sudo (/etc/ssh/sshd_config)
sed -i 's/^#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart sshd`

Step 5: Audit and Monitoring

`# View sudo usage records (RHEL family /var/log/secure, Debian family /var/log/auth.log)
grep sudo /var/log/secure | tail -20
# View recent failed-login sources
grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head`

Configuration Verification

`# 1. Verify sudoers authorization is in effect (should list only authorized commands)
sudo -l
# 2. Verify denied commands (unauthorized commands should report "not allowed to run")
sudo cat /etc/shadow
# 3. Verify login lockout: after 5 consecutive wrong passwords, should prompt Account locked
# 4. Verify audit: after running sudo systemctl status nginx once, check sudo logs
grep systemctl /var/log/secure | tail -3`

FAQ

Q1: sudoers typo locked every account out of sudo. How to recover?

Do not reboot. Fix it in the retained root session. If root cannot run sudo itself, use pkexec visudo -f /etc/sudoers.d/xxx or repair after mounting in rescue mode. Daily best practice: edit with visudo (forced syntax check on save), validate on a test account, then roll out.

Q2: Do faillock and fail2ban lockout mechanisms conflict?

No. Complementary. faillock locks accounts at the PAM layer (local and SSH); fail2ban bans source IPs at the network layer. Running both yields account+IP dual protection. Note even_deny_root also locks root; unlock in rescue/single-user mode.

Q3: Many team accounts. How to avoid per-account sudoers entries?

Use group grants: add members to %ops, write one group rule in sudoers.d. New members join the group for the same rights; leavers are removed from the group. For finer grain, stack command aliases (Cmnd_Alias) and time windows (sudo supports HOSTS/CMDS/time limits).

Summary

Four steps: password policy raises the bar, faillock stops online brute force, least-privilege sudoers narrows escalation, audit logs provide traceability. After configuration, verify with sudo -l and login tests, and keep a usable root emergency path (e.g. cloud-vendor rescue mode) so a misconfig does not strand you.