No soul is struck from the roll. Only locked.
Who may enter, who may become root, and whose key is still in a file two
years after they left. Audit local accounts, sudoers and authorized_keys
across the fleet — then lock the stale ones, with live re-validation first.
“And his key was in the file, and he had left in the spring of the year before.” Findings 6:3 — the jump host, of course
Offboarding removes someone from the directory, the chat, the wiki and the badge system, and then stops. The account on the jump host was created by hand in a hurry in 2022, so it is in no directory, and nothing will ever tell thee it is still there.
jump01.hostname.loc · click an account to lock it
Try root, or the account thou camest in on. Both
decline. So does the one that has never logged in — and that last refusal is the one
worth understanding.
Three verbs. Only one of them touches a host.
discover — read-only. Enumerates accounts from
passwd, joins password status and ageing from
shadow, and last-login age from lastlog. Reads
/etc/sudoers and sudoers.d, and every per-user
authorized_keys it can reach. Writes
users_plan.json and a workbook.
apply — takes the plan, re-runs discovery first, and locks
only the accounts that are still stale. Anyone who logged in since the audit simply drops out
of the list. It never runs userdel, never removes a key, never edits
sudoers.
report — re-renders an existing plan to Excel without touching the fleet.
What makes an account stale. It must be a login account —
UID >= 1000 with a real shell — whose last login is older than
--stale-days, and which is not protected. Every one of those four
conditions is doing work.
Re-checked at apply time, as a second guard
| Protected | Why |
|---|---|
root and every UID < 1000 |
System accounts. Locking one is how a service stops at 04:00 with no obvious cause. |
The account thou connectest as (-u) |
The oldest mistake in fleet management, prevented structurally rather than remembered. |
Anything named with --protect NAME |
Repeatable. For the service account with a human-looking name that has not logged in since it was created, and must not be. |
| Last login unknown, or never | The important one. See below. |
An account with no login history is reported and never auto-locked.
Absence of evidence is not evidence of disuse: lastlog can be
truncated, rotated, or simply never written for an account that authenticates some other
way. Locking on a missing record would mean locking on a gap in a file, which is not a
finding — it is a guess.
Thou wilt still see all eighteen of them in the report, because they are worth thy attention. The tool just will not act on them for thee.
Never deleted — there is no verb for it
There is no userdel in this tool. Not behind a flag, not behind a
confirmation, not in the plan schema. Deletion is a decision with no undo; it stays with thee.
| What apply does | Command | When |
|---|---|---|
| Locks the password | usermod -L |
Always. Immediate, and reversed with a single command if thou art wrong about who left. |
| Expires the account | chage -E |
Only with --expire. This is the one that also stops key-based login, which locking the password alone does not. |
| SSH keys | reported | Never modified. Editing authorized_keys automatically across a fleet is a very efficient way to lock out an entire team at once. |
| sudoers | reported | Never edited. A malformed sudoers file is a host nobody can escalate on, including thee. |
| Home directory and owned files | untouched | Somebody's crontab, somebody's script, somebody's only copy of something. |
Worth knowing: locking the password alone does not stop a key-based
login. If the account has a key in authorized_keys — and the
stale ones usually do — thou wantest --expire as well.
And, as everywhere in this family, it asks first:
The two dropped lines are the re-validation earning its keep. The plan was written last week. One of those people came back from parental leave this morning, and the other never had a login record to begin with.
Eight sheets, and the flags matter more than the counts
Stale Candidates is the sheet
apply would act on — read it before thou runnest anything.
Sudoers lists grant entries with NOPASSWD
highlighted. SSH Keys is the per-user key inventory with weak types
— ssh-dss — called out. Issues collects
duplicate UID 0, duplicate UIDs, and empty passwords: three findings that are each, on their
own, worth a conversation.
Alongside stale, discovery flags accounts with never-expiring passwords, accounts that have never logged in, NOPASSWD sudo grants, and weak keys. None of those make an account stale. All of them belong in the report.
It reads shadow for status and ageing fields only. There is
nowhere in the code where a password hash is read, stored, or written to a report, because
a fleet audit tool holding eighty hosts' worth of hashes is a liability wearing a
spreadsheet.
Count them, read the sheet, then lock the ones thou art sure of
Sudo is needed to read shadow and other users'
authorized_keys. Auth flags match every other book in the family: keys
or agent by default, --ask-ssh-pass for password login,
--sudo-pass-same-as-ssh for sudo. Passwords travel by stdin or the
SSHPASS environment variable, never argv.
Breaking the fourth wall, briefly
A real tool, written by a real sysadmin who read an authorized_keys
file on a slow afternoon and did not enjoy what was in it. Agentless, parallel, MIT licensed.
Hosts it cannot reach go to their own sheet with the reason, and the run carries on.
Its plans can also be handed to linux-apply, whose users adapter guards each lock on “the account still exists and is not currently logged in”, and drops root and UID 0 defensively on the way through — a second refusal behind the first.
It writes an xlsx, and it never writes a formula into one. Everything a host reports is
written as text, so a compromised server cannot hide a payload in a GECOS field and have it
fire when thou openest the report. Same as its elder siblings, through the same
xlsx_safe module. That part is still not a joke.
Built by vK, who has been paged at 03:00 and did not enjoy it. Companion to linux-audit, which examines, and linux-drift, which notices when a new account appears without a ticket.
Kneel also at the parish and read at the scriptorium. The Cluster abides. The Loop reconciles. The key, unremoved, still opens the door.
Nothing here works alone, and neither shouldst thou
The fleet is one testament in several books. Each does one job, writes a report thou canst hand to anyone, and refuses to be clever with thy servers.