Debian GNU/Linux · Filesystem & permissions

Protect the user, group and password database files

When it fails: The account database files have weak ownership or permissions. Password hashes can be read for offline cracking, or account files can be changed to add a user or gain root.

CB-DEB-FS-007highactiveautomatedautomated fixprofile core

As released in v0.1.1 beta · pre-release. Current state.

Description

The files that define local accounts, and the backups that the shadow tools keep with a - suffix, have the Debian ownership and at most these modes:

FilesOwner:groupMaximum mode
/etc/passwd, /etc/passwd-, /etc/group, /etc/group-root:root644
/etc/shadow, /etc/shadow-, /etc/gshadow, /etc/gshadow-root:shadow640
/etc/shellsroot:root644
/etc/security/opasswd, /etc/security/opasswd.oldroot:root600

Files that do not exist are skipped.

Debian uses group shadow for shadow and gshadow, not root as on other distributions. Setting them to root:root breaks password checks by unix_chkpwd for non-root programs (screen lockers, some PAM services).

Rationale

passwd and group must stay readable by everyone for name lookups, but only root may change them: write access means creating a UID 0 account. shadow and gshadow hold password hashes; on Debian the shadow group lets unix_chkpwd and screen lockers check a password without being root, and nobody else may read them. opasswd holds the previous password hashes kept by pam_pwhistory. The - backups contain the same data as the live files.

Impact

None known: these are the Debian defaults, and the fix only removes extra access.

Setting

Location/etc/passwd, /etc/group, /etc/shadow, /etc/gshadow, /etc/shells, /etc/security/opasswd
DefaultCompliant on a fresh install
RecommendedSee the table in the description

Audit

Run stat -c '%n %U:%G %a' /etc/passwd* /etc/group* /etc/shadow* /etc/gshadow* /etc/shells /etc/security/opasswd* and compare each line with the table above.

Automated: every check must pass. Scanners report each check by its id.

passwd

/etc/passwd and its backup are root:root, mode 644 or stricter.

path: /etc/passwd*
owner: root
group: root
mode: '0644'

group

/etc/group and its backup are root:root, mode 644 or stricter.

path: /etc/group*
owner: root
group: root
mode: '0644'

shadow

/etc/shadow and its backup are root:shadow, mode 640 or stricter.

path: /etc/shadow*
owner: root
group: shadow
mode: '0640'

gshadow

/etc/gshadow and its backup are root:shadow, mode 640 or stricter.

path: /etc/gshadow*
owner: root
group: shadow
mode: '0640'

shells

/etc/shells is root:root, mode 644 or stricter.

path: /etc/shells
owner: root
group: root
mode: '0644'

opasswd

/etc/security/opasswd and its backup are root:root, mode 600 or stricter.

path: /etc/security/opasswd*
owner: root
group: root
mode: '0600'

Remediation

chown root:root /etc/passwd /etc/passwd- /etc/group /etc/group- /etc/shells
chmod u-x,go-wx /etc/passwd /etc/passwd- /etc/group /etc/group- /etc/shells
chown root:shadow /etc/shadow /etc/shadow- /etc/gshadow /etc/gshadow-
chmod u-x,g-wx,o-rwx /etc/shadow /etc/shadow- /etc/gshadow /etc/gshadow-
chown root:root /etc/security/opasswd*
chmod 600 /etc/security/opasswd*
Restartnone
Disruptionnone

Rollback

Not needed: the fix only restores the Debian ownership and removes extra permissions.

passwd

Generated from check passwd: the engine writes the fix for every output, it sets the expected value and the check runs again after.

group

Generated from check group: the engine writes the fix for every output, it sets the expected value and the check runs again after.

shadow

Generated from check shadow: the engine writes the fix for every output, it sets the expected value and the check runs again after.

gshadow

Generated from check gshadow: the engine writes the fix for every output, it sets the expected value and the check runs again after.

shells

Generated from check shells: the engine writes the fix for every output, it sets the expected value and the check runs again after.

opasswd

Generated from check opasswd: the engine writes the fix for every output, it sets the expected value and the check runs again after.

Each release turns these fixes into remediate.sh and an Ansible role per profile: dry run by default, a fix runs only when its check fails.

References

Mappings

FrameworkIDRelationNote
ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0R50partialR50 covers every sensitive file; this control covers the account databases.
NIST SP 800-53 Rev. 55.1.1AC-3related

How this control relates to the other framework's: equivalent, stricter, looser, partial or related.

Threats mitigated

People and lifecycle

Authors
Verified2026-10-18 by Sn0wAlice on 12, Proxmox VM 922, Debian 12 genericcloud image, kernel 6.1.0-54-cloud-amd64. Passes on fresh install (shadow and gshadow root:shadow 640); generated fixes report compliant.
Verified2026-10-18 by Sn0wAlice on 13, Proxmox VM 932, Debian 13 genericcloud image, kernel 6.12.113+deb13-cloud-amd64. Passes on fresh install (shadow and gshadow root:shadow 640); generated fixes report compliant.
Introduced inv0.1.0
Created, updated2026-10-18, 2026-10-18
Translationsfr