System Hardening
CIS Benchmark
Auditing a host against the CIS benchmark with Lynis and OpenSCAP.
The previous pages applied controls one at a time. At some point you need to know, objectively, how a host stacks up against a recognized standard, and where the gaps are. That is what a benchmark gives you: a curated, versioned list of hardening controls with a way to test each one automatically. Benchmarks turn “I think this box is hardened” into a report you can read, compare over time, and hand to an auditor.
The Center for Internet Security (CIS) publishes the most widely used Linux benchmarks. This page explains what they cover, how to run two practical auditing tools against a host, and, most importantly, how to prioritize findings instead of chasing a perfect score.
What the CIS Linux benchmarks cover
A CIS benchmark is a document (hundreds of pages for a full Linux profile) organized into sections that mirror how you would harden a host from the ground up. Each control has a rationale, an audit procedure, and a remediation step.
| Section | Example controls |
|---|---|
| Initial setup | Filesystem module blacklisting, partition mount options, GRUB password |
| Services | Disable unused daemons, remove legacy servers, time sync |
| Network | sysctl hardening, firewall rules, disable IP forwarding |
| Logging and auditing | journald persistence, auditd rules, log permissions |
| Access and authentication | PAM policy, sudo config, SSH hardening, password quality |
| System maintenance | File permissions, no world-writable files, user and group hygiene |
Controls come in two levels. Level 1 is a baseline that should not break normal use. Level 2 is stricter, aimed at high-security environments, and more likely to affect functionality. Many controls overlap directly with earlier pages: the module blacklisting is the same as in Boot & Kernel Hardening, and the auditing section is what Auditd configures.
Running Lynis
Lynis is a lightweight, script-based auditing tool that runs on the host with no agent and no license. It is the fastest way to get a hardening picture and maps many of its tests to CIS controls. Install and run it against the local system.
sudo apt-get install -y lynis
sudo lynis audit system --quick 2>&1 | tail -n 14
Expected output:
Lynis security scan details:
Hardening index : 64 [############ ]
Tests performed : 257
Plugins enabled : 0
Suggestions:
- Consider hardening SSH configuration [SSH-7408]
- Harden the system by removing unneeded compilers [HRDN-7222]
- Enable auditd to collect audit information [ACCT-9628]
Lynis report saved to /var/log/lynis-report.dat
The report file holds the machine-readable detail. Pull the suggestions with their control IDs so you can look each one up in the Lynis documentation.
sudo grep 'suggestion\[\]' /var/log/lynis-report.dat | head -n 5
Expected output:
suggestion[]=SSH-7408|Consider hardening SSH configuration|
suggestion[]=ACCT-9628|Enable auditd to collect audit information|
suggestion[]=HRDN-7222|Harden the system by removing unneeded compilers|
suggestion[]=KRNL-6000|One or more sysctl values differ from the scan profile|
suggestion[]=FILE-6310|Consider mounting /tmp with noexec|
Running OpenSCAP
For a formal, standards-based audit, OpenSCAP evaluates a host against SCAP content, and the ssg (SCAP Security Guide) package ships CIS-aligned profiles for Ubuntu. It produces a detailed HTML report suitable for compliance evidence.
sudo apt-get install -y libopenscap8 ssg-debderived
sudo oscap xccdf eval --profile cis_level1_server \
--results scan.xml --report report.html \
/usr/share/xml/scap/ssg/content/ssg-ubuntu2404-ds.xml 2>&1 | grep -E 'Rule|Result' | head -n 8
Expected output:
Title Ensure permissions on /etc/shadow are configured
Rule xccdf_org.ssgproject.content_rule_file_permissions_etc_shadow
Result pass
Title Ensure GDM is removed or disabled
Rule xccdf_org.ssgproject.content_rule_package_gdm_removed
Result fail
The generated report.html renders every rule with pass or fail, its severity, and the remediation. This is the artifact you keep as a point-in-time record.
Prioritizing findings over the score
The hardening index and the pass percentage are seductive because they are single numbers, but chasing them is how people waste time and break systems. A better approach weighs each finding by impact and effort:
- Fix high-severity findings that map to a real attack path first: an open service, weak SSH config, missing
auditd, world-writable files. - Apply low-risk, high-coverage items next: the
sysctlset, module blacklisting, log permissions. These move the score a lot for little risk. - Defer or accept Level 2 items that would break your workload. Documenting an accepted exception is a legitimate outcome; forcing
noexecon/tmpwhen a build tool needs it is not.
A host at index 64 with every genuine attack path closed is in better shape than one at 90 that ran a remediation script blindly and now has a broken package manager. The benchmark is a map of gaps, not a leaderboard.
sudo grep -c 'warning\[\]' /var/log/lynis-report.dat
Expected output:
3
Warnings (as opposed to suggestions) are the findings to triage first, since Lynis reserves them for higher-impact issues.
Practical Guidance
- Run Lynis first for a fast, agentless picture, then OpenSCAP with a CIS profile when you need a formal, comparable report.
- Triage warnings before suggestions, and rank suggestions by attack-path impact rather than by how much they move the score.
- Apply low-risk, high-coverage items (
sysctl, module blacklisting, file permissions) broadly, since they overlap with Boot & Kernel Hardening and cost little. - Test Level 2 controls on the lab VM before production, and formally document any control you accept as an exception.
- Re-run the same tool with the same profile after changes to confirm findings actually closed and nothing regressed.
- Keep the OpenSCAP HTML report as point-in-time evidence and diff scans over time to catch configuration drift.