Red Hat® Ansible® Automation is a powerful tool for automating the configuration of systems. By running a predefined file called an Ansible Playbook, you can quickly configure the system according to your needs.
Ansible Automation can easily be used for security compliance automation, because it allows you to keep your system hardened, and it can operate on a large scale. Using Ansible Automation, you can set everything you need, including minimal password lengths, firewall rules, package installation, or the disabling of services.
ComplianceAsCode
works great with Ansible Automation.
ComplianceAsCode
connects a human-readable security policy with Ansible tasks that implement the settings required by the security policy.
The rules in ComplianceAsCode
profiles contain Ansible tasks that configure the system to conform to the rule.
From these Ansible tasks and rule metadata, ComplianceAsCode
generates an Ansible Playbook that you can use to harden your system.
After running the playbook, your system meets the requirements of the security policy.
ComplianceAsCode
generates a playbook for each profile that conforms to the profile definition.
Moreover, it generates separate playbooks for every rule.
-
Learn how to add an Ansible task for a rule
-
Learn how to leverage
ComplianceAsCode
structure when creating Ansible content -
Learn how to generate Ansible Playbooks from a
ComplianceAsCode
repository -
Learn how to use the Ansible Playbooks generated by
ComplianceAsCode
Important
|
Content used in this lab has been altered to increase its educative potential, and is therefore different from the content in ComplianceAsCode upstream repository or the content in the scap-security-guide package shipped in Red Hat® products. |
-
The
ComplianceAsCode
repository was already cloned. -
Ansible Automation was installed.
-
The following dependencies required for the
ComplianceAsCode
content build were installed usingyum install
:-
Generic build utilities:
cmake
andmake
, -
Utilities for generating SCAP content:
openscap-scanner
-
Python dependencies for putting content together:
python3-pyyaml
andpython3-jinja2
-
The ComplianceAsCode
project consists of human-readable files that are compiled into standard-compliant files that are difficult to read and edit directly.
For your convenience, the environment is already set up, so the content is built and ready to be used. No worries, though—you get to rebuild it later in the exercise.
To start the hands-on section, take the following steps:
-
Go to: Lab 4 Environment
-
Wait until all the steps being executed in the terminal are complete.
Ansible tasks can be attached to every rule in a ComplianceAsCode
project.
A lot of rules already contain Ansible tasks.
As an example, you add a new Ansible task for the accounts_tmout
rule.
You have already encountered this rule in Lab Exercise 1
.
This rule is about the interactive session timeout for inactive users.
Terminating an idle session within a short time period reduces the risk of unauthorized operations.
The Ansible task that you add configures the session timeout in the respective configuration file.
You work in the context of Red Hat® Enterprise Linux® 8 (RHEL 8) product and the OSPP profile for Red Hat® Enterprise Linux® 8,
but the structure is the same for all rules in ComplianceAsCode
.
As you already know from Lab Exercise 1, source code for the accounts_tmout
rule is located in the linux_os/guide/system/accounts/accounts-session/accounts_tmout
directory.
-
Switch to the rule directory and examine its content.
[... ]$ cd linux_os/guide/system/accounts/accounts-session/accounts_tmout [... accounts_tmout]$ ls bash oval rule.yml tests
As you learned in previous lab exercises, the
rule.yml
file contains the rule description, rationale, and metadata.NoteApart from
rule.yml
, there are also three subdirectories in theaccounts_tmout
directory:-
bash
contains source code for a Bash script that can fix the timeout settings, also called "Bash remediation." -
oval
contains source code for an OVAL check that checks if the timeout is set. -
tests
contains test scenarios which are used to test checks and remediations of a rule.
-
-
To add Ansible tasks in this rule, you first create a new directory called
ansible
in the rule directory, at the same level as thebash
andoval
directories. Create a newansible
directory and change into it:[... accounts_tmout]$ mkdir ansible [... ansible]$ cd ansible
-
Next, you create a new file in this directory that contains your Ansible task.
NoteIn
ComplianceAsCode
, the file needs to have a specific name. You have two options:-
shared.yml
is an universal name, the "shared" in this context means that the task can be applied to any product—that is, any Linux distribution. -
product_id.yml
, (for example,fedora.yml
), can be used if the task is specific to a single Linux distribution and cannot be extended to other Linux distributions.
-
-
Because the interactive session timeout is not a specific feature of RHEL 8, but is handled the same way in most Linux distributions, you can name the file
shared.yml
. Create a newshared.yml
file in theansible
directory and open it in the text editor.[... ansible]$ open shared.yml
-
Next, you start to write the Ansible content in this file. It is not in the format of an Ansible Playbook—instead, it uses a special format. It is a simple YAML file.
The first part of this file must be a header that helps the build system integrate the Ansible tasks with the SCAP content and also with the rule metadata.
Add the following content to the top of the
shared.yml
file, including the#
characters. If you want to copy and paste the text, you have to useCtrl+V
to paste it:# platform = multi_platform_all # reboot = false # strategy = restrict # complexity = low # disruption = low
Do not close the file yet.
NoteThe header contains optional metadata. The
platform
andreboot
fields have well-defined meanings:-
platform
is a comma-separated list of products that the Ansible tasks are applicable to. It can be an operating system name such asRed Hat Enterprise Linux 8
, or a wildcard string that matches multiple products—for example,multi_platform_rhel
. Here we use the wildcard string,multi_platform_all
, that matches all of the possible platforms. -
reboot
specifies if a reboot is needed to activate the settings. This can be eithertrue
orfalse
. Here, we signal that a reboot is not needed. This value is purely informational and setting it totrue
does not cause Ansible Automation to reboot the system.
The other fields are optional, and their meanings are fuzzier:
-
strategy
is the method or approach for making the described fix. It is typically one of the following:configure
,disable
,enable
,patch
,restrict
, orunknown
. -
complexity
is the estimated complexity or difficulty of applying the fix to the target. It can beunknown
,low
,medium
, orhigh
. -
disruption
is an estimate of the potential for disruption or operational degradation that the application of this fix imposes on the target. It can beunknown
,low
,medium
, orhigh
.
-
-
Now, you add an Ansible task or tasks for this rule below the header in
shared.yml
. Add the following content at the end of theshared.yml
file. Again, do not close the file just yet.- name: configure timeout lineinfile: create: yes dest: /etc/profile regexp: "^#?TMOUT" line: "TMOUT=600"
At this point, expect the entire file to look like this:
# platform = multi_platform_all # reboot = false # strategy = restrict # complexity = low # disruption = low - name: configure timeout lineinfile: create: yes dest: /etc/profile regexp: "^#?TMOUT" line: "TMOUT=600"
NoteIf you are familiar with Ansible Automation, you probably know that you just wrote an Ansible task. Normally, Ansible tasks are low-level components of Ansible Playbooks. The
ComplianceAsCode
project allows content contributors to focus on tasks, and the playbook that aggregates them is generated by the project. When writing tasks, you can use the standard Ansible syntax and write the Ansible tasks the exact same way as you write in Ansible Playbooks. You can use any Ansible module.Using Ansible language, you have defined a new Ansible task with the name "configure timeout". It uses the lineinfile Ansible module, which can add, modify, and remove lines in configuration files. Using the
lineinfile
module, you insert the lineTMOUT=600
to/etc/profile
.Note that the
regexp
line defines a regular expression that determines what Ansible Automation is going to do. If the regular expression matches a line, it is substituted withline
, so the linesTMOUT=1800
and#TMOUT=600
are replaced byTMOUT=600
. If no line matches the regular expression, contents ofline
are simply appended todest
, which in this case is/etc/profile
.In this rule, you add only a single Ansible task. If your goals need to be achieved by multiple Ansible tasks, they all go into the same file.
In
ComplianceAsCode
, the general rule is that the Ansible tasks must conform to the rule description inrule.yml
for the given rule. Tasks must not do anything different than what therule.yml
description requires. Think of the rule description as a natural language specification of what needs to be implemented in Ansible Automation.
At this point, your task does not fully conform to the rule description in rule.yml
.
The difference is that rule.yml
does not define a specific value for the timeout.
-
Check that
rule.yml
does not specify whether the timeout should be 600 seconds or a different amount of time. In fact, the rule is parameterized by a variable,var_accounts_tmout
. The specific value for a timeout variable is set by settingvar_accounts_tmout
in the profile definition. This way, every profile can define a different timeout but still reuse the same source code.You need to fix the Ansible task to use the
var_accounts_tmout
variable instead of explicitly setting 600 seconds in the task. The general format for binding a variable fromComplianceAsCode
profiles is{{{ ansible_instantiate_variables("var_accounts_tmout") }}}
. -
Add the following line right after the
# disruption = low
line in theshared.yml
file:{{{ ansible_instantiate_variables("var_accounts_tmout") }}}
Now, you can use the bound variable in the
configure timeout
Ansible task as an Ansible variable using the standard Ansible syntax. When theshared.yml
file is processed by theComplianceAsCode
build system, this variable binding is resolved automatically and a new Ansible variable is created in thevars
list in the generated playbook. -
Replace
line: "TMOUT=600"
withline: "TMOUT={{ var_accounts_tmout }}"
to use the variable in the task.At this point you have completed adding Ansible tasks for the
accounts_tmout
rule. Expect the contents of theshared.yml
file to look like this:# platform = multi_platform_all # reboot = false # strategy = restrict # complexity = low # disruption = low {{{ ansible_instantiate_variables("var_accounts_tmout") }}} - name: configure timeout lineinfile: create: yes dest: /etc/profile regexp: ^#?TMOUT line: "TMOUT={{ var_accounts_tmout }}"
-
You can now save the file by pressing
Ctrl+S
to save the file.
You now generate a playbook for the accounts_tmout
rule you modified.
You do this in the context of the Red Hat® Enterprise Linux® 8 product and the OSPP profile for Red Hat® Enterprise Linux® 8.
To generate Ansible Playbooks, a complete build of the content for the product needs to be performed. That means that all of the other playbooks for all of the other rules are generated as well. Moreover, the SCAP content is also generated.
-
Go back to the project root directory and run the following command to build the RHEL 8 product:
[... ansible]$ cd /workspace/content [... ]$ ADDITIONAL_CMAKE_OPTIONS="-DSSG_ANSIBLE_PLAYBOOKS_PER_RULE_ENABLED=ON" ./build_product rhel8
-
The Playbooks are generated in the
build/rhel8/playbooks
directory. Check the contents of this directory:[... ]$ ls build/rhel8/playbooks all anssi_bp28_high anssi_bp28_minimal cis_server_l1 cis_workstation_l2 cui hipaa ospp rht-ccp stig anssi_bp28_enhanced anssi_bp28_intermediary cis cis_workstation_l1 cjis e8 ism_o pci-dss standard stig_gui
Note that there is a directory for each profile in the RHEL8 product. That is because each profile consists of a different set of rules and the rules are parameterized by variables which can have different values in each profile.
-
The
accounts_tmout
rule is, for example, a part of the OSPP profile, so take a peek into theospp
directory:[... ]$ ls build/rhel8/playbooks/ospp
There are many playbook files in the
ospp
directory. One of them is theaccounts_tmout.yml
file, which is the Ansible Playbook that contains the Ansible tasks you added in theaccounts_tmout
rule. -
Open it in the text editor:
[... ]$ open build/rhel8/playbooks/ospp/accounts_tmout.yml
The contents of the
build/rhel8/playbooks/ospp/accounts_tmout.yml
file look like this:# platform = multi_platform_all # reboot = false # strategy = restrict # complexity = low # disruption = low - name: Set Interactive Session Timeout hosts: '@@HOSTS@@' become: true vars: var_accounts_tmout: '600' tags: - CCE-80673-7 - NIST-800-171-3.1.11 - NIST-800-53-AC-12 - NIST-800-53-AC-2(5) - NIST-800-53-CM-6(a) - NIST-800-53-SC-10 - accounts_tmout - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy tasks: - name: configure timeout lineinfile: create: true dest: /etc/profile regexp: ^#?TMOUT line: TMOUT={{ var_accounts_tmout }}
TipIf you see a typo in the YAML file, edit the source again and rebuild.
This is a normal Ansible Playbook that Ansible users are familiar with. The name of the playbook is the same as the title of the rule, which is defined in
rule.yml
. -
The
hosts
section contains only a placeholder string,'@@HOSTS@@'
, which needs to be replaced by a list of IP addresses or hosts that the playbook applies to. You have to edit this in order to check the playbook. To use your playbook on your environment (on a local host), replace'@@HOSTS@@'
with'localhost'
and pressCtrl+S
to save the file.[... ]$ open build/rhel8/playbooks/ospp/accounts_tmout.yml ... - name: Set Interactive Session Timeout hosts: 'localhost' become: true ...
Note that the timeout value supplied by the
var_accounts_tmout
variable was set to a specific value (600 seconds) during the build process, and the variable was added to thevars
section of the playbook.Note also that the playbook has tags in the
tags
section that were added based on metadata inrule.yml
. At the beginning, it contains the CCE (Common Configuration Enumeration) identifier. Finally, thetasks:
section contains the Ansible task that you created. -
Run the playbook:
[... ]$ ansible-playbook build/rhel8/playbooks/ospp/accounts_tmout.yml
-
Check if it has any effect:
[... ]$ cat /etc/profile
Note that
TMOUT=600
is at the end of the file!The biggest advantage of using Ansible tasks in
ComplianceAsCode
is that it gets integrated with the SCAP content, the HTML report, and the HTML guide as well. -
Navigate to the
build/guides
folder.: -
Right click the
ssg-rhel8-guide-ospp.html
file and selectOpen with Live Server
to preview the file. Note: Your browser may block the pop-up. You must allow it when asked. -
A new tab opens and you can see your
OSPP
profile, which contains two rules. -
Check the "Set Interactive Session Timeout" rule. Click the blue
(show)
link to the right of the green "Remediation Ansible snippet" label and you see your recently added Ansible content.
In the previous section, you learned about using a playbook for the accounts_tmout
rule.
However, security policies are usually complex, which in turn means that profiles consist of many rules.
It is not convenient to have a separate Ansible Playbook for each rule, because that means you need to apply many Ansible Playbooks to the system.
Fortunately, ComplianceAsCode
also generates Ansible Playbooks that contain all of the tasks for a given profile in a single playbook.
The playbooks are located in the build/ansible
directory.
This directory contains Ansible Playbooks for each profile.
The Playbooks files have .yml
extension.
[... ]$ ls build/ansible all-profile-playbooks-rhel8 rhel8-playbook-anssi_bp28_minimal.yml rhel8-playbook-cis.yml rhel8-playbook-hipaa.yml rhel8-playbook-rht-ccp.yml rhel8-playbook-anssi_bp28_enhanced.yml rhel8-playbook-cis_server_l1.yml rhel8-playbook-cjis.yml rhel8-playbook-ism_o.yml rhel8-playbook-standard.yml rhel8-playbook-anssi_bp28_high.yml rhel8-playbook-cis_workstation_l1.yml rhel8-playbook-cui.yml rhel8-playbook-ospp.yml rhel8-playbook-stig_gui.yml rhel8-playbook-anssi_bp28_intermediary.yml rhel8-playbook-cis_workstation_l2.yml rhel8-playbook-e8.yml rhel8-playbook-pci-dss.yml rhel8-playbook-stig.yml
-
Check the contents of the OSPP profile playbook in your editor and verify that a task for the
accounts_tmout
rule is there among all the other tasks.[... ]$ open build/ansible/rhel8-playbook-ospp.yml
At this point, you have per-rule Ansible Playbooks available, as well as per-profile ones. You can integrate these into your CI/CD pipelines and infrastructure management as needed.