Automate RHEL 10 STIG Hardening with rhel10-ansible-lockdown

If you’ve ever had to manually work through a DISA STIG checklist for a Red Hat Enterprise Linux system, you know the pain. Hundreds of controls, dozens of config files, and one missed setting away from a failed audit. I build the rhel10-ansible-lockdown to take away that pain and mirror the RHEL9 ansible content that DISA provides.

rhel10-ansible-lockdown is a fully automated Ansible framework (likely buggy) that applies 434 controls from the RHEL 10 STIG (current as of February 2026 by DISA).

What Makes It Different

Most STIG automation tools are black boxes. You run them, something changes, and you hope for the best. This tool is built differently:

  • One file per control. Each of the 434 STIG controls lives in its own task file with the full STIG description, check text, and fix text embedded in its comments. You always know exactly what a task does and why.
  • Every control is toggleable. Don’t want to enforce NFS or GDM removal? Set the control the false and it’s skipped. No hacking playbooks required.
  • Nothing stops on failure. Every task uses a rescue block so a single failing control doesn’t halt your entire hardening run. Fix those missed failures manually.
  • Splunk-ready output. Every asset message uses structured formatting for easy ingestion and dashboarding.
  • Interactive customizer included. A built-in Python TUI lets you browse all 434 controls and toggle them on or off before running. No need to edit YAML (or even understand it).

Requirements

  • Ansible >= 2.14 on the local system or control node (part of the default RedHat 10 repository)
  • Python >= 3.9 (also part of the default RedHat 10 repository)
  • Running RHEL10 (common sense but we never know nowadays)

Getting Started in 3 Easy Steps

Step 1 – Clone the repository

git clone https://github.com/tgtechacademy/rhel10-lockdown.git
cd rhel10-lockdown

Step 2 – Customize Which Controls to Run (Optional)

If you need to disable specific controls before running (for example, if NFS is a legitimate requirement in your environment) launch the interactive customizer:

python customize.py

Use the arrow keys to browse all 434 controls, press i to read the full description and fix text for any item and press space to toggle a control on or off. When done, press s to save your selections to vars/main.yml (can edit manually if you choose to do so) and q to quit.

Step 3 – Run the Playbook (as root)

./enforce.sh

That’s it. A playbook will launch against all 434 controls, remediations will occur where needed, and a full Ansible run log can be ingested straight into Splunk or reviewed manually. Note: some controls will require manual remediate.

Optional: Run Only What You Need

The framework also supports granular tag-based execution:

# HIGH severity controls only
./enforce.sh --tags high

# A single specific control
./enforce.sh --tags RHEL-10-700970

# Everything except LOW severity
./enforce.sh --skip-tags low

# Target a single host from your inventory
./enforce.sh --limit my-server

GitHub Project

https://github.com/tylergross/rhel10-ansible-lockdown

Prev