Security compliance scanning is no longer optional. Whether you're running Oracle Linux 10 for database workloads, web services, or cloud infrastructure, regulatory frameworks like PCI-DSS, HIPAA, and DISA STIG require demonstrable, auditable compliance evidence. OpenSCAP is the industry-standard open-source framework that makes this possible — and on Oracle Linux 10, it ships with official SCAP Security Guide (SSG) content maintained by the Oracle team.
This guide walks you through everything: installing the toolchain, understanding SCAP content structure, running profile-specific scans, interpreting results, applying automated remediation, and scheduling continuous compliance reporting.
SCAP (Security Content Automation Protocol) is a NIST standard (SP 800-126) for expressing security configuration requirements in machine-readable form. OpenSCAP is the reference open-source implementation. It provides both the scanning engine (oscap) and the tooling to process XCCDF, OVAL, and DataStream content.
Key SCAP terminology
| Term | What it is | File extension |
|---|
| XCCDF | Extensible Configuration Checklist Description Format — defines rules, groups, and profiles | .xml |
| OVAL | Open Vulnerability and Assessment Language — machine-readable check definitions | .xml |
| DataStream | Single bundled file containing XCCDF + OVAL + CPE dictionary + remediation scripts | -ds.xml |
| Profile | A named subset of rules from an XCCDF benchmark (e.g. CIS Level 2) | — |
| SSG | SCAP Security Guide — the upstream project producing all official content | package |
| ARF | Asset Reporting Format — structured XML results container for auditors | -arf.xml |
02 Installing the OpenSCAP Toolchain
Oracle Linux 10 ships OpenSCAP and the SCAP Security Guide in the standard AppStream and BaseOS repositories. No additional repos are needed.
Install all required packages
dnf update -y dnf install -y openscap-scanner dnf install -y scap-security-guide dnf install -y scap-workbench oscap --version
OpenSCAP command line tool (oscap) 1.3.10Copyright 2009--2024 Red Hat Inc., Durham, North Carolina....and othersCompiled with: OpenSSL-3.2.1, libxml2-2.12.5, libxslt-1.1.39, libcurl-8.6.0,pcre2-10.43, GConfPlatform : x86_64CPE : cpe:/o:oracle:oracle_linux:10
ls /usr/share/xml/scap/ssg/content/ | grep ol10
ssg-ol10-ds.xmlssg-ol10-xccdf.xmlssg-ol10-oval.xmlssg-ol10-cpe-oval.xmlssg-ol10-cpe-dictionary.xmlssg-ol10-ocil.xml
๐ก
Always use the DataStream (-ds.xml)
Use ssg-ol10-ds.xml for all scanning operations. It is a single self-contained SCAP 1.3 DataStream file that bundles XCCDF rules, OVAL checks, CPE dictionaries, and Bash/Ansible remediation scripts together. The individual component files exist for legacy tooling only.
03 Listing Available Profiles
Before running a scan, discover which security profiles are bundled in the OL10 content. Each profile maps to a specific regulatory framework or hardening standard.
oscap info \ /usr/share/xml/scap/ssg/content/ssg-ol10-ds.xml \ | grep "Id\|Title" | head -40
Profiles:Id: xccdf_org.ssgproject.content_profile_cisTitle: CIS Oracle Linux 10 Benchmark Level 1 - ServerId: xccdf_org.ssgproject.content_profile_cis_server_l2Title: CIS Oracle Linux 10 Benchmark Level 2 - ServerId: xccdf_org.ssgproject.content_profile_cis_workstation_l1Title: CIS Oracle Linux 10 Benchmark Level 1 - WorkstationId: xccdf_org.ssgproject.content_profile_stigTitle: DISA STIG for Oracle Linux 10Id: xccdf_org.ssgproject.content_profile_pci-dssTitle: PCI-DSS v3.2.1 Oracle Linux 10Id: xccdf_org.ssgproject.content_profile_hipaaTitle: Health Insurance Portability and Accountability Act (HIPAA)Id: xccdf_org.ssgproject.content_profile_standardTitle: Standard System Security Profile
Profile quick reference
๐ต
cis / cis_server_l2
CIS Oracle Linux 10 Benchmark
Most widely adopted hardening standard. L1 is low-disruption; L2 adds stricter controls. Ideal starting point for any production server.
Level 1 / Level 2๐ด
stig
DISA Security Technical Implementation Guide
US Department of Defense standard. Strictest commonly used profile — required for US federal and DoD environments. Can be disruptive without testing.
High Assurance๐ณ
pci-dss
PCI Data Security Standard v3.2.1
Required for systems that store, process, or transmit cardholder data. Focuses on network, access control, and audit logging requirements.
Mandatory (retail/finance)๐ฅ
hipaa
Health Insurance Portability & Accountability Act
Required for systems handling protected health information (PHI). Emphasizes access control, audit controls, and data integrity.
Healthcare04 Running Your First Scan
The oscap xccdf eval command is the workhorse of OpenSCAP. Here are the complete examples for each major use case.
CIS Level 1 Server scan
mkdir -p /var/log/scap/$(date +%Y-%m) oscap xccdf eval \ --profile xccdf_org.ssgproject.content_profile_cis \ --results /var/log/scap/$(date +%Y-%m)/cis-l1-results.xml \ --report /var/log/scap/$(date +%Y-%m)/cis-l1-report.html \ --fetch-remote-resources \ /usr/share/xml/scap/ssg/content/ssg-ol10-ds.xml
CIS Level 2 Server scan (stricter)
oscap xccdf eval \ --profile xccdf_org.ssgproject.content_profile_cis_server_l2 \ --results /var/log/scap/$(date +%Y-%m)/cis-l2-results.xml \ --report /var/log/scap/$(date +%Y-%m)/cis-l2-report.html \ --oval-results \ --verbose WARNING \ /usr/share/xml/scap/ssg/content/ssg-ol10-ds.xml
DISA STIG scan
oscap xccdf eval \ --profile xccdf_org.ssgproject.content_profile_stig \ --results-arf /var/log/scap/$(date +%Y-%m)/stig-arf.xml \ --results /var/log/scap/$(date +%Y-%m)/stig-results.xml \ --report /var/log/scap/$(date +%Y-%m)/stig-report.html \ /usr/share/xml/scap/ssg/content/ssg-ol10-ds.xml xmllint --noout /var/log/scap/$(date +%Y-%m)/stig-arf.xml && echo "Valid XML"
PCI-DSS scan
oscap xccdf eval \ --profile xccdf_org.ssgproject.content_profile_pci-dss \ --results /var/log/scap/$(date +%Y-%m)/pci-results.xml \ --report /var/log/scap/$(date +%Y-%m)/pci-report.html \ --oval-results \ /usr/share/xml/scap/ssg/content/ssg-ol10-ds.xml
⚠️
Scan Duration
A full STIG scan evaluates 300+ rules and can take 3–8 minutes depending on system resources. Run scans during maintenance windows on production systems, or use --rule to target specific rule IDs for quick spot checks.
05 Interpreting Scan Results
OpenSCAP produces both a human-readable HTML report and a machine-readable XML results file. Understanding what each section means is essential for building a remediation plan.
Generating a score summary from XML results
oscap xccdf generate report \ /var/log/scap/$(date +%Y-%m)/cis-l2-results.xml \ | grep -E "score|pass|fail|error" | head -10 echo "=== Result Summary ===" xmllint --xpath \ "count(//result[.='pass'])" \ /var/log/scap/$(date +%Y-%m)/cis-l2-results.xml echo "rules passed" xmllint --xpath \ "count(//result[.='fail'])" \ /var/log/scap/$(date +%Y-%m)/cis-l2-results.xml echo "rules failed"
List only the failed rules
oscap xccdf generate report \ /var/log/scap/$(date +%Y-%m)/cis-l2-results.xml \ | grep "fail" | grep "rule" xsltproc \ /usr/share/openscap/xsl/xccdf-report.xsl \ /var/log/scap/$(date +%Y-%m)/cis-l2-results.xml \ > /var/log/scap/$(date +%Y-%m)/cis-l2-custom-report.html grep -A2 'result>fail<' \ /var/log/scap/$(date +%Y-%m)/cis-l2-results.xml \ | grep "idref" | awk -F'"' '{print $2}'
Sample result output
Total Rules
250
CIS L2 profile
Understanding the results XML structure
<!-- Root benchmark result element --> <TestResult id="xccdf_org.open-scap_testresult_cis_server_l2" start-time="2026-06-15T02:14:07" end-time="2026-06-15T02:17:43"> <target>ol10-prod-db01.example.com</target> <!-- Individual rule result --> <rule-result idref="xccdf_org.ssgproject.content_rule_sshd_disable_root_login" severity="high" weight="1.0"> <result>fail</result> <message severity="info"> PermitRootLogin is set to 'yes' in /etc/ssh/sshd_config </message> </rule-result> <!-- Aggregate score --> <score system="urn:xccdf:scoring:default" maximum="100"> 87.350006 </score> </TestResult>
06 Automated Remediation
OpenSCAP can generate and apply remediation scripts directly from scan results. The SSG bundles both Bash scripts and Ansible playbooks for every remediatable rule. This is the most powerful feature for operations teams — you can go from scan to fix in a single pipeline.
๐จ
Always test remediation in a non-production environment first
Automated remediation can alter SSH configuration, PAM settings, filesystem mount options, and kernel parameters. Some changes require a reboot. Test in a staging environment and review the generated script before running it on production systems.
Generate a Bash remediation script from results
oscap xccdf generate fix \ --fix-type bash \ --result-id xccdf_org.open-scap_testresult_cis_server_l2 \ --output /tmp/ol10-cis-l2-remediate.sh \ /var/log/scap/$(date +%Y-%m)/cis-l2-results.xml wc -l /tmp/ol10-cis-l2-remediate.sh 847 /tmp/ol10-cis-l2-remediate.sh head -30 /tmp/ol10-cis-l2-remediate.sh
#!/bin/bash################################################################################ Bash Remediation Script for xccdf_org.ssgproject.content_profile_cis_server_l2# Profile Title: CIS Oracle Linux 10 Benchmark Level 2 - Server# Generated: 2026-06-15T02:17:43###############################################################################set -e# Ensure /tmp is a separate partitionif grep -qP '^\S+\s+/tmp\s' /etc/fstab; thenmount -o remount,nodev,nosuid,noexec /tmpfi# Disable SSH root login (RULE: sshd_disable_root_login)if grep -q "^PermitRootLogin" /etc/ssh/sshd_config; thensed -i 's/^PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_configelseecho "PermitRootLogin no" >> /etc/ssh/sshd_configfi
Generate an Ansible playbook for remediation
oscap xccdf generate fix \ --fix-type ansible \ --result-id xccdf_org.open-scap_testresult_cis_server_l2 \ --output /tmp/ol10-cis-l2-remediate.yml \ /var/log/scap/$(date +%Y-%m)/cis-l2-results.xml ansible-playbook \ --check --connection local \ -i "localhost," \ /tmp/ol10-cis-l2-remediate.yml ansible-playbook \ --connection local \ -i "localhost," \ /tmp/ol10-cis-l2-remediate.yml
Scan with inline Bash remediation (single command)
oscap xccdf eval \ --remediate \ --profile xccdf_org.ssgproject.content_profile_cis \ --results /var/log/scap/$(date +%Y-%m)/cis-remediated-results.xml \ --report /var/log/scap/$(date +%Y-%m)/cis-remediated-report.html \ /usr/share/xml/scap/ssg/content/ssg-ol10-ds.xml oscap xccdf eval \ --profile xccdf_org.ssgproject.content_profile_cis \ --results /var/log/scap/$(date +%Y-%m)/cis-post-remediation.xml \ --report /var/log/scap/$(date +%Y-%m)/cis-post-remediation.html \ /usr/share/xml/scap/ssg/content/ssg-ol10-ds.xml
07 Running OVAL Vulnerability Scans
Beyond configuration compliance, OpenSCAP can also scan for known CVEs using OVAL definitions published by Oracle. This requires downloading the latest OVAL feed from Oracle's security advisory page.
mkdir -p /var/lib/scap/oval curl -s -o /var/lib/scap/oval/ol10-oval.xml.bz2 \ "https://linux.oracle.com/security/oval/com.oracle.elsa-ol10.xml.bz2" bzip2 -dk /var/lib/scap/oval/ol10-oval.xml.bz2 oscap oval eval \ --results /var/log/scap/$(date +%Y-%m)/oval-results.xml \ --report /var/log/scap/$(date +%Y-%m)/oval-report.html \ /var/lib/scap/oval/ol10-oval.xml oscap oval eval \ --results /var/log/scap/$(date +%Y-%m)/oval-results.xml \ /var/lib/scap/oval/ol10-oval.xml \ | grep "true" | awk '{print $1}'
OVAL Results Summary:Definition oval:com.oracle.elsa:def:20245260 trueCVE CVE-2024-5260 — openssl: memory confusion in PKCS#12Severity HIGHAffected openssl-3.2.1-2.el10.x86_64Fixed in openssl-3.2.2-1.el10.x86_64Definition oval:com.oracle.elsa:def:20245178 trueCVE CVE-2024-5178 — kernel: use-after-free in io_uringSeverity MEDIUMAffected kernel-6.8.8-100.0.1.el10.x86_64Fixed in kernel-6.8.12-100.0.2.el10.x86_64Total vulnerable definitions: 2Recommended action: dnf update openssl kernel
08 Automating Scans with systemd Timers
Production environments need continuous compliance monitoring. Rather than cron, Oracle Linux 10 uses systemd timers as the standard scheduler. Here is a complete setup for daily automated scanning with log rotation.
Create the scan script
cat > /usr/local/bin/run-scap-scan.sh << 'EOF' #!/bin/bash set -euo pipefail PROFILE="xccdf_org.ssgproject.content_profile_cis_server_l2" CONTENT="/usr/share/xml/scap/ssg/content/ssg-ol10-ds.xml" DATESTAMP=$(date +%Y-%m-%d) OUTDIR="/var/log/scap/${DATESTAMP}" HOSTNAME=$(hostname -s) LOGFILE="/var/log/scap/scan-runner.log" mkdir -p "${OUTDIR}" echo "[$(date -Is)] Starting CIS L2 scan on ${HOSTNAME}" >> "${LOGFILE}" oscap xccdf eval \ --profile "${PROFILE}" \ --results "${OUTDIR}/${HOSTNAME}-cis-l2-results.xml" \ --report "${OUTDIR}/${HOSTNAME}-cis-l2-report.html" \ --oval-results \ "${CONTENT}" || true SCORE=$(xmllint --xpath "string(//score)" \ "${OUTDIR}/${HOSTNAME}-cis-l2-results.xml" 2>/dev/null || echo "N/A") echo "[$(date -Is)] Scan complete. Score: ${SCORE}" >> "${LOGFILE}" if [[ "${SCORE%%.*}" -lt "80" ]] 2>/dev/null; then echo "ALERT: SCAP score ${SCORE} below threshold on ${HOSTNAME}" \ | mail -s "[SCAP ALERT] ${HOSTNAME} CIS Score: ${SCORE}" security@example.com fi EOF chmod +x /usr/local/bin/run-scap-scan.sh
Create the systemd service and timer units
cat > /etc/systemd/system/scap-scan.service << 'EOF' [Unit] Description=OpenSCAP CIS Level 2 Compliance Scan Documentation=man:oscap(8) After=network.target [Service] Type=oneshot ExecStart=/usr/local/bin/run-scap-scan.sh StandardOutput=journal StandardError=journal SyslogIdentifier=scap-scan NoNewPrivileges=yes PrivateTmp=yes EOF
cat > /etc/systemd/system/scap-scan.timer << 'EOF' [Unit] Description=Daily OpenSCAP CIS Compliance Scan Timer Requires=scap-scan.service [Timer] OnCalendar=*-*-* 02:00:00 RandomizedDelaySec=1800 Persistent=true Unit=scap-scan.service [Install] WantedBy=timers.target EOF systemctl daemon-reload systemctl enable --now scap-scan.timer systemctl list-timers scap-scan.timer
NEXT LEFT LAST PASSED UNIT ACTIVATESMon 2026-06-16 02:17:44 UTC 23h left Sun 2026-06-15 02:14:07 UTC 3h ago scap-scan.timer scap-scan.service1 timers listed.
Log rotation for scan results
cat > /etc/logrotate.d/scap-scan << 'EOF' /var/log/scap/scan-runner.log { weekly rotate 52 compress delaycompress missingok notifempty create 0640 root root } EOF find /var/log/scap/ -type d -mtime +90 -exec rm -rf {} + 2>/dev/null
09 Scanning Remote Hosts via SSH
OpenSCAP's oscap-ssh utility lets you scan remote Oracle Linux 10 hosts from a central management node without installing the full OpenSCAP suite on each target.
dnf install -y openscap-utils oscap-ssh root@ol10-target-01 22 xccdf eval \ --profile xccdf_org.ssgproject.content_profile_cis \ --report /tmp/ol10-target-01-cis-report.html \ --results /tmp/ol10-target-01-cis-results.xml \ /usr/share/xml/scap/ssg/content/ssg-ol10-ds.xml for HOST in ol10-db01 ol10-db02 ol10-web01; do echo "=== Scanning ${HOST} ===" oscap-ssh root@${HOST} 22 xccdf eval \ --profile xccdf_org.ssgproject.content_profile_cis \ --results /var/log/scap/$(date +%Y-%m)/${HOST}-cis-results.xml \ --report /var/log/scap/$(date +%Y-%m)/${HOST}-cis-report.html \ /usr/share/xml/scap/ssg/content/ssg-ol10-ds.xml & done wait echo "All scans complete"
10 Common Findings and Manual Fixes
The following rules fail most frequently on a default Oracle Linux 10 installation. Here are the specific fixes for the most impactful ones.
Fix 1: Disable SSH root login
grep -i PermitRootLogin /etc/ssh/sshd_config PermitRootLogin yes # ← this must be 'no' sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' \ /etc/ssh/sshd_config systemctl reload sshd grep PermitRootLogin /etc/ssh/sshd_config PermitRootLogin no
Fix 2: Set password hashing to SHA-512
authselect current grep "sha512\|md5" /etc/pam.d/password-auth authselect select sssd with-faillock --force grep password /etc/pam.d/system-auth | grep unix password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok sed -i 's/^ENCRYPT_METHOD.*/ENCRYPT_METHOD SHA512/' \ /etc/login.defs
Fix 3: Set secure umask system-wide
grep umask /etc/profile /etc/bashrc cat > /etc/profile.d/cis-umask.sh << 'EOF' umask 027 EOF chmod 644 /etc/profile.d/cis-umask.sh
Fix 4: Enable and configure auditd
systemctl enable --now auditd cat > /etc/audit/rules.d/cis-ol10.rules << 'EOF' ## CIS Oracle Linux 10 - Required Audit Rules -a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change -a always,exit -F arch=b64 -S clock_settime -k time-change -w /etc/passwd -p wa -k identity -w /etc/shadow -p wa -k identity -w /etc/group -p wa -k identity -w /etc/gshadow -p wa -k identity -a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged -a always,exit -F path=/usr/bin/su -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged -a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale -w /var/log/audit/ -p wa -k audit-access -e 2 EOF augenrules --load auditctl -l | head -20
Fix 5: Configure kernel parameters
cat > /etc/sysctl.d/99-cis-ol10.conf << 'EOF' ## CIS Oracle Linux 10 sysctl hardening net.ipv4.ip_forward = 0 net.ipv6.conf.all.forwarding = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv6.conf.all.accept_redirects = 0 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.all.accept_source_route = 0 net.ipv6.conf.all.accept_source_route = 0 net.ipv4.tcp_syncookies = 1 kernel.randomize_va_space = 2 kernel.yama.ptrace_scope = 1 fs.suid_dumpable = 0 EOF sysctl --system sysctl kernel.randomize_va_space kernel.randomize_va_space = 2
11 Viewing and Comparing Reports Over Time
Compliance is not a one-time event — it's a continuous process. OpenSCAP lets you compare results across time to measure improvement.
dnf install -y python3-lxml jq for RESULT in /var/log/scap/2026-*/*cis-l2-results.xml; do DATE=$(xmllint --xpath "string(//TestResult/@end-time)" "${RESULT}" 2>/dev/null) SCORE=$(xmllint --xpath "string(//score[1])" "${RESULT}" 2>/dev/null) printf "%s\t%.2f\n" "${DATE}" "${SCORE}" done
Date Score────────────────────────────────2026-06-01T02:14:07 73.202026-06-08T02:11:33 79.452026-06-15T02:17:43 87.35↑ +14.15 points improvement over 14 days
cd /var/log/scap/$(date +%Y-%m) && \ python3 -m http.server 8080 &
12 Quick Reference
| Command | Purpose | Key flags |
|---|
| oscap info <ds.xml> | Inspect content: list profiles, benchmarks, CPE | — |
| oscap xccdf eval | Run a compliance scan against an XCCDF profile | --profile, --results, --report |
| oscap xccdf generate fix | Generate Bash or Ansible remediation from results | --fix-type bash|ansible |
| oscap oval eval | Scan for CVEs using Oracle OVAL definitions | --results, --report |
| oscap-ssh | Scan a remote host over SSH | USER@HOST PORT [oscap args] |
| oscap xccdf validate | Validate an XCCDF document for correctness | — |
| oscap ds split | Split a DataStream into component files | --output-dir |
๐ฏ
Production recommendation
Start with CIS Level 1. Establish a baseline score, fix the high-severity failures, re-scan, then gradually move toward Level 2 or STIG. A score increase from 65% to 90% in 30 days is achievable with the automated remediation pipeline described in this guide. Document every change — your auditors will ask for it.
Comments