The Enterprise Linux OpenSCAP Operational Guide: Automated Vulnerability Auditing, Baseline Compliance, and Safeguarded Air-Gapped Remediation
Target Platforms: Red Hat Enterprise Linux Family (RHEL 8/9/10, Rocky Linux, AlmaLinux, Oracle Linux), Ubuntu LTS (22.04/24.04/26.04), Debian GNU/Linux (11/12/13), and openSUSE / SUSE Linux Enterprise (SLES/SLED 15 SP7) Target Audience: Systems Architects, Linux System Administrators, DevOps Engineers, and Information Security Auditors Tooling Stack: OpenSCAP Scanner (
oscap 1.3.14+), SCAP Security Guide (0.1.82+/ComplianceAsCode/content), Ansible Core (2.16+), DNF / APT / Zypper /createrepo_cDesign Framework: Terminal & Cloud Publication Standard (DSOM Rule 11 — Pure White#FFFFFF, High-Legibility Typography) Sanitization Notice: All hostnames (*.example.com) and IP addresses (192.0.2.0/24,198.51.100.0/24) adhere strictly to RFC 5737 and RFC 1918 for public consumption.
DO NOT RUN UNVETTED AUTOMATED REMEDIATIONS IN PRODUCTION ENVIRONMENTS.
Executing automated package updates (dnf upgrade -y / apt upgrade -y) or automated security policy hardening fixes (oscap xccdf eval --remediate) directly on live production infrastructure without qualification can trigger catastrophic service outages, sever inter-cluster communication links, corrupt database processes, and break container bridge networking.
- Mandatory Pre-Remediation Snapshots: Take full hypervisor snapshots (or LVM storage snapshots) and complete database logical dumps (PostgreSQL / Oracle) immediately before performing any package updates or configuration mutations.
- Mandatory Non-Mutating Dry-Run Simulation: Always execute DNF/APT dry runs (
--setopt=tsflags=test/--dry-run) and SCAP fix script inspection (oscap xccdf generate fix ...) to verify that zero packages will be removed and zero critical configurations destroyed. - Subsystem Protection Invariants: Never permit remediation automation to disable specialized cluster signaling (SCTP Protocol 132 for real-time clustering on port 29168), enforce
noexecon/tmp(breaks PostgreSQL PostGIS extensions and Oracle shadow processes), or disable IPv4 packet forwarding (breaks container microservices networking). - Scheduled Maintenance Windows: All package upgrades and host reboots must be executed during low-traffic maintenance windows (02:00–04:00 local time) using serial rolling execution (
serial: 1) with verified rollback procedures.
Executive Overview: The Dual-Track Security Paradigm
Securing enterprise web applications, microservices, and databases running on enterprise Linux distributions requires two fundamentally distinct, complementary assessment methodologies. Confusing these two tracks or applying automated security remediations blindly leads to service outages, broken dependencies, and cluster communication failures.
1. Part A: The OVAL Vulnerability Assessment Track
- Core Standard: Open Vulnerability and Assessment Language (OVAL v2).
- Primary Objective: Detect unpatched Common Vulnerabilities and Exposures (CVEs), Red Hat Security Advisories (RHSAs), Ubuntu Security Notices (USNs), or Debian Security Advisories (DSAs) across installed software packages.
- Evaluation Mechanism: OpenSCAP examines the local package manager database (
/var/lib/rpmor/var/lib/dpkg) against official distribution OVAL definitions, evaluating exact package versions, release epochs, and vendor cryptographic signatures. - The Ground Truth Standard (Red Hat KB 221883): External unauthenticated network port scanners (e.g., Rapid7, Nessus, Qualys) rely on banner grabbing over TCP (e.g. querying
SSH-2.0-OpenSSH_8.0). Network scanners flag dozens of false positives because they cannot detect vendor backported security patches. Authenticated on-host OpenSCAP OVAL evaluation is recognized as the definitive, cryptographically verified ground truth for enterprise Linux security compliance.
2. Part B: The XCCDF Baseline Hardening & Compliance Track
- Core Standard: Extensible Configuration Checklist Description Format (XCCDF 1.2) powered by
ComplianceAsCode/content. - Primary Objective: Measure system compliance against formal security benchmarks (CIS Level 1/2, DISA STIG, PCI-DSS, ANSSI, HIPAA).
- Evaluation Mechanism: OpenSCAP tests kernel parameters (
sysctl), file system mount options (/etc/fstab), PAM authentication modules, audit logging rules (auditd), password aging policies, and cryptographic algorithms. - The Safeguarded Remediation Imperative: Standard out-of-the-box XCCDF remediation scripts will cripple mission-critical applications if applied blindly. For example, standard CIS benchmarks unconditionally disable the Linux kernel SCTP module, enforce
noexecon temporary mounts, restrict shared memory, and flush firewall tables. In mission-critical enterprise systems—such as Core Clustered Message Engines, Web Application Portals, Relational Databases, and Microservice Hosts—these blind changes sever inter-node messaging links, crash relational databases, and destroy container networking bridges.
Table of Contents
Reference Architecture & Enterprise Fleet Topology
The procedures in this guide are illustrated using a multi-node enterprise infrastructure fleet spanning RedHat, Ubuntu, Debian, and openSUSE platforms. All addresses utilize RFC 5737 and RFC 1918 documentation ranges:
| Logical Role | Fully Qualified Domain Name (FQDN) | Management IP | Operating System | Critical Workload Subsystem |
|---|---|---|---|---|
| Automation Controller | mgmt-ctrl-01.infra.example.com |
192.0.2.10 |
RHEL 8.10 / 9.4 Golden Master | Ansible Core 2.16, Local Offline Repository Mirror |
| Ingress Gateway | gw-ingress-01.node.example.com |
198.51.100.20 |
Ubuntu 24.04 LTS | HAProxy 2.8, Reverse Proxy & TLS (Ports 443, 8899) |
| Microservices Host | svc-container-01.node.example.com |
198.51.100.30 |
Debian 12 (Bookworm) | Container Platform, Rootless Podman 5+ (20+ Microservices) |
| Web App & Spatial DB | app-web-01.node.example.com |
198.51.100.40 |
RHEL 8.10 / AlmaLinux 9 | Web API, PostgreSQL 17, PostGIS Spatial Extension |
| Core Message Engine | core-msg-01.node.example.com |
198.51.100.50 |
openSUSE Leap 15.6 / SLES 15 | Clustered Message Dispatcher, SCTP Clustered Links, Oracle 19c |
Multi-Distribution DataStream & Profile Matrix
OpenSCAP resolves Security Content Automation Protocol DataStreams from the scap-security-guide package or the upstream ComplianceAsCode/content release repository:
| OS Family | Target Distribution | SCAP DataStream Location / Artifact | Standard CIS Profile Identifier |
|---|---|---|---|
| RHEL Family | RHEL 8 / Alma 8 / Rocky 8 / OL 8 | /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml |
xccdf_org.ssgproject.content_profile_cis |
| RHEL Family | RHEL 9 / Alma 9 / Rocky 9 / OL 9 | /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml |
xccdf_org.ssgproject.content_profile_cis |
| RHEL Family | RHEL 10 / Alma 10 / Rocky 10 / OL 10 | /usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml |
xccdf_org.ssgproject.content_profile_cis |
| Ubuntu LTS | Ubuntu 22.04 LTS | ssg-ubuntu2204-ds.xml (ComplianceAsCode/content) |
xccdf_org.ssgproject.content_profile_cis_level2_server |
| Ubuntu LTS | Ubuntu 24.04 LTS | ssg-ubuntu2404-ds.xml (ComplianceAsCode/content) |
xccdf_org.ssgproject.content_profile_cis_level2_server |
| Ubuntu LTS | Ubuntu 26.04 LTS | Coverage unavailable upstream in SSG (Use 24.04 datastream fallback) | xccdf_org.ssgproject.content_profile_cis_level2_server |
| Debian | Debian 11 (Bullseye) | /usr/share/xml/scap/ssg/content/ssg-debian11-ds.xml |
xccdf_org.ssgproject.content_profile_standard |
| Debian | Debian 12 (Bookworm) | /usr/share/xml/scap/ssg/content/ssg-debian12-ds.xml |
xccdf_org.ssgproject.content_profile_standard |
| Debian | Debian 13 (Trixie) | Coverage unavailable upstream in SSG (Use Debian 12 datastream fallback) | xccdf_org.ssgproject.content_profile_standard |
| SUSE | openSUSE Leap 15 / SLES 15 | /usr/share/xml/scap/ssg/content/ssg-sle15-ds.xml |
xccdf_org.ssgproject.content_profile_cis |
Pre-Flight: Harvesting & Installing OpenSCAP Tools for Air-Gapped Environments
In secure enterprise and air-gapped environments without direct internet access, the OpenSCAP scanner utilities (openscap-scanner, scap-security-guide) cannot be installed directly from public mirrors. This section outlines the offline provisioning workflow.
Step 0.1: Package Dependencies and Artifact Inventory
The OpenSCAP scanner suite requires three primary package categories and their associated runtime dependencies:
openscap/libopenscap8: Core OpenSCAP C shared library, schema parsers, and OVAL/XCCDF engine.openscap-scanner: Command-line interface (/usr/bin/oscap) for scanning and report generation.scap-security-guide: Pre-compiled SCAP DataStream profiles (/usr/share/xml/scap/ssg/content/).- Supporting tools:
xml-common,libxslt,bzip2,pcre2.
Step 0.2: Downloading OpenSCAP Packages on an Online Staging Host
On an internet-connected staging machine matching the target OS family:
RHEL / Enterprise Linux Staging Host
# 1. Create dedicated harvest directory
mkdir -p /tmp/openscap_tools_harvest/packages && cd /tmp/openscap_tools_harvest
# 2. Download OpenSCAP packages with complete dependencies
dnf download --resolve --alldeps --destdir=/tmp/openscap_tools_harvest/packages \
openscap \
openscap-scanner \
scap-security-guide \
xml-common
# 3. Generate repository metadata
sudo dnf install -y createrepo_c
createrepo_c /tmp/openscap_tools_harvest/packages/
# 4. Compress bundle
tar -czvf /tmp/openscap-tools-rhel-airgap.tar.gz -C /tmp/openscap_tools_harvest packages
Ubuntu / Debian Staging Host
# 1. Create dedicated harvest directory
mkdir -p /tmp/openscap_tools_deb/packages && cd /tmp/openscap_tools_deb
# 2. Download DEB packages with dependencies
apt-get update && apt-get install --download-only -y \
openscap-scanner \
ssg-debian \
ssg-debderived
cp /var/cache/apt/archives/*.deb /tmp/openscap_tools_deb/packages/
# 3. Compress bundle
tar -czvf /tmp/openscap-tools-deb-airgap.tar.gz -C /tmp/openscap_tools_deb packages
Step 0.3: Air-Gapped Installation via Direct CLI
Once the tarball is transferred to the air-gapped target host:
# Extract archive and install offline
sudo mkdir -p /var/tmp/openscap_offline_tools
sudo tar -xzvf openscap-tools-rhel-airgap.tar.gz -C /var/tmp/openscap_offline_tools/
# Import vendor/local trusted GPG keys before repository setup
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
# Configure local repository with signature verification enabled
sudo tee /etc/yum.repos.d/openscap-local.repo << 'EOF'
[openscap-local]
name=Local OpenSCAP Tools Offline Repository
baseurl=file:///var/tmp/openscap_offline_tools/packages
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
priority=1
EOF
# Perform dry-run and install
sudo dnf install -y --setopt=tsflags=test --disablerepo=* --enablerepo=openscap-local openscap-scanner scap-security-guide
sudo dnf install -y --disablerepo=* --enablerepo=openscap-local openscap-scanner scap-security-guide
# Validate executable
oscap --version
Step 0.4: Automated Air-Gapped Tool Provisioning with Ansible
The following playbook (install_openscap_airgap_fleet.yml) distributes and installs the offline tool bundle across target nodes:
---
- name: "Provision OpenSCAP Toolset in Air-Gapped Fleet (Pre-Flight)"
hosts: fleet
gather_facts: true
become: true
vars:
controller_tools_archive: "/home/operator/openscap-tools-rhel-airgap.tar.gz"
target_tools_dir: "/var/tmp/openscap_offline_tools"
tasks:
- name: "0.1 Create target staging directory"
ansible.builtin.file:
path: "{{ target_tools_dir }}"
state: directory
mode: "0755"
- name: "0.2 Transfer and extract tools bundle to target host"
ansible.builtin.unarchive:
src: "{{ controller_tools_archive }}"
dest: "{{ target_tools_dir }}"
mode: "0755"
- name: "0.3 Configure local DNF repo definition (RHEL family)"
ansible.builtin.copy:
dest: "/etc/yum.repos.d/openscap-local.repo"
content: |
[openscap-local]
name=Local OpenSCAP Tools Offline Repository
baseurl=file://{{ target_tools_dir }}/packages
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
mode: "0644"
when: ansible_os_family == 'RedHat'
- name: "0.4 Execute pre-flight dry-run check (tsflags=test)"
ansible.builtin.command:
cmd: >
dnf install -y
--setopt=tsflags=test
--disablerepo=*
--enablerepo=openscap-local
openscap-scanner scap-security-guide
register: tool_dry_run
changed_when: false
when: ansible_os_family == 'RedHat'
- name: "0.5 Install OpenSCAP scanner and security guide"
ansible.builtin.dnf:
name:
- openscap-scanner
- scap-security-guide
state: present
disablerepo: "*"
enablerepo: "openscap-local"
disable_plugin: "subscription-manager"
when: ansible_os_family == 'RedHat'
- name: "0.6 Verify oscap executable presence"
ansible.builtin.command:
cmd: "oscap --version"
register: oscap_ver
changed_when: false
when: ansible_os_family == 'RedHat'
- name: "0.7 Display installed OpenSCAP version"
ansible.builtin.debug:
msg: "Host {{ inventory_hostname }}: {{ oscap_ver.stdout_lines[0] }}"
when: ansible_os_family == 'RedHat'
Part A: OpenSCAP OVAL (Vulnerability Assessment & Errata)
Part A1: OVAL Vulnerability Scanning & Reporting
This section demonstrates how to acquire official vendor OVAL streams, execute non-destructive host scans, and generate interactive HTML and XML compliance reports.
Step 0: Acquiring and Verifying Official Vendor OVAL Streams
Official OVAL definition streams are published by vendor security teams:
- Red Hat Enterprise Linux 8/9/10:
https://security.access.redhat.com/data/oval/v2/RHEL8/rhel-8.oval.xml.bz2 - Ubuntu 24.04 LTS (Noble):
https://security-metadata.canonical.com/oval/com.ubuntu.noble.usn.oval.xml.bz2 - Debian 12 (Bookworm):
https://www.debian.org/security/oval/oval-definitions-bookworm.xml.bz2
Connected Acquisition Example (Controller)
mkdir -p ~/openscap_oval && cd ~/openscap_oval
# Download RHEL 8 OVAL definitions
curl -fsSL -O https://security.access.redhat.com/data/oval/v2/RHEL8/rhel-8.oval.xml.bz2
bunzip2 -f rhel-8.oval.xml.bz2
# Download Ubuntu OVAL definitions
curl -fsSL -O https://security-metadata.canonical.com/oval/com.ubuntu.noble.usn.oval.xml.bz2
bunzip2 -f com.ubuntu.noble.usn.oval.xml.bz2
Step 1: Direct CLI Command Line Execution (Part A1)
To audit a host directly via the command line:
sudo mkdir -p /var/tmp/openscap_oval
# Execute OVAL scan against host RPM/DPKG package database
sudo oscap oval eval \
--results /var/tmp/openscap_oval/oval-results-$(hostname -s).xml \
--report /var/tmp/openscap_oval/oval-report-$(hostname -s).html \
~/openscap_oval/rhel-8.oval.xml
Understanding OpenSCAP OVAL CLI Exit Codes
- Return Code
0(rc=0): Evaluation completed successfully. Note:oscap oval evalreturns exit code0regardless of whether unpatched vulnerabilities or non-compliant OVAL definitions are found. - Return Code
1(rc=1): A genuine runtime error occurred (e.g. malformed XML, missing file, or permission denied).
Critical Audit Invariant: Unlike XCCDF scans (which return
rc=2on rule failures),oscap oval evalreturns0upon successful evaluation completion even when unpatched vulnerabilities exist. Administrators must inspect the generated XML or HTML report results directly to extract vulnerability findings rather than relying on the process exit code.
Step 2: Automated Fleet Audit Using Ansible Playbooks (Part A1)
Declarative playbook: audit_oval_fleet.yml.
---
- name: "Enterprise OpenSCAP OVAL Fleet Vulnerability Audit (Part A1)"
hosts: fleet,controllers
gather_facts: true
become: false
vars:
target_staging_dir: "/var/tmp/openscap_oval"
target_report_html: "/var/tmp/openscap_oval/oval-report-{{ inventory_hostname }}.html"
target_results_xml: "/var/tmp/openscap_oval/oval-results-{{ inventory_hostname }}.xml"
controller_harvest_dir: "/home/operator/audit-reports/oval/{{ inventory_hostname }}"
tasks:
- name: "1.1 Determine host-specific OVAL definition feed"
ansible.builtin.set_fact:
host_oval_filename: >-
{%- if ansible_os_family == 'RedHat' and ansible_distribution_major_version == '8' -%}
rhel-8.oval.xml
{%- elif ansible_os_family == 'RedHat' and ansible_distribution_major_version == '9' -%}
rhel-9.oval.xml
{%- elif ansible_os_family == 'RedHat' and ansible_distribution_major_version == '10' -%}
rhel-10.oval.xml
{%- elif ansible_distribution | lower == 'ubuntu' -%}
com.ubuntu.{{ ansible_distribution_release }}.usn.oval.xml
{%- elif ansible_distribution | lower == 'debian' and ansible_distribution_major_version == '11' -%}
oval-definitions-bullseye.xml
{%- elif ansible_distribution | lower == 'debian' and ansible_distribution_major_version == '12' -%}
oval-definitions-bookworm.xml
{%- else -%}
unsupported
{%- endif -%}
- name: "1.2 Fail if OVAL definition feed is unsupported for target host OS"
ansible.builtin.fail:
msg: "OVAL feed unavailable for {{ ansible_distribution }} {{ ansible_distribution_version }}"
when: host_oval_filename == 'unsupported'
- name: "1.3 Set target OVAL stream path"
ansible.builtin.set_fact:
controller_oval_stream: "/home/operator/openscap_oval/{{ host_oval_filename }}"
target_oval_stream: "{{ target_staging_dir }}/{{ host_oval_filename }}"
- name: "1.4 Verify openscap-scanner is installed"
ansible.builtin.command:
cmd: "which oscap"
register: oscap_check
changed_when: false
failed_when: oscap_check.rc != 0
- name: "1.4 Create staging and harvest directories"
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "0755"
loop:
- "{{ target_staging_dir }}"
- name: "1.5 Create local controller harvest directory"
ansible.builtin.file:
path: "{{ controller_harvest_dir }}"
state: directory
mode: "0755"
delegate_to: localhost
- name: "2.1 Distribute target OS-specific OVAL stream to target host"
ansible.builtin.copy:
src: "{{ controller_oval_stream }}"
dest: "{{ target_oval_stream }}"
mode: "0644"
when: inventory_hostname != 'mgmt-ctrl-01.infra.example.com'
- name: "3.1 Execute OpenSCAP OVAL evaluation scan"
ansible.builtin.command:
cmd: >
oscap oval eval
--results {{ target_results_xml }}
--report {{ target_report_html }}
{{ target_oval_stream }}
register: oscap_eval_raw
changed_when: false
failed_when: oscap_eval_raw.rc not in [0, 2]
- name: "4.1 Fetch HTML report to controller"
ansible.builtin.fetch:
src: "{{ target_report_html }}"
dest: "{{ controller_harvest_dir }}/oval-report.html"
flat: true
- name: "5.1 Extract compliance metrics from HTML report"
ansible.builtin.shell: |
bash -c "
VULN=\$(grep -oP 'title=\"Non-Compliant/Vulnerable/Unpatched\" style=\"width:20%\">\K[0-9]+' {{ target_report_html }} | head -n 1)
PASS=\$(grep -oP 'title=\"Compliant/Non-Vulnerable/Patched\" style=\"width:20%\">\K[0-9]+' {{ target_report_html }} | head -n 1)
TOTAL=\$(grep -oP '[0-9]+ Total' {{ target_report_html }} | head -n 1 | awk '{print \$1}')
echo \"TOTAL:\${TOTAL:-0} | VULN:\${VULN:-0} | PASS:\${PASS:-0}\"
"
register: oval_summary
changed_when: false
- name: "5.2 Display OVAL Assessment Scorecard"
ansible.builtin.debug:
msg:
- "=================================================================="
- "HOST: {{ inventory_hostname }} ({{ ansible_default_ipv4.address }})"
- "RUNNING KERNEL: {{ ansible_kernel }}"
- "OVAL EVALUATION: {{ oval_summary.stdout }}"
- "REPORTS STAGED AT: {{ controller_harvest_dir }}/"
- "=================================================================="
Part A2: OVAL-Driven Vulnerability Remediation (Air-Gapped Repositories)
When applying security errata in air-gapped production environments:
- Dependency Cleanup Control: Always specify
--setopt=clean_requirements_on_remove=0for DNF to prevent automatic removal of unneeded dependencies during operations, or omit--auto-removefor APT. Strictly avoid--allowerasing. The explicitRemoving:dry-run assertion in the playbook serves as the primary safeguard against accidental package removals. - Mandatory Dry-Run: Always execute dry-runs (
dnf upgrade --setopt=tsflags=test ...orapt-get upgrade --dry-run) first to verify transaction safety. - Rolling Serial Execution: Update nodes serially (
serial: 1in Ansible) to preserve cluster high availability.
Step 1: Identifying Errata Packages from OVAL Results
Extract flagged advisory IDs (RHSA / USN / DSA) from oval-report.html:
grep -oP '(RHSA|USN|DSA)-[0-9]+[:\-][0-9]+' /var/tmp/openscap_oval/oval-report-$(hostname -s).html | sort -u > /tmp/flagged_errata.txt
head -n 15 /tmp/flagged_errata.txt
Step 2: Harvesting Finding-Driven RPM/DEB Errata Packages on an Online Staging Node
Rather than relying on static, hardcoded package lists, harvesting must resolve the exact package dependencies associated with the OVAL evaluation audit findings:
Finding-Driven Harvest Procedure for RPM / Enterprise Linux:
mkdir -p /tmp/errata_harvest/packages && cd /tmp/errata_harvest
# 1. Option A: Download packages directly by flagged Red Hat Security Advisory (RHSA) IDs
ADVISORY_LIST=$(tr '\n' ',' < /tmp/flagged_rhsa.txt | sed 's/,$//')
dnf download --resolve --advisories="$ADVISORY_LIST" --destdir=/tmp/errata_harvest/packages
# 2. Option B: Resolve affected package names directly from OVAL XML result tags
grep -oP '(?<=<affected_pkg>)[^<]+' /var/tmp/openscap_oval/oval-results-$(hostname -s).xml | sort -u > /tmp/target_pkgs.txt
dnf download --resolve --destdir=/tmp/errata_harvest/packages $(cat /tmp/target_pkgs.txt)
Finding-Driven Harvest Procedure for DEB / Ubuntu / Debian:
mkdir -p /tmp/errata_harvest_deb/packages && cd /tmp/errata_harvest_deb
OVAL_RESULTS_FILE="/var/tmp/openscap_oval/oval-results-$(hostname -s).xml"
# Parse specific host OVAL XML results file to extract package names from vulnerable definitions
python3 -c "
import xml.etree.ElementTree as ET, sys, os
target_file = sys.argv[1]
if not os.path.isfile(target_file):
sys.stderr.write(f'Error: Specified OVAL results file {target_file} not found.\n')
sys.exit(1)
pkgs = set()
try:
tree = ET.parse(target_file)
root = tree.getroot()
for elem in root.iter():
if elem.tag.endswith('definition') and elem.attrib.get('result') in ['true', 'vulnerable']:
for item in elem.iter():
if 'name' in item.attrib:
pkgs.add(item.attrib['name'])
elif item.text and item.tag.endswith('name'):
pkgs.add(item.text.strip())
except Exception as e:
sys.stderr.write(f'Error parsing OVAL results file {target_file}: {e}\n')
sys.exit(1)
for p in sorted(pkgs):
print(p)
" "$OVAL_RESULTS_FILE" > /tmp/target_deb_pkgs.txt
# Validate that candidate DEB package findings are present before explicit download
if [ -s /tmp/target_deb_pkgs.txt ]; then
apt-get update && apt-get download $(cat /tmp/target_deb_pkgs.txt)
# Verify offline bundle integrity
for pkg in *.deb; do
dpkg-deb -I "$pkg" > /dev/null || echo "Corrupt DEB package: $pkg"
done
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
else
echo "No OVAL non-compliant DEB packages detected for harvest."
fi
Step 3: Creating Internal Offline Repositories
# For RPM repositories
createrepo_c /tmp/errata_harvest/packages/
tar -czvf /tmp/internal-security-errata-rhel.tar.gz -C /tmp/errata_harvest packages
# For DEB repositories
cd /tmp/errata_harvest_deb/packages
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
tar -czvf /tmp/internal-security-errata-deb.tar.gz -C /tmp/errata_harvest_deb packages
Step 4: Staging and Configuring Internal Repositories on Target Hosts
# RHEL Target Configuration
sudo mkdir -p /var/tmp/offline-repos
sudo tar -xzvf /tmp/internal-security-errata-rhel.tar.gz -C /var/tmp/offline-repos/
# Ensure trusted GPG keys are imported
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
sudo tee /etc/yum.repos.d/internal-security-errata.repo << 'EOF'
[internal-security-errata]
name=Internal Air-Gapped Security Errata
baseurl=file:///var/tmp/offline-repos/packages
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
priority=1
EOF
Step 5: Direct CLI Command Line Execution (Part A2)
# Mandatory Pre-Flight Transaction Dry-Run
sudo dnf upgrade -y \
--setopt=tsflags=test \
--disablerepo=* \
--enablerepo=internal-security-errata \
--disableplugin=subscription-manager \
--setopt=clean_requirements_on_remove=0 \
--nobest
# Live Upgrade Execution
sudo dnf upgrade -y \
--disablerepo=* \
--enablerepo=internal-security-errata \
--disableplugin=subscription-manager \
--setopt=clean_requirements_on_remove=0 \
--nobest
Step 6: Automated Fleet Remediation Using Ansible Playbooks (Part A2)
Declarative playbook: remediate_oval_fleet.yml.
---
- name: "Enterprise OVAL Errata Fleet Remediation (Part A2)"
hosts: fleet
serial: 1
gather_facts: true
become: true
vars:
controller_repo_bundle: "/home/operator/internal-security-errata-rhel.tar.gz"
target_repo_dir: "/var/tmp/offline-repos"
target_oval_stream: "/var/tmp/openscap_oval/rhel-8.oval.xml"
tasks:
- name: "1.1 Create target offline repo directory"
ansible.builtin.file:
path: "{{ target_repo_dir }}"
state: directory
mode: "0755"
- name: "1.2 Extract repository archive on target host"
ansible.builtin.unarchive:
src: "{{ controller_repo_bundle }}"
dest: "{{ target_repo_dir }}"
mode: "0755"
- name: "1.3 Deploy internal repository configuration"
ansible.builtin.copy:
dest: "/etc/yum.repos.d/internal-security-errata.repo"
content: |
[internal-security-errata]
name=Internal Air-Gapped Security Errata
baseurl=file://{{ target_repo_dir }}/packages
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
mode: "0644"
when: ansible_os_family == 'RedHat'
- name: "2.1 Execute mandatory pre-flight dry-run simulation (tsflags=test)"
ansible.builtin.command:
cmd: >
dnf upgrade -y
--setopt=tsflags=test
--disablerepo=*
--enablerepo=internal-security-errata
--disableplugin=subscription-manager
--setopt=clean_requirements_on_remove=0
--nobest
register: dnf_dry_run
changed_when: false
when: ansible_os_family == 'RedHat'
- name: "2.2 Assert 0 package removals during dry-run"
ansible.builtin.assert:
that:
- "'Removing:' not in dnf_dry_run.stdout"
fail_msg: "ABORT: DNF dry-run indicated package removals!"
when: ansible_os_family == 'RedHat'
- name: "3.1 Execute live package security upgrade"
ansible.builtin.dnf:
name: "*"
state: latest
disablerepo: "*"
enablerepo: "internal-security-errata"
disable_plugin: "subscription-manager"
nobest: true
when: ansible_os_family == 'RedHat'
- name: "4.1 Post-remediation OpenSCAP OVAL evaluation"
ansible.builtin.command:
cmd: >
oscap oval eval
--results /var/tmp/openscap_oval/oval-results-post.xml
--report /var/tmp/openscap_oval/oval-report-post.html
{{ target_oval_stream }}
register: oscap_post_eval
changed_when: false
failed_when: oscap_post_eval.rc not in [0, 2]
Part B: OpenSCAP Scanning for Full Security Guide (XCCDF)
Part B1: Baseline Scanning & Policy Audit Reporting
This section covers Extensible Configuration Checklist Description Format (XCCDF) profile inspection, baseline compliance evaluation, and automated reporting.
Step 0: Inspecting Available Profiles in SCAP Security Guide
# Query profiles for installed DataStream
oscap info /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
Key profiles:
xccdf_org.ssgproject.content_profile_cis: CIS Benchmark (Level 1 / Level 2 Server).xccdf_org.ssgproject.content_profile_stig: DISA STIG Profile.xccdf_org.ssgproject.content_profile_pci-dss: PCI-DSS v3.2.1 Control Baseline.xccdf_org.ssgproject.content_profile_anssi_bp28_high: ANSSI BP-028 High Hardening.
Step 1: Direct CLI Command Line Execution (Part B1)
sudo mkdir -p /var/tmp/openscap_xccdf
sudo oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_cis \
--results /var/tmp/openscap_xccdf/cis-results-$(hostname -s).xml \
--report /var/tmp/openscap_xccdf/cis-report-$(hostname -s).html \
/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
Extract Score from Results XML:
XML_FILE="/var/tmp/openscap_xccdf/cis-results-$(hostname -s).xml"
SCORE=$(grep -oP '<score[^>]*>\K[0-9.]+' "$XML_FILE" | head -n 1)
echo "CIS Benchmark Compliance Score: ${SCORE}%"
Step 2: Automated Fleet Compliance Audit Using Ansible Playbooks (Part B1)
Declarative playbook: audit_xccdf_security_guide.yml.
---
- name: "Enterprise OpenSCAP XCCDF Baseline Compliance Audit (Part B1)"
hosts: fleet
gather_facts: true
become: false
vars:
target_report_html: "/var/tmp/openscap_xccdf/xccdf-report-{{ inventory_hostname }}.html"
target_results_xml: "/var/tmp/openscap_xccdf/xccdf-results-{{ inventory_hostname }}.xml"
controller_harvest_dir: "/home/operator/audit-reports/xccdf/{{ inventory_hostname }}"
tasks:
- name: "1.0 Dynamically select SCAP DataStream and Profile per host OS"
ansible.builtin.set_fact:
scap_datastream: >-
{%- if ansible_distribution | lower in ['rocky', 'almalinux', 'centos', 'redhat', 'oraclelinux', 'ol'] -%}
/usr/share/xml/scap/ssg/content/ssg-rhel{{ ansible_distribution_major_version }}-ds.xml
{%- elif ansible_distribution | lower in ['opensuse', 'sles', 'sled', 'suse'] -%}
/usr/share/xml/scap/ssg/content/ssg-sle15-ds.xml
{%- elif ansible_distribution | lower == 'ubuntu' and ansible_distribution_version in ['22.04', '24.04'] -%}
/usr/share/xml/scap/ssg/content/ssg-ubuntu{{ ansible_distribution_version | replace('.', '') }}-ds.xml
{%- elif ansible_distribution | lower == 'ubuntu' and ansible_distribution_version == '26.04' -%}
/usr/share/xml/scap/ssg/content/ssg-ubuntu2404-ds.xml
{%- elif ansible_distribution | lower == 'debian' and ansible_distribution_major_version in ['11', '12'] -%}
/usr/share/xml/scap/ssg/content/ssg-debian{{ ansible_distribution_major_version }}-ds.xml
{%- elif ansible_distribution | lower == 'debian' and ansible_distribution_major_version == '13' -%}
/usr/share/xml/scap/ssg/content/ssg-debian12-ds.xml
{%- else -%}
unsupported
{%- endif -%}
scap_profile: >-
{%- if ansible_distribution | lower == 'ubuntu' -%}
xccdf_org.ssgproject.content_profile_cis_level2_server
{%- elif ansible_distribution | lower == 'debian' -%}
xccdf_org.ssgproject.content_profile_standard
{%- else -%}
xccdf_org.ssgproject.content_profile_cis
{%- endif -%}
- name: "1.0b Fail if SCAP DataStream is unsupported for target host OS"
ansible.builtin.fail:
msg: "SCAP DataStream unsupported for {{ ansible_distribution }} {{ ansible_distribution_version }}"
when: scap_datastream == 'unsupported'
- name: "1.1 Create target and controller directories"
ansible.builtin.file:
path: "/var/tmp/openscap_xccdf"
state: directory
mode: "0755"
- name: "1.2 Create controller harvest directory"
ansible.builtin.file:
path: "{{ controller_harvest_dir }}"
state: directory
mode: "0755"
delegate_to: localhost
- name: "2.1 Execute OpenSCAP XCCDF compliance scan"
ansible.builtin.command:
cmd: >
oscap xccdf eval
--profile {{ scap_profile }}
--results {{ target_results_xml }}
--report {{ target_report_html }}
{{ scap_datastream }}
register: xccdf_eval_raw
changed_when: false
failed_when: xccdf_eval_raw.rc not in [0, 2]
- name: "3.1 Fetch HTML and XML reports to controller"
ansible.builtin.fetch:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
flat: true
loop:
- { src: "{{ target_report_html }}", dest: "{{ controller_harvest_dir }}/xccdf-report.html" }
- { src: "{{ target_results_xml }}", dest: "{{ controller_harvest_dir }}/xccdf-results.xml" }
- name: "4.1 Extract compliance score"
ansible.builtin.shell: |
grep -oP '<score[^>]*>\K[0-9.]+' {{ target_results_xml }} | head -n 1
register: compliance_score
changed_when: false
- name: "4.2 Display Compliance Scorecard"
ansible.builtin.debug:
msg:
- "=================================================================="
- "HOST: {{ inventory_hostname }} ({{ ansible_default_ipv4.address }})"
- "PROFILE: {{ scap_profile }}"
- "COMPLIANCE SCORE: {{ compliance_score.stdout | default('N/A') }}%"
- "REPORT: {{ controller_harvest_dir }}/xccdf-report.html"
- "=================================================================="
Part B2: Safeguarded Baseline Remediation (Protecting Critical Subsystems)
Applying OpenSCAP remediation rules blindly using --remediate or applying out-of-the-box CIS / STIG hardening playbooks without tailoring is one of the leading causes of self-inflicted production outages in enterprise environments.
- Clustered Signaling Failure (SCTP Protocol 132): Standard CIS rules disable the SCTP kernel module, immediately severing all clustered inter-node messaging links on port 29168.
- Relational Database Crashes (/tmp noexec): Standard benchmarks enforce
noexecon/tmpand/var/tmp. This immediately crashes PostgreSQL spatial extensions (PostGIS dynamic shared library compilation) and Oracle database shadow processes. - Container Routing Breakdown (Docker / Podman): Enforcing
net.ipv4.ip_forward = 0severs bridge routing, isolating all microservices on container application hosts. - Cryptographic Incompatibility: Enabling Kernel FIPS mode without careful planning breaks legacy client TLS/SSL ciphers and database connections.
Remediation Rule: You MUST generate dry-run fix scripts, audit every single rule against your application stack, and deploy a custom Tailoring profile (tailoring.xml) to explicitly de-select destructive rules prior to execution.
1. The Mission-Critical Application Subsystem Impact Matrix
| Vulnerable Rule Identifier | Standard SCAP Action | Affected Subsystems | Operational Failure Impact | Safeguarded Action |
|---|---|---|---|---|
rule_kernel_module_sctp_disabled |
Adds install sctp /bin/true |
Clustered Message Broker (dispatchd) |
FATAL: Disables SCTP Protocol 132. Clustered nodes cannot establish high-availability signaling on port 29168. | DO NOT EXECUTE. Keep SCTP enabled. |
rule_mount_option_tmp_noexec |
Mounts /tmp with noexec |
PostgreSQL 17, PostGIS, Oracle 19c | FATAL: PostgreSQL dynamic extension compilation (PostGIS) and Oracle shadow processes crash when executing temporary code in /tmp. |
DO NOT EXECUTE. Omit noexec on /tmp. |
rule_sysctl_net_ipv4_ip_forward |
Sets net.ipv4.ip_forward = 0 |
Microservice Container Hosts (Podman/Docker) | FATAL: Shuts down container packet forwarding. Microservices lose network reachability. | DO NOT EXECUTE. Maintain ip_forward=1. |
rule_enable_fips_mode |
Enables Kernel FIPS 140-2 mode | API Gateway, Ingress HAProxy | FATAL: Breaks legacy client encryption protocols and proprietary SSL cipher suites. | DO NOT EXECUTE. Maintain standard crypto policies. |
2. Generating and Inspecting Remediation Fixes (Dry-Run Review)
# Generate Bash Remediation Script
oscap xccdf generate fix \
--profile xccdf_org.ssgproject.content_profile_cis \
--fix-type bash \
--output /tmp/cis_remediation_raw.sh \
/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
# Audit raw script for destructive rules
grep -n "sctp" /tmp/cis_remediation_raw.sh
grep -n "noexec" /tmp/cis_remediation_raw.sh
grep -n "ip_forward" /tmp/cis_remediation_raw.sh
3. Creating a Custom Tailoring Profile (tailoring.xml)
Create an OpenSCAP Tailoring file (tailoring.xml) to explicitly exclude destructive rules:
<?xml version="1.0" encoding="UTF-8"?>
<xccdf:Tailoring xmlns:xccdf="http://checklists.nist.gov/xccdf/1.2" id="xccdf_custom_tailoring">
<xccdf:benchmark href="/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml"/>
<xccdf:version time="2026-10-07T17:00:00">1</xccdf:version>
<!-- 1. Safeguarded Profile for RHEL, Ubuntu, and SUSE (Derived from CIS Profile) -->
<xccdf:Profile id="xccdf_org.ssgproject.content_profile_cis_custom_safe" extends="xccdf_org.ssgproject.content_profile_cis">
<xccdf:title>CIS Benchmark (Safeguarded Enterprise Web & Clustered Profile)</xccdf:title>
<xccdf:description>CIS profile tailored to exclude destructive rules that impact SCTP cluster links, container forwarding, and database shared memory.</xccdf:description>
<!-- EXCLUDE SCTP DISABLE RULE (Preserves Clustered Inter-Node Signaling) -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_kernel_module_sctp_disabled" selected="false"/>
<!-- EXCLUDE TMP NOEXEC (Preserves PostgreSQL PostGIS & Oracle dynamic compilation) -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_mount_option_tmp_noexec" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_mount_option_var_tmp_noexec" selected="false"/>
<!-- EXCLUDE IP FORWARDING DISABLE (Preserves Podman & Container bridge routing) -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_ip_forward" selected="false"/>
<!-- EXCLUDE AUTOMATIC FIPS ENFORCEMENT -->
<xccdf:select idref="xccdf_org.ssgproject.content_rule_enable_fips_mode" selected="false"/>
</xccdf:Profile>
<!-- 2. Safeguarded Profile for Debian GNU/Linux (Derived from Standard Profile bound to ssg-debian12-ds.xml) -->
<xccdf:Profile id="xccdf_org.ssgproject.content_profile_standard_custom_safe" extends="xccdf_org.ssgproject.content_profile_standard">
<xccdf:title>Debian Standard Baseline (Safeguarded Enterprise Profile)</xccdf:title>
<xccdf:description>Debian standard profile tailored to exclude destructive network and filesystem mount restrictions.</xccdf:description>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_ip_forward" selected="false"/>
<xccdf:select idref="xccdf_org.ssgproject.content_rule_mount_option_tmp_noexec" selected="false"/>
</xccdf:Profile>
</xccdf:Tailoring>
Step 4: Direct CLI Execution with Tailored Remediation (Part B2)
# Execute safe tailored remediation
sudo oscap xccdf eval \
--tailoring-file tailoring.xml \
--profile xccdf_org.ssgproject.content_profile_cis_custom_safe \
--remediate \
--results /var/tmp/openscap_xccdf/cis-results-remediated.xml \
--report /var/tmp/openscap_xccdf/cis-report-remediated.html \
/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
Step 5: Production-Grade Declarative Ansible Playbook for Safeguarded Remediation (Part B2)
Playbook: remediate_safeguarded_security_guide.yml.
---
- name: "Enterprise Safeguarded Baseline Remediation (Part B2)"
hosts: fleet
serial: 1
gather_facts: true
become: true
vars:
tailoring_file_src: "files/tailoring.xml"
tailoring_file_dest: "/etc/security/scap-tailoring.xml"
tasks:
- name: "1.0 Dynamically select SCAP DataStream and Safe Profile per host OS"
ansible.builtin.set_fact:
scap_datastream: >-
{%- if ansible_distribution | lower in ['rocky', 'almalinux', 'centos', 'redhat', 'oraclelinux', 'ol'] -%}
/usr/share/xml/scap/ssg/content/ssg-rhel{{ ansible_distribution_major_version }}-ds.xml
{%- elif ansible_distribution | lower in ['opensuse', 'sles', 'sled', 'suse'] -%}
/usr/share/xml/scap/ssg/content/ssg-sle15-ds.xml
{%- elif ansible_distribution | lower == 'ubuntu' and ansible_distribution_version in ['22.04', '24.04'] -%}
/usr/share/xml/scap/ssg/content/ssg-ubuntu{{ ansible_distribution_version | replace('.', '') }}-ds.xml
{%- elif ansible_distribution | lower == 'ubuntu' and ansible_distribution_version == '26.04' -%}
/usr/share/xml/scap/ssg/content/ssg-ubuntu2404-ds.xml
{%- elif ansible_distribution | lower == 'debian' and ansible_distribution_major_version in ['11', '12'] -%}
/usr/share/xml/scap/ssg/content/ssg-debian{{ ansible_distribution_major_version }}-ds.xml
{%- elif ansible_distribution | lower == 'debian' and ansible_distribution_major_version == '13' -%}
/usr/share/xml/scap/ssg/content/ssg-debian12-ds.xml
{%- else -%}
unsupported
{%- endif -%}
safe_profile: >-
{%- if ansible_distribution | lower == 'debian' -%}
xccdf_org.ssgproject.content_profile_standard_custom_safe
{%- else -%}
xccdf_org.ssgproject.content_profile_cis_custom_safe
{%- endif -%}
- name: "1.0b Fail if SCAP DataStream is unsupported for target host OS"
ansible.builtin.fail:
msg: "SCAP DataStream unsupported for {{ ansible_distribution }} {{ ansible_distribution_version }}"
when: scap_datastream == 'unsupported'
# -------------------------------------------------------------------------
# 1. PRE-FLIGHT SUBSYSTEM HEALTH CHECK (ENFORCING ASSERTIONS)
# -------------------------------------------------------------------------
- name: "1.1 Assert core message engine daemon is running prior to remediation"
ansible.builtin.command:
cmd: "pgrep -a dispatchd"
register: msg_proc
changed_when: false
failed_when: msg_proc.rc != 0
when: "'core-msg' in inventory_hostname"
- name: "1.2 Assert container manager is active prior to remediation"
ansible.builtin.command:
cmd: "podman ps -q"
register: container_proc
changed_when: false
failed_when: container_proc.rc != 0
when: "'svc-container' in inventory_hostname"
# -------------------------------------------------------------------------
# 2. DEPLOY AND VALIDATE TAILORED PROFILE
# -------------------------------------------------------------------------
- name: "2.1 Deploy verified SCAP tailoring XML"
ansible.builtin.copy:
src: "{{ tailoring_file_src }}"
dest: "{{ tailoring_file_dest }}"
mode: "0644"
- name: "2.2 Validate tailoring file structure prior to remediation"
ansible.builtin.command:
cmd: "oscap info {{ tailoring_file_dest }}"
register: tailoring_val
changed_when: false
- name: "2.3 Validate SCAP DataStream content prior to remediation"
ansible.builtin.command:
cmd: "oscap info {{ scap_datastream }}"
register: datastream_val
changed_when: false
# -------------------------------------------------------------------------
# 3. EXECUTE SAFE TAILORED REMEDIATION
# -------------------------------------------------------------------------
- name: "3.1 Execute OpenSCAP tailored remediation"
ansible.builtin.command:
cmd: >
oscap xccdf eval
--tailoring-file {{ tailoring_file_dest }}
--profile {{ safe_profile }}
--remediate
--results /var/tmp/openscap_xccdf/xccdf-results-remediated.xml
--report /var/tmp/openscap_xccdf/xccdf-report-remediated.html
{{ scap_datastream }}
register: rem_out
changed_when: true
failed_when: rem_out.rc not in [0, 2]
# -------------------------------------------------------------------------
# 4. POST-REMEDIATION INVARIANT ASSERTIONS
# -------------------------------------------------------------------------
- name: "4.1 CRITICAL ASSERTION: Verify SCTP module remains loadable"
ansible.builtin.command:
cmd: "modprobe -n -v sctp"
register: sctp_mod
changed_when: false
failed_when: "'install /bin/true' in sctp_mod.stdout or sctp_mod.rc != 0"
- name: "4.2 CRITICAL ASSERTION: Verify IP forward enabled on container node"
ansible.builtin.command:
cmd: "sysctl -n net.ipv4.ip_forward"
register: ip_fwd
changed_when: false
failed_when: ip_fwd.stdout.strip() != '1'
when: "'svc-container' in inventory_hostname"
# -------------------------------------------------------------------------
# 5. HARVEST POST-REMEDIATION SCORECARD
# -------------------------------------------------------------------------
- name: "5.1 Extract post-remediation compliance score"
ansible.builtin.shell: |
grep -oP '<score[^>]*>\K[0-9.]+' /var/tmp/openscap_xccdf/xccdf-results-remediated.xml | head -n 1
register: post_score
changed_when: false
- name: "5.2 Display Remediation Completion Report"
ansible.builtin.debug:
msg:
- "=================================================================="
- "HOST: {{ inventory_hostname }}"
- "STATUS: SAFEGUARDED REMEDIATION COMPLETED"
- "NEW COMPLIANCE SCORE: {{ post_score.stdout | default('N/A') }}%"
- "SUBSYSTEM HEALTH: ALL APPLICATION INVARIANTS SATISFIED"
- "=================================================================="
Appendices & Operational Reference Cheatsheet
1. Master OpenSCAP CLI Command Matrix
| Administrative Task | OpenSCAP CLI Invocation | Expected Exit Codes |
|---|---|---|
| Inspect SCAP DataStream | oscap info <datastream.xml> |
0 = OK |
| Inspect OVAL Definitions | oscap info <oval.xml> |
0 = OK |
| Run OVAL Scan (Part A1) | oscap oval eval --results res.xml --report rep.html <oval.xml> |
0 = Completed (Inspect XML/HTML), 1 = Error |
| Run XCCDF Scan (Part B1) | oscap xccdf eval --profile <prof> --results res.xml --report rep.html <ds.xml> |
0 = Pass, 2 = Fail |
| Generate Fix Script (Bash) | oscap xccdf generate fix --profile <prof> --fix-type bash <ds.xml> > fix.sh |
0 = OK |
| Generate Fix (Ansible) | oscap xccdf generate fix --profile <prof> --fix-type ansible <ds.xml> > fix.yml |
0 = OK |
| Run Tailored Scan | oscap xccdf eval --tailoring-file tail.xml --profile <tail_prof> ... |
0 = Pass, 2 = Fail |
| Run Safe Remediation (Part B2) | oscap xccdf eval --tailoring-file tail.xml --profile <tail_prof> --remediate ... |
0 = Pass, 2 = Fail |
2. Common Exit Code Diagnostic Matrix
| Exit Code | Diagnostic Meaning | Recommended Administrative Action |
|---|---|---|
0 |
100% Evaluation Pass / Full Compliance | System satisfies all checked rules. Save HTML/XML reports as signed audit proof. |
2 |
Evaluation completed; rule failures/vulnerabilities detected | Expected normal audit result. Do NOT treat as automation failure; inspect HTML report. |
1 |
Fatal error (missing file, invalid XML, syntax error) | Check file paths, verify XML namespace, and ensure oscap has read permissions. |
| ASIMP (Ansible System Integrity Management Platform) | Deep State of Mind (DSOM) For My AI Protocol | Harisfazillah Jamel (LinuxMalaysia) | 2026-07-12 Standard: UK English | DBP-standard Bahasa Melayu Malaysia (Piawai) | GNU General Public License v3.0 | Legal Notice & Disclaimer |