Guide

RHEL 8 STIG remediation, explained for engineers

The DISA Red Hat Enterprise Linux 8 STIG is several hundred rules long, written in assessment language rather than operator language. This guide explains what the benchmark actually asks for, how to measure where a host stands, how to automate the majority of the fixes with Ansible or shell, and which rules you should never let a script decide.

How the RHEL 8 STIG is built

Each rule carries a group ID, a rule ID, a severity of CAT I, CAT II or CAT III, and one or more CCIs (Control Correlation Identifiers). The CCI is the important part: it is the link from a Linux configuration setting back to a NIST SP 800-53 control. That is why the same remediation work can satisfy an audit requirement, a logging requirement and an authentication requirement at once.

Severity is a statement about the rule, not about your host. CAT I findings are the ones that permit direct compromise: remote root logins, disabled authentication, unsupported packages. CAT II is the bulk of the benchmark. CAT III rules harden defence in depth and are usually the safest to automate first.

Two artifacts matter in practice. The DISA STIG itself is distributed as an XCCDF benchmark plus a manual review guide. The SCAP Security Guide (the scap-security-guide package, built from the open-source ComplianceAsCode project) ships a machine-readable DISA STIG profile for RHEL 8 together with generated Ansible and Bash remediation content. Scan with the second, report against the first.

Step 1: measure before you fix

Never start with a remediation playbook. Start with a baseline scan so you can prove what changed and roll back to a known state.

sudo dnf install -y openscap-scanner scap-security-guide

sudo oscap xccdf eval \
  --profile xccdf_org.ssgproject.content_profile_stig \
  --results /tmp/rhel8-stig-before.xml \
  --report /tmp/rhel8-stig-before.html \
  /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml

The command exits non-zero when any rule fails, which is expected on a first run, so do not let it fail your pipeline. The HTML report is the human view; the XML results file is what you diff against after remediation, and what feeds an eMASS or OSCAL assessment result later.

Step 2: generate remediation, do not hand-write it

OpenSCAP can emit remediation content scoped to exactly the rules that failed on this host. This is far safer than applying a whole-benchmark playbook, because it does not touch rules that already pass.

# Ansible playbook for the failed rules only
sudo oscap xccdf generate fix \
  --fix-type ansible \
  --result-id "" \
  /tmp/rhel8-stig-before.xml > rhel8-stig-fix.yml

# Or a shell script, for hosts with no Ansible control node
sudo oscap xccdf generate fix \
  --fix-type bash \
  --result-id "" \
  /tmp/rhel8-stig-before.xml > rhel8-stig-fix.sh

Read the generated file before running it. Every task is tagged with its rule ID and severity, so you can drop individual tasks with an Ansible --skip-tags rather than editing the file and losing the ability to regenerate it.

ansible-playbook -i inventory rhel8-stig-fix.yml \
  --check --diff \
  --skip-tags "partition,reboot_required"

Run in check mode first, on one host, in a non-production environment. Then run for real, reboot, and re-scan. The delta between the two results files is your evidence.

Step 3: build it in, do not bolt it on

Remediating a running host is the expensive path. The cheap path is applying the STIG profile at install time, so every host starts compliant and drift is the only thing you ever have to chase. Anaconda accepts an OSCAL-adjacent kickstart addon that runs the profile during installation:

%addon org_fedora_oscap
  content-type = scap-security-guide
  profile = xccdf_org.ssgproject.content_profile_stig
%end

For image-based fleets, run the same profile in your image build (Image Builder, Packer, or a container build for UBI-based workloads) and store the resulting scan report alongside the image as its birth certificate. Then schedule a periodic scan on running hosts and alert on newly failing rules. That recurring delta is drift, and drift is what auditors find.

What not to automate

A generated playbook will happily brick a host. These categories deserve a human decision every time.

Partition layout

Separate filesystems for /var, /var/log, /var/log/audit, /home and /tmp are STIG requirements that cannot be applied safely after installation. Bake them into your kickstart or image build instead of trying to remediate a running host.

FIPS mode

Enabling FIPS with fips-mode-setup requires a reboot and can break agents or TLS clients that negotiate non-approved algorithms. Enable it in a build pipeline, then re-run the scan on the rebooted host.

Session and login banners

The banner text is fixed by DoD policy and is easy to automate, but the check is byte-exact. Store the approved text as a file in your repository rather than embedding it in a playbook string.

USBGuard, AIDE, audit rules

Automated fixes install and enable these, but the resulting policy still needs tuning for your workload. An enabled service with a default policy passes the check and can still be operationally wrong.

Documented exceptions

Some rules genuinely do not apply, such as a container host with no graphical target, an appliance with a vendor-managed kernel. Mark these Not Applicable with a written justification rather than forcing a fix that breaks the system.

Reporting the result

A pass rate on its own is not an answer, because it hides the denominator. Report the number of rules evaluated, the number passed, the number failed by severity, and the number marked Not Applicable with a justification. Rules that could not be evaluated are not passes.

Because each rule carries CCIs, the same scan result also answers the control-level question: which NIST 800-53 controls are now satisfied on this host, and which remain open. That mapping is published, it should be looked up rather than guessed, and it is the bridge between a Linux scan report and a System Security Plan.

Where SecBaseline fits

The STIG Explainer turns individual RHEL 8 rules into plain English and shows the NIST 800-53 controls behind them. The crosswalk pivots those rules against CIS Benchmark recommendations so you can see where one piece of hardening work covers both. OSCAL Bridge expresses the same control data in machine-readable form, and SSP Studio drafts the plan narrative from the controls you actually applied.

Important

This guide is an explanation, not an authorisation. The DISA RHEL 8 STIG is revised regularly, so always work from the current release published on the DoD Cyber Exchange, and validate every automated fix against your own system owner and authorising official. SecBaseline is not affiliated with DISA, DoD, or the Center for Internet Security.

Back to the tool directory.