Locks Linux system accounts under UID 1000 and points their shells at nologin to block interactive logins
This Automox Worklet™ locks interactive login on every Linux system account that has no reason to host a human session. The Worklet reads /etc/passwd, picks out every entry with a UID below 1000, and applies two changes per account: usermod -L to lock the password field, and usermod -s /sbin/nologin to swap the login shell out from under any future SSH or console attempt. The combination blocks both the password path and the public-key path.
Four accounts are skipped on purpose. The Worklet preserves root so administrators retain a recovery path, and it preserves halt, sync, and shutdown because their legacy shells map to system control commands rather than interactive sessions. Every other account with a UID below 1000 is locked and pointed at nologin.
The remediation is idempotent. Running it a second time on an already-hardened endpoint produces no changes, because usermod is a no-op when the target state already matches. That makes the Worklet safe to schedule on a recurring policy so that any account a future package install adds with a default shell is corrected on the next evaluation.
CIS Benchmark control 5.4.2 calls for every account below the UID_MIN threshold to be locked and pointed at a non-interactive shell. The control exists because system accounts are a common target in post-exploitation chains. An attacker who lands code execution as a service account looks first for a working /bin/bash, then for a sudoers entry, then for a way to pivot to a real user. Replacing the shell with /sbin/nologin removes that first step without changing how the underlying services run, because services invoke binaries directly and never request a login shell.
Encoding CIS 5.4.2 as a recurring Automox policy holds the locked-shell state in place on every workstation, every server, and every container host. A fresh Ubuntu install that ships a new system account during a package upgrade, a RHEL build host that picks up a daemon account from an EPEL package, and a long-running Debian container that has accumulated drift over six months all converge on the same locked, nologin-shelled state on the next evaluation. The remediation is idempotent, so subsequent runs produce no state changes unless a new account has been introduced since the previous pass.
Evaluation phase: The Worklet exits non-zero unconditionally so remediation always runs. This is the recommended pattern for usermod-driven hardening because checking the current state of every UID-below-1000 account costs roughly the same as applying the change, and the change is idempotent. If you prefer a check-only pass, pair the policy with a separate compliance Worklet that runs awk -F: '$3 < 1000 {print $1, $7}' /etc/passwd and flags any line whose seventh field is not /sbin/nologin.
Remediation phase: The script reads /etc/passwd through awk -F: '($3 < 1000) {print $1}' and iterates each username. For every account except root, it runs /usr/sbin/usermod -L <user> to lock the password. For every account except root, halt, sync, and shutdown, it also runs /usr/sbin/usermod -s /sbin/nologin <user> to set the login shell. The script outputs a single completion message and exits 0. Any usermod errors surface in the Automox activity log.
Linux endpoint with a standard /etc/passwd layout (RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu, openSUSE)
Root privileges for the Automox agent (the default agent context already meets this)
/sbin/nologin available on the endpoint – the script targets /sbin/nologin, which ships with shadow-utils or login on all supported distributions; on newer distributions the same binary may also appear at /usr/sbin/nologin
/usr/sbin/usermod available – part of the shadow-utils or passwd package on every supported distribution
Pre-deployment review: confirm no human users have been provisioned with UIDs below 1000 (a non-default choice on some legacy builds); locking those accounts will block their owners out
Confirm no services rely on a real shell for the account they run as – modern systemd units invoke ExecStart binaries directly and do not require an interactive shell, but a small number of legacy init scripts wrap commands through su - <serviceaccount> and will fail when the shell is replaced
After remediation, every account in /etc/passwd with a UID below 1000 – except root, halt, sync, and shutdown – has /sbin/nologin as its login shell and a locked password field in /etc/shadow. Verify with awk -F: '($3 < 1000) {print $1, $3, $7}' /etc/passwd, which lists each account, its UID, and its current shell. Run sudo passwd -S <account> to confirm the password status reports L (locked). Both checks complete in under a second on a typical endpoint and produce evidence suitable for a CIS 5.4.2 audit attachment.
Services running under the affected accounts continue to operate normally. Direct attempts to log in – via ssh daemon@host or su - mail – return the standard nologin message ("This account is currently not available.") and exit non-zero. Subsequent policy runs produce no state changes, because usermod recognises the target shell and lock state as already applied. Re-evaluation on an endpoint where a package install has added a new service account with a default shell will catch and correct that account on the next scheduled run.


Loading...
Consider Worklets your easy button
A Worklet is an automation script, written in Bash or PowerShell, designed for seamless execution on endpoints – at scale – within the Automox platform. Worklets deploy named-CVE mitigations within hours of disclosure, perform configuration, remediation, and install or remove applications and settings across Windows, macOS, and Linux.

AUTOMOX + WORKLETS™
Uncover new possibilities with simple, powerful automation.
By submitting this form you agree to our Master Services Agreement and Privacy Policy
By submitting this form you agree to our Master Services Agreement and Privacy Policy.
Already have an account? Log in