Ansible + OpenSCAP For Compliance Automation
Ansible is powerful orchestration tool we use exclusively internally for managing all of our systems. There’s nothing that runs on our network that isn’t managed entirely through Ansible.
SCAP is a line of standards managed by NIST. It was created to provide a standardized approach to maintaining the security of systems, such as automatically verifying the presence of patches, checking system security configuration settings, and examining systems for signs of compromise.
We can combine the two to perform automated compliance checking against a fleet of hosts.
Side Note: Selecting a Policy
Selecting a policy is mostly beyond the scope of this article.
On RHEL-based systems, you can query the list of installed SCAP documents like so
rpm -ql scap-security-guide | grep -E 'ssg-.*-ds.xml'
…and the profiles contained within each by running the
oscap info command
oscap info /usr/share/xml/scap/ssg/content/ssg-rhel7-ds.xml
This will give you, amongst other bits of information, a list of profiles
xccdf_org.ssgproject.content_profile_pci-dss profile, for example, corresponds to the PCI Data Security Standard profile on RHEL 7.
Running a Scan
You can easily run a scan of a single local system with the
oscap xccdf eval command, passing it the name of the desired profile and the file that it resides in.
oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_pci-dss \
--report /tmp/oscap-report.html \
This will generate a rich HTML report at
/tmp/oscap-report.html for viewing.
Automating the Scan
We can use Ansible’s
fetch modules to run reports on remote hosts and pull all the reports back to a single machine. The advantage of this is that we already have our entire fleet under the inventory.
Here’s an example playbook which, in sequence
- Installs and updates OpenSCAP and the security guide
- Runs a scan
- Downloads the generated HTML report and stores it under the inventory hostname in a folder
- Fails if the scan fails
Running the scans is as simple as running the playbook:
Now you have a way to quickly find hosts that are non-compliant as they will show up as
failed in the Ansible play summary.
The exit code of Ansible will also reflect this failed state, making it ideal for integration into a CI system.
PLAY RECAP *******************************************
host01 : ok=2 changed=1 unreachable=0 failed=0
host02 : ok=1 changed=1 unreachable=0 failed=1
You can then quickly determine what the issues are by referring to its report, and what steps to take to remediate it.
The power of Ansible also means we can define different policies for different host groups or environments.
We can run these reports nightly (or on whatever frequency is appropriate) to ensure we never fall out of compliance. You could even bake this step into your base image testing — food for another post perhaps.