Automated Compliance Scanning with OpenSCAP
OpenSCAP is an open-source framework that automates security compliance scanning using the SCAP (Security Content Automation Protocol) standard on Linux systems. This guide covers installing OpenSCAP, selecting appropriate profiles such as STIG and CIS, running scans, generating reports, and automating remediation.
Prerequisites
- Ubuntu 20.04+, CentOS/Rocky 8+, or RHEL 8+ with root access
- Internet access to download SCAP content
- At least 1 GB free disk space for reports and content
- Basic understanding of your target compliance standard (STIG, CIS, PCI-DSS)
Installing OpenSCAP
# Ubuntu/Debian
sudo apt update
sudo apt install -y openscap-scanner openscap-utils scap-security-guide
# CentOS/Rocky/RHEL
sudo dnf install -y openscap openscap-scanner scap-security-guide
# Verify installation
oscap --version
SCAP content is installed to /usr/share/xml/scap/ssg/content/ on most distributions:
# List available content files
ls /usr/share/xml/scap/ssg/content/
# You'll see files like:
# ssg-ubuntu2004-ds.xml
# ssg-rhel8-ds.xml
# ssg-centos8-ds.xml
Understanding SCAP Content and Profiles
SCAP content files use XCCDF format and contain multiple profiles (rule sets). Each profile maps to a compliance standard.
# List available profiles for your OS
oscap info /usr/share/xml/scap/ssg/content/ssg-ubuntu2004-ds.xml
# For RHEL/CentOS
oscap info /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
Common profiles you'll see:
| Profile ID | Standard |
|---|---|
xccdf_org.ssgproject.content_profile_cis | CIS Benchmark |
xccdf_org.ssgproject.content_profile_stig | DISA STIG |
xccdf_org.ssgproject.content_profile_pci-dss | PCI-DSS |
xccdf_org.ssgproject.content_profile_hipaa | HIPAA |
# Get detailed profile information including rule count
oscap info --profile xccdf_org.ssgproject.content_profile_cis \
/usr/share/xml/scap/ssg/content/ssg-ubuntu2004-ds.xml
Running Your First Compliance Scan
Set variables for your OS and preferred profile:
# Ubuntu
CONTENT="/usr/share/xml/scap/ssg/content/ssg-ubuntu2004-ds.xml"
PROFILE="xccdf_org.ssgproject.content_profile_cis_level1_server"
# RHEL/CentOS
CONTENT="/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml"
PROFILE="xccdf_org.ssgproject.content_profile_cis"
Run the scan:
sudo oscap xccdf eval \
--profile "$PROFILE" \
--results /tmp/scan-results.xml \
--report /tmp/scan-report.html \
--oval-results \
"$CONTENT"
echo "Exit code: $?"
# 0 = all rules passed
# 1 = oscap error
# 2 = some rules failed
Quick scan without saving results (for testing):
sudo oscap xccdf eval \
--profile "$PROFILE" \
--fetch-remote-resources \
"$CONTENT" 2>/dev/null | grep -E "^Rule|pass|fail|error" | head -50
Generating HTML Reports
OpenSCAP produces detailed HTML reports. View them in a browser:
# Scan with full reporting
sudo oscap xccdf eval \
--profile "$PROFILE" \
--results /var/log/openscap/results-$(date +%Y%m%d).xml \
--report /var/log/openscap/report-$(date +%Y%m%d).html \
--oval-results \
"$CONTENT"
# Create directory first
sudo mkdir -p /var/log/openscap
Generate a report from existing results XML:
# Regenerate HTML from saved XML results
oscap xccdf generate report /var/log/openscap/results-20260101.xml \
> /var/log/openscap/report-20260101.html
Extract a summary of failures:
# Show only failed rules
oscap xccdf generate report /var/log/openscap/results-20260101.xml 2>/dev/null | \
grep -A2 "fail"
# Using the XML directly
grep 'result>fail' /var/log/openscap/results-20260101.xml | wc -l
STIG Compliance Scanning
STIG (Security Technical Implementation Guide) scanning is common in government and defense environments.
# RHEL 8 STIG scan
sudo oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_stig \
--results /var/log/openscap/stig-results.xml \
--report /var/log/openscap/stig-report.html \
/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
For Ubuntu STIG (requires DISA content):
# Download DISA STIG content (Ubuntu example)
wget https://dl.dod.cyber.mil/wp-content/uploads/stigs/zip/U_CAN_Ubuntu_20-04_LTS_STIG.zip
unzip U_CAN_Ubuntu_20-04_LTS_STIG.zip -d /tmp/ubuntu-stig/
# Scan with DISA content
sudo oscap xccdf eval \
--profile MAC-1_Sensitive \
--results /var/log/openscap/disa-results.xml \
--report /var/log/openscap/disa-report.html \
/tmp/ubuntu-stig/U_CAN_Ubuntu_20-04_LTS_STIG_V1R*.xml
Automated Remediation
OpenSCAP can generate Ansible playbooks or bash scripts to fix failures automatically.
Generate a remediation bash script:
# Generate fix script from scan results
oscap xccdf generate fix \
--fix-type bash \
--output /tmp/remediation.sh \
--result-id "" \
/var/log/openscap/results-$(date +%Y%m%d).xml
# Review before running
less /tmp/remediation.sh
# Apply remediation
sudo bash /tmp/remediation.sh
Generate an Ansible playbook for remediation:
# Generate Ansible playbook from results
oscap xccdf generate fix \
--fix-type ansible \
--output /tmp/remediation-playbook.yml \
/var/log/openscap/results-$(date +%Y%m%d).xml
# Run with Ansible
ansible-playbook -i localhost, /tmp/remediation-playbook.yml
Generate a full remediation playbook proactively (before scanning):
# Generate playbook directly from profile without scanning first
oscap xccdf generate fix \
--fix-type ansible \
--profile "$PROFILE" \
--output /tmp/full-remediation.yml \
"$CONTENT"
Scheduling Regular Scans
Automate weekly compliance scans:
sudo mkdir -p /var/log/openscap
sudo nano /usr/local/bin/openscap-weekly-scan.sh
#!/bin/bash
set -euo pipefail
CONTENT="/usr/share/xml/scap/ssg/content/ssg-ubuntu2004-ds.xml"
PROFILE="xccdf_org.ssgproject.content_profile_cis_level1_server"
DATE=$(date +%Y%m%d)
LOG_DIR="/var/log/openscap"
mkdir -p "$LOG_DIR"
echo "Starting OpenSCAP scan at $(date)"
oscap xccdf eval \
--profile "$PROFILE" \
--results "$LOG_DIR/results-$DATE.xml" \
--report "$LOG_DIR/report-$DATE.html" \
--oval-results \
"$CONTENT"
EXIT_CODE=$?
# Count results
PASS=$(grep -c 'result>pass' "$LOG_DIR/results-$DATE.xml" 2>/dev/null || echo 0)
FAIL=$(grep -c 'result>fail' "$LOG_DIR/results-$DATE.xml" 2>/dev/null || echo 0)
echo "Scan complete. Pass: $PASS, Fail: $FAIL"
echo "Report: $LOG_DIR/report-$DATE.html"
# Alert if failures exceed threshold
if [ "$FAIL" -gt 20 ]; then
echo "ALERT: $FAIL compliance failures detected" | \
mail -s "OpenSCAP Alert: $FAIL failures on $(hostname)" [email protected]
fi
# Keep only last 90 days of reports
find "$LOG_DIR" -name "*.html" -mtime +90 -delete
find "$LOG_DIR" -name "*.xml" -mtime +90 -delete
sudo chmod +x /usr/local/bin/openscap-weekly-scan.sh
# Schedule weekly on Sunday at 2 AM
sudo crontab -e
# Add:
# 0 2 * * 0 /usr/local/bin/openscap-weekly-scan.sh >> /var/log/openscap/cron.log 2>&1
Troubleshooting
"No such file or directory" for SCAP content:
# Check what content is installed
find /usr/share/xml -name "*.xml" 2>/dev/null | head -20
# Install missing content
sudo apt install scap-security-guide # Ubuntu
sudo dnf install scap-security-guide # CentOS/Rocky
Scan hangs or takes very long:
# Run with verbose output to identify which rule is slow
sudo oscap xccdf eval --verbose WARNING --profile "$PROFILE" "$CONTENT" 2>&1 | tail -20
# Skip network-dependent rules
sudo oscap xccdf eval --profile "$PROFILE" --skip-valid "$CONTENT"
Profile not found error:
# List exact profile IDs available
oscap info "$CONTENT" | grep "Id:"
# Copy the full ID string exactly as shown
HTML report is empty or broken:
# Ensure xsltproc is installed
sudo apt install xsltproc # Ubuntu
sudo dnf install libxslt # CentOS/Rocky
Conclusion
OpenSCAP provides a robust, standards-based approach to automated compliance scanning on Linux. By selecting the right profile (STIG, CIS, HIPAA), scheduling regular scans, and using the generated remediation scripts, you can maintain a measurable and auditable compliance posture. Run scans weekly, review the HTML reports, and remediate failures promptly to keep your infrastructure aligned with your target security standard.


