Skip to content

Latest commit

 

History

History
423 lines (359 loc) · 18.8 KB

lab4_ansible.adoc

File metadata and controls

423 lines (359 loc) · 18.8 KB

Lab Exercise 4: Using Ansible in ComplianceAsCode

Introduction

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.

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® 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:

  1. Go to: Lab 4 Environment

  2. 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® 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.

  1. 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.

  2. 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
  3. 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.

  4. 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
  5. 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.

  6. 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 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 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.

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.

  1. 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") }}}.

  2. 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.

  3. 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 }}"
  4. 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® 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.

  1. 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
  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. Run the playbook:

    [... ]$ ansible-playbook build/rhel8/playbooks/ospp/accounts_tmout.yml
  7. 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.

  8. Navigate to the build/guides folder.:

  9. 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.

  10. A new tab opens and you can see your OSPP profile, which contains two rules.

  11. 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.

    4 01 guide
    Figure 1. The "Set Interactive Session Timeout" rule displayed in an HTML guide and including the expanded Ansible content

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
  1. 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.