← All rules
SOCLE-CLD-GEN-044// Hardening (misc)mediumpersistent config

Ensure nologin Shell is Not Listed in /etc/shells

Ensures nologin and /bin/false are not listed in /etc/shells, so they remain true non-login shells.

Checked against the content of a persistent configuration file, the source of truth that survives reboots.

A pass proves? running now✓ on disk✓ survives rebootthe qualified verdict →
Debian 12CIS 1.1.0Debian 13CIS 1.0.0FedoraRHEL 10 / Rocky 10 / AlmaLinux 10RHEL 8 / Rocky 8 / AlmaLinux 8CIS 4.0.0RHEL 9 / Rocky 9 / AlmaLinux 9CIS 2.0.0Ubuntu 22.04CIS 3.0.0Ubuntu 24.04CIS 1.0.0Ubuntu 26.04
One check, maps to 1 standard

A mapping is a cross-reference to where each standard places this requirement, anchored and cross-validated, not a claim of equivalence. A passing check is evidence toward these references, how to read it.

Why this rule matters

/etc/shells is the list of valid login shells, consulted by programs such as chsh, FTP daemons and various PAM modules to decide whether an account is a real interactive user. nologin and /bin/false are deliberately non-login shells assigned to service/system accounts to deny them a session. Listing them in /etc/shells declares them valid login shells, which can re-enable interactive access (e.g. via FTP or chsh) for accounts that were meant to have none. They must be absent from the file.

What Pavois checks

Pavois greps the live /etc/shells for any nologin or /bin/false entry and expects none. This file is itself the effective source of truth consulted by chsh/FTP/PAM, so inspecting it directly reflects exactly what those programs will accept as a valid login shell.

describe command('grep -qE \'nologin|/bin/false\' /etc/shells 2>/dev/null && echo ko || echo ok') do
  its('stdout.strip') { should eq 'ok' }
end

How to verify it is applied

Confirm neither non-login shell is listed:

  • grep -E 'nologin|/bin/false' /etc/shells, expected output is empty (no match).
  • cat /etc/shells, should list only real interactive shells such as /bin/bash, /bin/sh, /usr/bin/zsh.

Inspect & investigate

Changes to login-shell configuration leave traces:

  • grep -E 'chsh|shells' /var/log/auth.log (Debian/Ubuntu) / /var/log/secure (RHEL), shows chsh invocations that read /etc/shells.
  • cat /etc/shells is the authoritative current-state view of accepted login shells.

Remediation

No automated harden plan is defined for this rule yet, so it must be applied manually: edit /etc/shells and remove any line referencing nologin or /bin/false. Removing them from the valid shells list does not change which shell each account actually uses (that stays in /etc/passwd); it only stops those non-login shells from being treated as valid login shells.

Pavois applies this with its own harden engine, the plan below, not a shell script:

commandsed -ri '\#(nologin|/bin/false)#d' /etc/shells
namestrip-nologin-from-shells
not_if! grep -qE 'nologin|/bin/false' /etc/shells
resourceexec
pavois harden plan local

where the target is local, a user@host SSH alias, or a container , Docs

Impact & precautions

Risk if not applied: service accounts assigned nologin//bin/false may regain interactive access through programs that gate on /etc/shells (FTP, chsh).

Precautions before applying: removing these entries is low-risk and does not affect existing logins of real users. Just confirm no in-house tooling explicitly requires nologin to be present in /etc/shells (rare). After the change, verify service accounts still cannot open an interactive session.

Standards mapping

StandardReferenceTypeVersionConfidence
CIS5.4.3.1directper OS, see the benchmark tablehigh

Each reference is a cross-reference anchored in the upstream benchmark and cross-validated against the SCAP Security Guide and ansible-lockdown, not a claim of equivalence. Direct = a prescriptive, line-level requirement; supporting = an abstract control family (NIST) the check provides evidence toward. How to read a mapping.

Sources & references