Handbook sections▾
Foundations
Understanding the threats to a Linux hostWhy we hardenThe defense principles behind every ruleEffective configuration: the truth no file holdsThe standards Pavois maps toSOCLE control ID modelEvidence & exportsHow the A-E grade is computedWhat a PASS proves: the qualified verdictTrust model for the evidence bundleIs SOCLE just your own norm? (governance & the circularity question)What Pavois covers, and what it doesn'tDomains
Hardening SSHHardening PAMMandatory Access Control (SELinux / AppArmor)Hardening the host firewallHardening sudoFile Permissions & OwnershipMount & filesystem hardeningHardening kernel modulesHardening the kernel & network with sysctlAudit logging with auditdHardening logging with journald and rsyslogHardening systemd servicesPackage hygieneHardening the bootloader (GRUB)Synchronizing timeLogin banners and MOTDControlling cron and at accessHardening the GNOME desktop (dconf)Tooling
Undo a hardening run: restore pointsOperating Pavois: privileges, air-gap, timing, exceptionsRun Pavois in CI (GitHub Actions)Feature status: delivered, partial, roadmapGovernance: licence, versioning, provenance, securityHardening logging with journald and rsyslog
Last reviewed
Logs are the black box of a server. Make them persistent, tamper-evident and shipped off-box so an incident can be reconstructed after the fact.
The threat: logs are attacked precisely because they hold the proof
Logs are where an intrusion leaves its footprints, and that is exactly why they are attacked. An adversary who lands on a host quickly turns to anti-forensics: wiping /var/log/journal, truncating syslog files, or simply triggering a reboot when the journal lives only in volatile memory. Worse, the danger is often silence: with default Storage=auto, journals can sit in /run and vanish at the next boot; an uncapped journal can fill the log partition, after which journald drops new records and the evidence of the attack in progress is never written. If logs are stored only locally, the same root access that let the attacker in lets them edit or delete the proof. Without trustworthy logs, an incident becomes unprovable.
Why harden it
Logging is the one control whose value is realised after the breach. Every other defense aims to stop the attacker; logging assumes one eventually gets through and asks: can we reconstruct the timeline? Hardening the pipeline guarantees the answer is yes: records survive reboots, the partition does not silently fill, tampering is detectable, and a copy lives somewhere the local attacker cannot reach.
Defense principles applied
- Persistence:
Storage=persistentwrites journals to/var/log/journalso they outlive crashes, power loss and reboots, instead of evaporating from/run. - Availability of the log channel:
Compress=yesplus retention caps (SystemMaxUse=,SystemKeepFree=,MaxRetentionSec=) stretch history within the disk budget and stop a full partition silently dropping records.RateLimitIntervalSec/RateLimitBurstblunt a log-flood DoS, but set them generously so real security events are never dropped. - Single, deliberate pipeline:
ForwardToSyslog=noavoids blind double-writing; centralized shipping is configured explicitly (an rsyslog@@remoterule orsystemd-journal-upload). - Integrity off-box: forward to a remote collector / SIEM so logs exist beyond the reach of local root.
- Accountability: pull the kernel audit trail into the journal with
Audit=yes, and keep a complete time-ordered record.
How do you make logs tamper-evident? Forward Secure Sealing
A local attacker with root can edit journal files. Forward Secure Sealing (FSS) makes that detectable: journald periodically seals the journal with an evolving key, so any retroactive edit breaks the seal. Generate the key pair once, enable sealing, and verify on demand:
journalctl --setup-keys # generate the sealing key + a verification key (store the latter off-box)
# set Seal=yes in journald.conf, then:
systemctl restart systemd-journald
journalctl --verify # PASS, or reports the first tampered/garbled entryFSS detects tampering; it does not prevent it. Pair it with off-box shipping so you also retain an untampered copy.
What Pavois audits: the effective journald configuration
Pavois audits the effective journald configuration the way the daemon resolves it. Because journald merges its drop-in directory /etc/systemd/journald.conf.d/ over the base /etc/systemd/journald.conf, Pavois greps both, so a base file overridden by a drop-in is read as the value that actually applies, where a single-file scan (OVAL/oscap) would report the wrong state. Its Logging (journald) rules check Storage=persistent (journald-storage), Compress=yes (journald-compress), and ForwardToSyslog=no (journald-forwardtosyslog). These map to the CIS journald benchmarks and ANSSI BP-028 R71, and pavois harden apply can write a single drop-in (/etc/systemd/journald.conf.d/99-Pavois.conf) satisfying all three, followed by systemctl restart systemd-journald.
Verify
journalctl --disk-usage # how much the journal occupies vs the cap
journalctl --list-boots # persistent history across reboots
journalctl --verify # FSS integrity check
systemd-analyze cat-config systemd/journald.conf # the merged effective config
journalctl -k -b -1 # last boot's kernel log, proving persistencePitfalls
Storage=autois not persistence: it only persists if/var/log/journalalready exists. UseStorage=persistent(or create the directory).- Aggressive
RateLimitBurstdrops security events: a brute-force or scan can be silenced by your own rate limit. Tune it high for security-relevant units. - FSS detects, never prevents: it tells you logs were altered after the fact; only off-box shipping preserves an intact copy.
- A reboot rotates but does not delete: don't confuse
--list-bootsseparation with log loss.
FAQ
How do I prove the logs weren't altered? Enable Forward Secure Sealing (journalctl --setup-keys, Seal=yes) and run journalctl --verify; a broken seal pinpoints the first tampered entry.
Why ForwardToSyslog=no if I want central logging? Because blind forwarding double-writes everything; configure shipping explicitly (rsyslog @@remote or systemd-journal-upload) so there is one authoritative, intentional pipeline.
Why does Pavois read both journald.conf and the drop-in dir? Because the daemon merges them; a drop-in can override the base, so only the merged result is the truth.