# yaml-language-server: $schema=../../../../schema/control.schema.json id: CB-UBU-AUTH-018 title: Prevent interactive logins to system accounts finding: title: A system account has a login shell or an unlocked password description: Service accounts are rarely watched; one that accepts logins is an easy way in or a quiet persistence point. status: active profiles: [core] risk: severity: medium assessment: automated tags: [accounts, service-accounts] description: | System accounts (UID below `UID_MIN`, 1000 on Ubuntu) run services and own files. They do not need to log in. Their shell must be `/usr/sbin/nologin` or `/bin/false`, and their password must be locked. `root`, `sync`, `shutdown` and `halt` are the exceptions. rationale: | A system account with a valid shell can be used to log in if it ever gets a password or an SSH key, and attackers like to add access to such accounts because nobody checks them. impact: | Services keep working: they do not use a login shell. Administrators who need a shell as a service account use `sudo -u -s /bin/bash`. notes: | Accounts are read from `/etc/passwd` only; network directories (LDAP, SSSD) are out of scope. audit: manual: | 1. `awk -F: '$3 < 1000 && $1 !~ /^(root|sync|shutdown|halt)$/ {print $1, $7}' /etc/passwd`: every shell must be `/usr/sbin/nologin`, `/sbin/nologin` or `/bin/false`. 2. Every account with such a non-login shell must show `L` with `passwd -S`. checks: - id: shells engine: shell description: System accounts with a login shell. spec: script: | bad=$(awk -F: '$3 < 1000 && $1 !~ /^(root|sync|shutdown|halt)$/ && $7 !~ /^(\/usr)?\/sbin\/nologin$|^\/bin\/false$/ {print $1 ":" $7}' /etc/passwd) echo "${bad:-none}" [ -z "$bad" ] - id: locked engine: shell description: Accounts without a login shell that are not locked. spec: script: | bad= for u in $(awk -F: '$1 != "root" && $7 ~ /nologin$|^\/bin\/false$/ {print $1}' /etc/passwd); do s=$(passwd -S "$u" 2>/dev/null | cut -d' ' -f2) [ "$s" = L ] || bad="$bad $u:$s" done echo "${bad:-none}" [ -z "$bad" ] remediation: manual: | 1. For each listed system account: `usermod -s /usr/sbin/nologin `. 2. For each account without a login shell that is not locked: `usermod -L `. effects: restart: none disruption: low lockout_risk: false rollback: | Restore `/etc/passwd` and `/etc/shadow` from the backup. scripts: - id: fix engine: shell content: | cb_backup /etc/passwd cb_backup /etc/shadow awk -F: '$3 < 1000 && $1 !~ /^(root|sync|shutdown|halt)$/ && $7 !~ /^(\/usr)?\/sbin\/nologin$|^\/bin\/false$/ {print $1}' /etc/passwd | while read -r u; do usermod -s /usr/sbin/nologin "$u"; done for u in $(awk -F: '$1 != "root" && $7 ~ /nologin$|^\/bin\/false$/ {print $1}' /etc/passwd); do [ "$(passwd -S "$u" | cut -d' ' -f2)" = L ] || usermod -L "$u" done references: - title: usermod(8), Ubuntu manual pages url: https://manpages.ubuntu.com/manpages/noble/man8/usermod.8.html publisher: Canonical kind: vendor-doc accessed: 2026-10-19 - title: ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R34) url: https://messervices.cyber.gouv.fr/documents-guides/fr_np_linux_configuration-v2.0.pdf publisher: ANSSI kind: guide accessed: 2026-10-19 mappings: - framework: anssi-linux framework_version: "2.0" id: R34 relation: equivalent - framework: nist-800-53r5 framework_version: "5.1.1" id: AC-2 relation: related - framework: cis-ubuntu-2004 framework_version: "3.0.0" id: "5.4.2.7" relation: equivalent - framework: cis-ubuntu-2004 framework_version: "3.0.0" id: "5.4.2.8" relation: equivalent - framework: cis-ubuntu-2204 framework_version: "3.0.0" id: "5.4.2.7" relation: equivalent - framework: cis-ubuntu-2204 framework_version: "3.0.0" id: "5.4.2.8" relation: equivalent - framework: cis-ubuntu-2404 framework_version: "2.0.0" id: "5.4.2.7" relation: equivalent - framework: cis-ubuntu-2404 framework_version: "2.0.0" id: "5.4.2.8" relation: equivalent - framework: cis-ubuntu-2604 framework_version: "1.0.0" id: "5.4.2.7" relation: equivalent - framework: cis-ubuntu-2604 framework_version: "1.0.0" id: "5.4.2.8" relation: equivalent threats: - framework: mitre-attack id: T1078.003 authors: - name: Alice github: Sn0wAlice verified: - date: 2026-10-19 by: Sn0wAlice versions: ["20.04"] environment: Proxmox VM, Ubuntu 20.04 cloud image, kernel 5.4.0-216-generic notes: "Passes on a fresh install; profiles core and server-hardened." - date: 2026-10-19 by: Sn0wAlice versions: ["22.04"] environment: Proxmox VM, Ubuntu 22.04 cloud image, kernel 5.15.0-198-generic notes: "Passes on a fresh install; profiles core and server-hardened." - date: 2026-10-19 by: Sn0wAlice versions: ["24.04"] environment: Proxmox VM, Ubuntu 24.04 cloud image, kernel 6.8.0-147-generic notes: "Passes on a fresh install; profiles core and server-hardened." - date: 2026-10-19 by: Sn0wAlice versions: ["26.04"] environment: Proxmox VM, Ubuntu 26.04 cloud image, kernel 7.0.0-38-generic notes: "Passes on a fresh install; profiles core and server-hardened." introduced_in: 0.1.0 created: 2026-10-19 updated: 2026-10-19