Per-Host Lockdown Enterprise Configuration
Config File/Variables File Best Practices
Variables follow a standard naming convention
Variables that are set in defaults/main.yml that are user-changeable use <osName><osVersion><roleType>_<descriptiveName>.
For example, rhel8stig_ssh_session_timeout is the variable name to set the ssh session timeout and rhel8stig_ssh_required will set if SSH is required. Within the tasks themselves, there are variables that are defined via a task. Those are named as <osDistroName>_<osVersionNumber>_<controlNumber>_<descriptiveName>. For example, rhel_08_010020_prelink_installed is the registered value if prelink is installed in control 010020. This formatting of variables follows throughout all of our roles.
We have generic default values set on all variables. Some can be left as their defaults and others should be changed. For example, we have all controls enabled by default, and that is something you might want to keep. There are also variables that define more localized settings like DNS server addresses or lists of unnecessary accounts to remove. You should read over the defaults/main.yml file to understand all of the variable options. There are comments around each variable that describe the options for that variable and show what controls include that variable. Make sure to read these notes since some options allow you to set a value that is out of bounds to conform to the role standards.
For example, setting the ssh timeout to more than 600 seconds in the RHEL 8 STIG role. The STIG standard requires the timeout to be 10 minutes (600 seconds) or less. The comments around a variable will inform you of the values that fit into the standard.
There are two ways to override controls within our Roles:
- The first way is to disable controls. The toggles available allow you to disable with broad toggles like the category/section toggles, disruptive toggles, tags, and more. There are also more fine-tuned individual control toggles. These are all adjusted via the defaults/main.yml file. The top section of the defaults/main.yml file will have settings to toggle controls on/off.
- The second way to override controls is to branch from the master branch of a repo and change the controls directly. This will be a localized edit and will be a deviation from the standard role hosted in the master branch of the repo.
What is Needed
- The most basic elements needed on the host for Linux nodes are SSH and the ability for the Ansible/Tower server to connect to the host via SSH. For Windows based systems, the Ansible/Tower server will need to connect to the host via WinRM. The packages that are specifically required for each role are listed in the README file within the role. There are togglable “pre” tasks that will install the needed packages using the system package manager before the role is run. This gives the option to automate the package installations or allow for manual installation of the needed packages.
- Instructions to assist with setting up WinRM on Windows-based hosts can be found here.
Configuring Iterative Remediation
The Roles are written with many controls that allow the enabling and disabling of controls. There are many options to create iterative changes to apply controls. The easiest way to handle this is via Job Templates in Ansible Tower. Using RHEL 8 STIG as an example, we can break a RHEL 8 STIG project into many templates to run the role in multiple ways. For example, you can create a job template to run everything in the role, another to run only a certain category, another to run only fixes related to SELinux, and another template to apply only non-intrusive fixes. With a limitless number of Job Templates allowed, you have a limitless number of options in how to run our baselines. This also applies to other aspects of the Ansible Tower Project.
Adding our Role with Other Roles in a Playbook
Along with toggling controls, you can also include our baseline Roles with other Roles within a Playbook. For example, you might have to configure Windows Server 2019 Domain Controllers. In this situation you can have a role that creates the Domain Control, another role to do additional configurations, and then our role to apply a security baseline all in the same Playbook. This will result in a node that is a Domain Control, has needed OS/Application tweaks, and a security baseline applied all in one automated template.
Best Place to Store Variables Files
There are a couple places to keep variables within a role. The first place which is preferred for variables that might change is the defaults/main.yml file. This file has some of the lowest precedence, which means these variables are easily overwritten. If your variables are going to be more permanent, they can go in vars/main.yml. There are a large number of places to keep variables, and those are the two main locations within our Roles. For a better understanding of variable location options here is the list of precedence for Ansible variables. The links take you to the main Ansible Docs footnotes for the variable precedence.
- command line values (for example, -u my_user, these are not variables)
- role defaults (defined in role/defaults/main.yml) 1
- inventory file or script group vars 2
- inventory group_vars/all 3
- playbook group_vars/all 3
- inventory group_vars/* 3
- playbook group_vars/* 3
- inventory file or script host vars 2
- inventory host_vars/* 3
- playbook host_vars/* 3
- host facts / cached set_facts 4
- play vars
- play vars_prompt
- play vars_files
- role vars (defined in role/vars/main.yml)
- block vars (only for tasks in block)
- task vars (only for the task)
- set_facts / registered vars
- role (and include_role) params
- include params
- extra vars (for example, -e "user=my_user") always win precedence