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, securityPackage hygiene
Last reviewed
Every installed package is code that can be exploited. Strip the unneeded and insecure ones, keep the rest patched automatically, and verify packages are signed and really on disk.
The threat: more packages, more CVEs, more cleartext
Every package you install is attack surface: more binaries, more listening services, more libraries with their own CVE stream. Two failures dominate. First, insecure legacy software that should never be on a modern host: the telnet, rsh, ftp, tftp and talk families speak unencrypted, cleartext protocols, so credentials and session data are trivially sniffed or tampered with on the wire; an rsh-server even authenticates by trust files (.rhosts), turning a network position into a privileged login. Second, unpatched packages: a known CVE in an installed component is a published exploit recipe, and a server that lags on security updates is breached with public tooling. Add supply-chain tampering (a backdoored or substituted package) and the installed set itself becomes the payload.
Why harden it
You cannot defend what you did not need to install. A removed package has zero CVEs, zero listeners, zero misconfigurations. Shrinking the package set is the cheapest, most durable risk reduction: it cuts the patch workload, removes whole classes of cleartext protocols, and eliminates dormant services an attacker could enable. What remains must be current (security updates applied promptly) and trustworthy (what's on disk matches what the distribution signed).
Defense principles applied
- Attack-surface reduction: uninstall packages with no business need, especially insecure servers/clients (
telnet/telnetd,rsh/rsh-server,ftp/vsftpd,tftp/tftp-server,talk/talkd,snmpd,xinetd,nis/ypserv). - Patch management: apply security updates promptly and automatically (
unattended-upgrades,dnf-automatic) so fixes land without manual effort. - Integrity and provenance: trust only signed packages from authorized repositories (GPG verification), and baseline binaries with file-integrity monitoring (
AIDE), so a tampered package is detected. - Least functionality: keep the security tooling (
audit,sudo,cron,openssh-server) and drop the rest. - Defense in depth: a service you removed can't be misconfigured, exposed, or exploited later.
How do you keep packages patched?
The goal is security updates, applied fast, unattended. Apply only security fixes, then automate them:
# Debian/Ubuntu: security-only, then automate
apt update && apt list --upgradable
unattended-upgrade --dry-run -d # preview what the security policy would install
apt install unattended-upgrades && dpkg-reconfigure -plow unattended-upgrades
# RHEL/Fedora: security-only, then automate
dnf updateinfo list security # which security advisories apply
dnf upgrade --security
dnf install dnf-automatic # set apply_updates=yes in /etc/dnf/automatic.conf
systemctl enable --now dnf-automatic.timerVerify package trust and patch state
# Is the repo signature actually enforced? (supply-chain integrity)
grep -R gpgcheck /etc/dnf/dnf.conf /etc/yum.repos.d/ # gpgcheck=1 everywhere (RHEL)
apt-config dump | grep -i AllowUnauthenticated # must stay 'false' (Debian)
# Is the automation running?
systemctl status unattended-upgrades dnf-automatic.timer
# Is the host behind, and does it need a reboot?
apt list --upgradable ; dnf updateinfo summary
[ -f /var/run/reboot-required ] && echo 'reboot required' ; needs-restarting -rWhat Pavois audits: the package manager's own database
Pavois drives over a hundred package rules through CINC/InSpec's package(...) resource, which queries the package manager's own database (dpkg/rpm), the real installed state, not a guess from a file listing. Each rule asserts a package should_not be_installed (insecure or unneeded) or should be_installed (security tooling). It checks the cleartext-protocol families are gone (telnet/telnetd, rsh/rsh-server, ftp/vsftpd, tftp/tftp-server, talk/talkd), along with unneeded servers (snmpd, xinetd, nis/ypserv, samba, dovecot, nginx/httpd, bind, dnsmasq, cups); and that defensive packages are present (aide, dnf-automatic/unattended-upgrades, audit, sudo, cron, openssh-server, the MAC stack). Because the assertion reads the package DB, the result reflects what is actually installed and runnable. Findings map to CIS package hygiene and ANSSI BP-028 R45/R67.
Pitfalls
--allow-unauthenticated/gpgcheck=0defeats the whole trust model: never disable signature verification to make an install work; fix the missing key instead.- Automatic updates without auto-reboot leave kernel CVEs live: a patched kernel only protects you after a reboot. Configure a reboot window (
Unattended-Upgrade::Automatic-Reboot). - Removing a package a service depends on breaks it: check reverse-dependencies (
apt rdepends,dnf repoquery --whatrequires) before purging. - Unattended upgrades can pull a breaking change: scope them to the security pocket, and stage in pre-production for critical hosts.
FAQ
How do I apply only security updates, not everything? dnf upgrade --security (RHEL) or unattended-upgrades scoped to the security pocket (Debian); dnf updateinfo list security / apt list --upgradable show what applies.
How do I know packages are genuine? GPG signature verification: keep gpgcheck=1 (dnf) and never pass --allow-unauthenticated (apt). apt-secure rejects unsigned repos by default.
Why does Pavois read dpkg/rpm instead of scanning files? Because the package database is the authoritative installed state; a binary left on disk or a half-removed package would mislead a file scan.