Description
Every regular file under /var/log/, including the journal files in /var/log/journal/, must
have no permission for other users, no write permission for its group and no execute bit
(mode 0640 or stricter).
Two exceptions:
- the session records
wtmp,btmpandlastlog(and their rotated copies) must stay writable by theutmpgroup, andwtmpandlastlogreadable by everyone forlastandlastlogto work: for them only execute bits and writes by other users are forbidden (mode0664or stricter); - the package manager logs in
/var/log/apt/, which apt recreates readable by everyone at each run, may be0644; - the files matching
tolerated_0644(by defaultdpkg.log*andalternatives.log*, which logrotate recreates withcreate 0644) may be0644too. They must never be writable by group or others.
journald creates its files with mode 0640 (set in /usr/lib/tmpfiles.d/systemd.conf), and
rsyslog with $FileCreateMode (CB-DEB-AUDIT-005).
On a fresh Debian 12 or 13 cloud image, dpkg.log, faillog and, on Debian 12,
cloud-init.log are 0644. A file recreated by its program or by logrotate with a
create 0644 directive goes back to the wider mode until the fix runs again: list such files
in tolerated_0644, or change the create mode in /etc/logrotate.d/.
Rationale
Logs record failed logins (sometimes with a password typed in the user name field), source addresses, commands and application data. Readable logs help an attacker map the system; writable logs let them erase or forge their traces.
Impact
Users who are not in the adm group can no longer read files such as /var/log/cloud-init.log.
Grant access with group membership (adm) instead of wider modes.
Setting
| Location | /var/log/ |
| Default | Several files 0644 |
| Recommended | 0640 or stricter; 0664 for wtmp, btmp and lastlog; 0644 in /var/log/apt and for {{ tolerated_0644 }} |
Parameters
| Parameter | Core | Server | Server hardened | Desktop | Desktop hardened | Bounds |
|---|---|---|---|---|---|---|
tolerated_0644list. File name patterns under /var/log allowed to be 0644 (never group or world writable). | dpkg.log*, alternatives.log* | dpkg.log*, alternatives.log* | dpkg.log*, alternatives.log* | dpkg.log*, alternatives.log* | dpkg.log*, alternatives.log* |
The value used is your override (tailoring file), else the profile's, else the one of the profile it extends, else the default. Bounds limit what an override may set.
Audit
Run, as root:
find /var/log -type f ! -path '/var/log/apt/*' ! -name 'wtmp*' ! -name 'btmp*' ! -name 'lastlog*' -perm /0137 -ls
find /var/log -type f \( -name 'wtmp*' -o -name 'btmp*' -o -name 'lastlog*' \) -perm /0113 -ls
find /var/log/apt -type f -perm /0133 -ls
The commands must print nothing, except files matching {{ tolerated_0644 }} reported by the
first command with mode 0644 (they must not be writable by group or others).
Automated: every check must pass. Scanners report each check by its id.
var-log
Files under /var/log with more access than allowed.
script: |
[ -d /var/log ] || exit 2
set -f
ex= tol=
for p in $CB_TOLERATED_0644; do ex="$ex ! -name $p"; tol="$tol -o -name $p"; done
bad=$( { find /var/log -type f ! -path '/var/log/apt/*' ! -name 'wtmp*' ! -name 'btmp*' ! -name 'lastlog*' $ex -perm /0137
find /var/log -type f \( -name 'wtmp*' -o -name 'btmp*' -o -name 'lastlog*' \) -perm /0113
find /var/log/apt -type f -perm /0133
[ -z "$tol" ] || find /var/log -type f \( ${tol# -o } \) -perm /0133; } 2>/dev/null)
set +f
if [ -n "$bad" ]; then
printf '%s\n' "$bad" | while IFS= read -r f; do stat -c '%n %a' "$f"; done
exit 1
fi
echo "no log file under /var/log is more permissive than allowed"
Remediation
Run, as root:
find /var/log -type f ! -path '/var/log/apt/*' ! -name 'wtmp*' ! -name 'btmp*' ! -name 'lastlog*' -perm /0137 -exec chmod u-x,g-wx,o-rwx {} +
find /var/log -type f \( -name 'wtmp*' -o -name 'btmp*' -o -name 'lastlog*' \) -perm /0113 -exec chmod u-x,g-x,o-wx {} +
find /var/log/apt -type f -perm /0133 -exec chmod u-x,g-wx,o-wx {} +
For files rotated by logrotate, also change the create mode in the matching
/etc/logrotate.d/ file.
| Restart | none |
| Disruption | low |
Rollback
Run chmod 644 on the files that need to be readable by everyone again.
chmod
set -f
ex= tol=
for p in $CB_TOLERATED_0644; do ex="$ex ! -name $p"; tol="$tol -o -name $p"; done
find /var/log -type f ! -path '/var/log/apt/*' ! -name 'wtmp*' ! -name 'btmp*' ! -name 'lastlog*' $ex -perm /0137 -exec chmod u-x,g-wx,o-rwx {} +
find /var/log -type f \( -name 'wtmp*' -o -name 'btmp*' -o -name 'lastlog*' \) -perm /0113 -exec chmod u-x,g-x,o-wx {} +
find /var/log/apt -type f -perm /0133 -exec chmod u-x,g-wx,o-wx {} +
[ -z "$tol" ] || find /var/log -type f \( ${tol# -o } \) -perm /0133 -exec chmod u-x,g-wx,o-wx {} +
set +f
Handwritten code reads parameters from CB_<NAME> environment variables. 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
- tmpfiles.d(5), Debian manual pages Debian, vendor-doc, accessed 2026-10-18
- logrotate(8), Debian manual pages Debian, vendor-doc, accessed 2026-10-18
- ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R71) ANSSI, guide, accessed 2026-10-18
Mappings
| Framework | ID | Relation | Note |
|---|---|---|---|
| ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0 | R71 | partial | R71 asks for protected logs; this control covers local file permissions. |
| NIST SP 800-53 Rev. 55.1.1 | AU-9 | related |
How this control relates to the other framework's: equivalent, stricter, looser, partial or related.
Threats mitigated
People and lifecycle
| Authors |
|
| Verified | 2026-10-18 by Sn0wAlice on 12, Proxmox VM, Debian 12 genericcloud image, kernel 6.1.0-54-cloud-amd64, BIOS boot. Fails on fresh install (dpkg.log, faillog, cloud-init.log 0644); fix restricts them; passes after AIDE install and reboot. |
| Verified | 2026-10-18 by Sn0wAlice on 13, Proxmox VM, Debian 13 genericcloud image, kernel 6.12.113+deb13-cloud-amd64, BIOS boot. Fails on fresh install (dpkg.log 0644); fix restricts it; passes after AIDE install and reboot. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-18, 2026-10-18 |
| Translations | fr |