1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
|
= Lab Exercise 4: Using Ansible in ComplianceAsCode
:toc2:
:linkattrs:
:experimental:
:imagesdir: images
== Introduction
Red Hat^(R)^ Ansible^(R)^ 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.
.*Goals*
* 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^(R)^ products.
.*Preconfigured Lab Environment*
* The `ComplianceAsCode` repository was already cloned.
* Ansible Automation was installed.
* The following dependencies required for the `ComplianceAsCode` content build were installed using `yum install`:
** Generic build utilities: `cmake` and `make`,
** Utilities for generating SCAP content: `openscap-scanner`
** Python dependencies for putting content together: `python3-pyyaml` and `python3-jinja2`
== Hands-on Lab
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: link:https://gitpod.io/#WORKSHOP=lab4_ansible/https://github.com/ComplianceAsCode/content[Lab 4 Environment]
. Wait until all the steps being executed in the terminal are complete.
== Adding an Ansible Task for a Rule
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^(R)^ Enterprise Linux^(R)^ 8 (RHEL 8) product and the OSPP profile for Red Hat^(R)^ Enterprise Linux^(R)^ 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.
+
[NOTE]
====
Apart from `rule.yml`, there are also three subdirectories in the `accounts_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 the `bash` and `oval` directories.
Create a new `ansible` 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.
+
[NOTE]
====
In `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 new `shared.yml` file in the `ansible` 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 use `Ctrl+V` to paste it:
+
----
# platform = multi_platform_all
# reboot = false
# strategy = restrict
# complexity = low
# disruption = low
----
+
Do not close the file yet.
+
[NOTE]
====
The header contains optional metadata.
The `platform` and `reboot` 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 as `Red 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 either `true` or `false`.
Here, we signal that a reboot is not needed.
This value is purely informational and setting it to `true` 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`, or `unknown`.
* `complexity` is the estimated complexity or difficulty of applying the fix to the target.
It can be `unknown`, `low`, `medium`, or `high`.
* `disruption` is an estimate of the potential for disruption or operational degradation that the application of this fix imposes on the target.
It can be `unknown`, `low`, `medium`, or `high`.
====
. 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 the `shared.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"
----
+
[NOTE]
====
If you are familiar with Ansible Automation, you probably know that you just wrote an link:https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html#tasks-list[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 link:https://docs.ansible.com/ansible/latest/modules/modules_by_category.html[any Ansible module^].
Using Ansible language, you have defined a new Ansible task with the name "configure timeout".
It uses the link:https://docs.ansible.com/ansible/latest/modules/lineinfile_module.html[lineinfile^] Ansible module, which can add, modify, and remove lines in configuration files.
Using the `lineinfile` module, you insert the line `TMOUT=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 with `line`, so the lines `TMOUT=1800` and `#TMOUT=600` are replaced by `TMOUT=600`.
If no line matches the regular expression, contents of `line` are simply appended to `dest`, 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 in `rule.yml` for the given rule.
Tasks must not do anything different than what the `rule.yml` description requires.
Think of the rule description as a natural language specification of what needs to be implemented in Ansible Automation.
// Now, it is a good time to build the playbook, open it, and run it in a check mode.
== Using Variables in Ansible Tasks
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 setting `var_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 from `ComplianceAsCode` profiles is `{{{ ansible_instantiate_variables("var_accounts_tmout") }}}`.
. Add the following line right after the `# disruption = low` line in the `shared.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 the `shared.yml` file is processed by the `ComplianceAsCode` build system, this variable binding is resolved automatically and a new Ansible variable is created in the `vars` list in the generated playbook.
. Replace `line: "TMOUT=600"` with `line: "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 the `shared.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.
== Generating and Using Ansible Playbooks for a Rule
You now generate a playbook for the `accounts_tmout` rule you modified.
You do this in the context of the Red Hat^(R)^ Enterprise Linux^(R)^ 8 product and the OSPP profile for Red Hat^(R)^ Enterprise Linux^(R)^ 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 the `ospp` directory:
+
----
[... ]$ ls build/rhel8/playbooks/ospp
----
+
There are many playbook files in the `ospp` directory.
One of them is the `accounts_tmout.yml` file, which is the Ansible Playbook that contains the Ansible tasks you added in the `accounts_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 }}
----
+
[TIP]
====
If 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 press `Ctrl+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 the `vars` section of the playbook.
+
Note also that the playbook has tags in the `tags` section that were added based on metadata in `rule.yml`.
At the beginning, it contains the CCE (Common Configuration Enumeration) identifier.
Finally, the `tasks:` 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 select `Open 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.
+
.The "Set Interactive Session Timeout" rule displayed in an HTML guide and including the expanded Ansible content
image::4-01-guide.png[]
== Using the Profile Ansible Playbooks
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.
<<top>>
link:README.adoc#table-of-contents[ Table of Contents ] | link:lab5_oval.adoc[Lab Exercise 5: The Art of OVAL Checks]
|