Apply CIS Benchmarks with OpenSCAP
Use OpenSCAP and scap-security-guide to evaluate, report on, and remediate Linux systems against CIS Benchmarks — covering install, eval, and automation.
Before you start
- ▸Root or sudo access on the target system
- ▸Internet access for initial package installation
- ▸A snapshot or backup of the system before running any remediation
- ▸Basic familiarity with systemd unit files and sshd configuration
The Center for Internet Security (CIS) Benchmarks are the closest thing the Linux world has to an industry-standard hardening checklist. OpenSCAP gives you an automated, auditable way to evaluate and remediate a system against those benchmarks without manual checklist grinding. This guide walks through installing the tooling, running evaluations, generating human-readable HTML reports, and applying targeted remediations — all from the command line.
What You Need
OpenSCAP consists of two main components: the oscap scanner binary (provided by openscap-scanner or openscap depending on the distro) and the SCAP Security Guide (SSG), which ships the actual XCCDF profiles and OVAL definitions for CIS, STIG, PCI-DSS, and others. You need both.
Install OpenSCAP and scap-security-guide
Debian / Ubuntu
sudo apt update
sudo apt install -y openscap-scanner ssg-debderived ssg-base
On Ubuntu 22.04+ the package ssg-ubuntu may also appear. Install it if available — it provides Ubuntu-specific profiles.
Fedora / RHEL 9 / Rocky / AlmaLinux
sudo dnf install -y openscap-scanner scap-security-guide
On RHEL 9 and clones you may need the openscap-utils package too if you want the oscap-chroot and container tooling.
Arch Linux
sudo pacman -S openscap scap-security-guide
The SSG package on Arch is maintained in the community repo; confirm the version covers your target profile before relying on it in production.
Locate the Correct Data Stream File
SSG ships XML data stream files — one per distro family — under /usr/share/xml/scap/ssg/content/. Each file bundles every available profile for that OS.
ls /usr/share/xml/scap/ssg/content/
You will see files like ssg-ubuntu2204-ds.xml, ssg-rhel9-ds.xml, or ssg-fedora-ds.xml. Use the one that matches your running OS.
List all profiles bundled in a data stream to find the right CIS level:
oscap info /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
Look for profile IDs containing cis. You will typically see at minimum xccdf_org.ssgproject.content_profile_cis (Level 2 Server) and xccdf_org.ssgproject.content_profile_cis_server_l1 (Level 1 Server). CIS Level 1 targets practical hardening with minimal service disruption; Level 2 is stricter and may impact functionality.
Run an Evaluation (Audit Mode)
Always run a full evaluation before any remediation so you have a baseline to compare against. This reads policy; it does not change the system.
Ubuntu example
sudo oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_cis_level1_server \
--results /var/log/oscap/cis-results.xml \
--report /var/log/oscap/cis-report.html \
/usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xml
RHEL 9 / Rocky / AlmaLinux example
sudo mkdir -p /var/log/oscap
sudo oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_cis \
--results /var/log/oscap/cis-results.xml \
--report /var/log/oscap/cis-report.html \
/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
The scan runs several hundred rules and can take 2–5 minutes. Exit code 0 means the scan completed; exit code 2 means at least one rule returned a fail or error — this is normal on a fresh system.
Read the HTML Report
Open /var/log/oscap/cis-report.html in a browser. Each rule shows a pass/fail/notapplicable status, a severity rating, a description of the required setting, and — crucially — a remediation snippet. The summary at the top gives you a compliance percentage score.
Pay attention to rules marked notchecked: these require manual review because OVAL cannot automate the verification (for example, physical access controls or organisational policies).
Generate a Remediation Script
Rather than applying changes blindly via oscap's live remediation, generating a Bash script first lets you review exactly what will change before touching the system. This is the recommended approach for production.
sudo oscap xccdf generate fix \
--profile xccdf_org.ssgproject.content_profile_cis \
--fix-type bash \
--result-id "" \
--output /var/log/oscap/cis-remediation.sh \
/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
Review the script before running it. Many rules touch sshd_config, PAM, kernel parameters via sysctl, and audit daemon settings. Read each section and comment out anything incompatible with your environment — for example, USB storage disable rules on a workstation, or NFS-related rules on a host that legitimately uses NFS.
Apply Live Remediation
If you prefer to let oscap apply fixes directly — acceptable on a freshly provisioned host or a staging VM — use the --remediate flag. Take a snapshot or backup first.
sudo oscap xccdf eval \
--remediate \
--profile xccdf_org.ssgproject.content_profile_cis \
--results /var/log/oscap/cis-remediation-results.xml \
--report /var/log/oscap/cis-remediation-report.html \
/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
Some rules require a reboot to take effect (kernel parameters, bootloader hardening). Re-run the evaluation after rebooting to confirm the rule now passes.
Re-evaluate and Compare
After remediation, run another evaluation and compare the HTML reports. Your pass rate should improve significantly, though a score of 100% is rarely achievable without accepting operational trade-offs.
sudo oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_cis \
--results /var/log/oscap/cis-results-post.xml \
--report /var/log/oscap/cis-report-post.html \
/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
To compare result XML files programmatically, use oscap xccdf diff if available, or diff the two HTML reports side by side in a browser.
Automate Periodic Scans with systemd
Running oscap from a systemd timer keeps compliance drift visible without manual effort.
sudo tee /etc/systemd/system/oscap-cis.service <<'EOF'
[Unit]
Description=OpenSCAP CIS Benchmark Scan
[Service]
Type=oneshot
ExecStart=/usr/bin/oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_cis \
--results /var/log/oscap/cis-results-latest.xml \
--report /var/log/oscap/cis-report-latest.html \
/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
EOF
sudo tee /etc/systemd/system/oscap-cis.timer <<'EOF'
[Unit]
Description=Weekly OpenSCAP CIS Scan
[Timer]
OnCalendar=Mon *-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now oscap-cis.timer
sudo systemctl list-timers oscap-cis.timer
Troubleshooting
- Profile not found: The profile ID varies by SSG version and distro. Always run
oscap info <datastream>and copy the exact profile ID from its output. - Scan exits with errors on specific rules: Rules may return
errorwhen a required package isn't installed (e.g., an audit rule foraidewhen AIDE isn't present). Install prerequisites or mark the rule asnotapplicablevia a tailoring file. - Remediation breaks SSH access: CIS rules often set
PermitRootLogin noand restrict ciphers. Ensure you have a non-root sudo user and a console fallback before remediating remotely. - Old SSG version lacks CIS profiles: On older Ubuntu LTS versions, SSG may only ship STIG profiles. Upgrade SSG from upstream: github.com/ComplianceAsCode/content/releases publishes pre-built data streams.
- Report file is empty: The output directory must exist before running oscap. Create it with
mkdir -p /var/log/oscap.
Frequently asked questions
- What is the difference between CIS Level 1 and Level 2 profiles in SSG?
- Level 1 covers foundational hardening settings that have minimal impact on usability and service availability. Level 2 adds stricter controls — such as disabling more kernel modules and tightening audit rules — that may break functionality if applied without review. Use Level 1 as a starting point and promote to Level 2 only after testing.
- Can I customise which rules are applied without editing the SSG XML directly?
- Yes. OpenSCAP supports XCCDF tailoring files that let you enable, disable, or change rule values without touching the upstream data stream. Use oscap xccdf generate tailoring or the SCAP Workbench GUI to build a tailoring file, then pass it to oscap with the --tailoring-file flag.
- Will running oscap --remediate on a live server cause downtime?
- Potentially, yes. Rules that restart sshd, modify PAM stacks, or alter firewall rules can interrupt active sessions. Always test remediation on an identical staging system first, and have out-of-band console access when remediating production systems.
- How do I scan a container image or chroot rather than the running host?
- Use oscap-chroot for chroot environments or oscap-podman / oscap-docker for container images. These wrappers mount the target filesystem and run OVAL checks against it without executing the container, which is useful in CI/CD pipelines.
- My RHEL 9 clone (Rocky, Alma) shows many rules as 'notapplicable' — is that normal?
- Some rules check for RHEL-specific packages or subscription-manager metadata that clones don't provide. This is expected. Review notapplicable rules manually to determine whether the underlying intent of the control is still met on your system.
Related guides
Manage Secrets with Ansible Vault
Encrypt Ansible secrets with AES-256 using ansible-vault: encrypt files and inline vars, automate with password files, and isolate group-level secrets with vault IDs.
AppArmor Explained
Learn how AppArmor profiles work, how to switch between enforce and complain mode, create new profiles, and diagnose access denials on Ubuntu, Debian, and Arch.
How to Audit a Linux System with auditd
Set up auditd on Linux to track file access, syscalls, and privilege use. Covers persistent rules, file watches, ausearch, and aureport across major distros.
How to Audit Linux Hardening with Lynis
Run Lynis to audit your Linux server, interpret the hardening index and warning output, and work through findings from critical to low-effort wins.