redact gate pattern literals in the audit prose — the pre-commit gate self-matches its own documented patterns when quoted verbatim
28 lines
1.5 KiB
Markdown
28 lines
1.5 KiB
Markdown
---
|
|
name: faillock-sudo-lockout-recovery
|
|
description: "Diagnose and recover from a pam_faillock sudo lockout on Frank's Arch workstations, typically caused by an agent's non-interactive sudo retries"
|
|
---
|
|
|
|
# Faillock Sudo Lockout Recovery
|
|
|
|
## Symptom
|
|
User reports "sudo password rejected / changed"; journal shows
|
|
`pam_faillock(sudo:auth): User <u> is temporarily locked out due to 3 consecutive failed login attempts`.
|
|
|
|
## Diagnose (read-only, one round)
|
|
1. `stat -c '%n mtime=%y ctime=%z' /etc/shadow` — unchanged mtime = password was NEVER changed.
|
|
2. `journalctl --since '<window>' | grep 'sudo\['` — lines with `PWD=` / `COMMAND=` name the spammer (agent harness loops show `PWD=/home/.../.omp`, `COMMAND=...yay/pacman...`, no `TTY=`).
|
|
3. `faillock --user <user>` — shows the valid failure entries.
|
|
|
|
## Root cause law
|
|
In the omp harness sudo has NO TTY: each `sudo <cmd>` = 3 pam_unix failures. Arch pam_faillock defaults deny=3 with ~600s unlock_time, and each retry re-arms it — the user's real interactive sudo is locked while the loop runs.
|
|
|
|
## Recover
|
|
1. Kill the loop: `ps -eo pid,ppid,etime,cmd | grep -E 'sudo|yay|makepkg'` → kill offending PIDs; stop/kill the responsible agent session.
|
|
2. `faillock --user "$USER" --reset` — works unprivileged for your own user (dir /run/faillock/<user> is 0700 owner).
|
|
3. User verifies with `sudo -v` in a real terminal.
|
|
|
|
## Prevent
|
|
- Agents NEVER run sudo/yay/pacman/pkexec; no SUDO_ASKPASS/expect workarounds.
|
|
- Root-requiring steps are handed to the user as exact copy-paste commands in the final report.
|