Giter Club home page Giter Club logo

rhel8-cis's Introduction

RHEL 8 CIS

Configure a RHEL/Rocky/AlmaLinux 8 machine to be CIS compliant


Org Stars Stars Forks followers Twitter URL

Discord Badge

Release Branch Release Tag Release Date

Main Pipeline Status

Devel Pipeline Status Devel Commits

Issues Open Issues Closed Pull Requests

License


Looking for support?

Lockdown Enterprise

Ansible support

Community

Join us on our Discord Server to ask questions, discuss features, or just chat with other Ansible-Lockdown users.


Caution(s)

This role will make changes to the system which may have unintended consequences. This is not an auditing tool but rather a remediation tool to be used after an audit has been conducted.

  • Testing is the most important thing you can do.

  • Check Mode is not supported! The role will complete in check mode without errors, but it is not supported and should be used with caution. The RHEL8-CIS-Audit role or a compliance scanner should be used for compliance checking over check mode.

  • This role was developed against a clean install of the Operating System. If you are implementing to an existing system please review this role for any site specific changes that are needed.

  • To use release version please point to main branch and relevant release/tag for the cis benchmark you wish to work with.

  • If moving across major releases e.g. v2.0.0 - v3.0.0 there are significant changes to the benchmarks and controls it is suggested to start as a new standard not to upgrade.

  • Containers references vars/is_container.yml this is an example and to be updated for your requirements

  • Did we mention testing??


Matching a security Level for CIS

It is possible to to only run level 1 or level 2 controls for CIS. This is managed using tags:

  • level1_server
  • level1_workstation
  • level2_server
  • level2_workstation

The control found in defaults main also need to reflect this as this control the testing thet takes place if you are using the audit component.

Coming from a previous release

CIS release always contains changes, it is highly recommended to review the new references and available variables. This have changed significantly since ansible-lockdown initial release. This is now compatible with python3 if it is found to be the default interpreter. This does come with pre-requisites which it configures the system accordingly.

Further details can be seen in the Changelog

Auditing (new)

This can be turned on or off within the defaults/main.yml file with the variable rhel8cis_run_audit. The value is false by default, please refer to the wiki for more details. The defaults file also populates the goss checks to check only the controls that have been enabled in the ansible role.

This is a much quicker, very lightweight, checking (where possible) config compliance and live/running settings.

A new form of auditing has been developed, by using a small (12MB) go binary called goss along with the relevant configurations to check. Without the need for infrastructure or other tooling. This audit will not only check the config has the correct setting but aims to capture if it is running with that configuration also trying to remove false positives in the process.

Refer to RHEL8-CIS-Audit.

Example Audit Summary

This is based on a vagrant image with selections enabled. e.g. No Gui or firewall. Note: More tests are run during audit as we check config and running state.

ok: [default] => {
    "msg": [
        "The pre remediation results are: ['Total Duration: 5.454s', 'Count: 338, Failed: 47, Skipped: 5'].",
        "The post remediation results are: ['Total Duration: 5.007s', 'Count: 338, Failed: 46, Skipped: 5'].",
        "Full breakdown can be found in /var/tmp",
        ""
    ]
}

PLAY RECAP *******************************************************************************************************************************************
default                    : ok=270  changed=23   unreachable=0    failed=0    skipped=140  rescued=0    ignored=0

Documentation

Requirements

General:

  • Basic knowledge of Ansible, below are some links to the Ansible documentation to help get started if you are unfamiliar with Ansible

  • Functioning Ansible and/or Tower Installed, configured, and running. This includes all of the base Ansible/Tower configurations, needed packages installed, and infrastructure setup.

  • Please read through the tasks in this role to gain an understanding of what each control is doing. Some of the tasks are disruptive and can have unintended consequences in a live production system. Also familiarize yourself with the variables in the defaults/main.yml file.

Technical Dependencies:

RHEL/AlmaLinux/Rocky/Oracle 8 - Other versions are not supported.

  • AlmaLinux/Rocky Has been tested on 8.8(enabling crypto (sections 1.10 & 1.11) breaks updating or installs : July 01 2021
  • Access to download or add the goss binary and content to the system if using auditing (other options are available on how to get the content to the system.)
  • Python3.8
  • Ansible 2.11+
  • python-def (should be included in RHEL 8)
  • libselinux-python

Role Variables

This role is designed that the end user should not have to edit the tasks themselves. All customizing should be done via the defaults/main.yml file or with extra vars within the project, job, workflow, etc.

Tags

There are many tags available for added control precision. Each control has it's own set of tags noting what level, if it's scored/notscored, what OS element it relates to, if it's a patch or audit, and the rule number.

Below is an example of the tag section from a control within this role. Using this example if you set your run to skip all controls with the tag services, this task will be skipped. The opposite can also happen where you run only controls tagged with services.

      tags:
      - level1-server
      - level1-workstation
      - scored
      - avahi
      - services
      - patch
      - rule_2.2.4

Community Contribution

We encourage you (the community) to contribute to this role. Please read the rules below.

  • Your work is done in your own individual branch. Make sure to Signed-off and GPG sign all commits you intend to merge.
  • All community Pull Requests are pulled into the devel branch
  • Pull Requests into devel will confirm your commits have a GPG signature, Signed-off, and a functional test before being approved
  • Once your changes are merged and a more detailed review is complete, an authorized member will merge your changes into the main branch for a new release

Known Issues

cloud0init - due to a bug this will stop working if noexec is added to /var. rhel8cis_rule_1_1_3_3

bug 1839899

Almalinux BaseOS, EPEL and many cloud providers repositories, do not allow repo_gpgcheck on rule_1.2.3 this will cause issues during the playbook unless or a workaround is found.

Pipeline Testing

uses:

  • ansible-core 2.12
  • ansible collections - pulls in the latest version based on requirements file
  • runs the audit using the devel branch
  • This is an automated test that occurs on pull requests into devel

Local Testing

Molecule can be used to work on this role and test in distinct scenarios.

examples

molecule test -s default
molecule converge -s wsl -- --check
molecule verify -s localhost

local testing uses:

  • ansible 2.13.3
  • molecule 4.0.1
  • molecule-docker 2.0.0
  • molecule-podman 2.0.2
  • molecule-vagrant 1.0.0
  • molecule-azure 0.5.0

Added Extras

  • pre-commit can be tested and can be run from within the directory
pre-commit run

Credits and Thanks

Massive thanks to the fantastic community and all its members. This includes a huge thanks and credit to the original authors and maintainers. Josh Springer, Daniel Shepherd, Bas Meijeri, James Cassell, Mike Renfro, DFed, George Nalen, Mark Bolwell

rhel8-cis's People

Contributors

bbaassssiiee avatar billskico avatar carnells avatar cf-sewe avatar chandlerswift avatar dfederlein avatar dmacduff avatar georgenalen avatar jeromesteunenberg avatar marcov-git avatar mrsteve81 avatar pavloos avatar pre-commit-ci[bot] avatar thulium-drake avatar tomkuba avatar uk-bolly avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rhel8-cis's Issues

Check mode labels missing

Describe the Issue
Check mode runs fail on 1.1.15 (which also includes 1.1.16 and 1.1.17), and 4.2.1.4

Expected Behavior
Tasks run successfully in check mode

Actual Behavior

[...]
TASK [RHEL8-CIS : "1.1.15 | L1 | AUDIT | Ensure nodev option set on /dev/shm partition | Check for /dev/shm existence
 1.1.16 | L1 | AUDIT | Ensure nosuid option set on /dev/shm partition | Check for /dev/shm existence
 1.1.17 | L1 | AUDIT | Ensure noexec option set on /dev/shm partition | Check for /dev/shm existence"] ***
task path: /ansible/roles/RHEL8-CIS/tasks/section_1/cis_1.1.x.yml:250
skipping: [[host]] => {"changed": false, "msg": "skipped, running in check mode"}

TASK [RHEL8-CIS : "1.1.15 | L1 | PATCH | Ensure nodev option set on /dev/shm partition | skips if mount absent
 1.1.16 | L1 | PATCH | Ensure nosuid option set on /dev/shm partition | skips if mount absent
 1.1.17 | L1 | PATCH | Ensure noexec option set on /dev/shm partition | skips if mount absent"] ***
task path: /ansible/roles/RHEL8-CIS/tasks/section_1/cis_1.1.x.yml:259
fatal: [[host]]: FAILED! => {"msg": "The conditional check ''dev/shm' in rhel8cis_1_1_15_dev_shm_status.stdout' failed. The error was: error while evaluating conditional ('dev/shm' in rhel8cis_1_1_15_dev_shm_status.stdout): 'dict object' has no attribute 'stdout'\n\nThe error appears to be in '/ansible/roles/RHEL8-CIS/tasks/section_1/cis_1.1.x.yml': line 259, column 9, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n      - name: |\n        ^ here\n"}

PLAY RECAP *********************************************************************
[host]   : ok=16   changed=0    unreachable=0    failed=1    skipped=5    rescued=0    ignored=0

Control(s) Affected
1.1.15/16/17, 4.2.1.4

Environment (please complete the following information):

  • Host Python Version: 3.6.8
ansible-playbook 2.10.9.post0
  config file = /ansible/ansible.cfg
  configured module search path = ['/home/runner/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.8/site-packages/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.8.3 (default, Aug 31 2020, 16:03:14) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]

Section 6.2.8: file does not have argument warn

Describe the Issue
In section 6.2.8 there is a file statement to ensure owner of home folder is the user. This fails since warn is not an argument for file.

Expected Behavior
Without args/warn this works as expected

Actual Behavior
With args/warn this fails

Control(s) Affected
Role may not be implemented fully.

Environment (please complete the following information):

  • Ansible Version: 2.9.27
  • Host Python Version: 3.6.8
  • Ansible Server Python Version: 3.6.8
  • Additional Details:

Additional Notes

Possible Solution
Remove the following:

args:
  warn: no

Running in check mode fails on task 6.2.20

Describe the Issue
Running in check mode fails on task 6.2.20

Expected Behavior
Task doesn't have a syntax error

Actual Behavior

chandler@localhost % ansible-playbook --limit $HOST test.yml -vv --check --tags rule_6.2.20

TASK [RHEL8-CIS : 6.2.20 | L1 | AUDIT | Ensure all users' home directories exist] ***************************************************
task path: /ansible/roles/RHEL8-CIS/tasks/section_6/cis_6.2.x.yml:468
fatal: [[host]]: FAILED! => {"msg": "The conditional check 'rhel_08_6_2_20_patch_audit.stdout \"| length > 0\"' failed. The error was: template error while templating string: expected token 'end of statement block', got 'string'. String: {% if rhel_08_6_2_20_patch_audit.stdout \"| length > 0\" %} True {% else %} False {% endif %}"}

PLAY RECAP **************************************************************************************************************************
[host]   : ok=17   changed=0    unreachable=0    failed=1    skipped=4    rescued=0    ignored=0

Control(s) Affected
6.2.20

Environment (please complete the following information):

  • Host Python Version: 3.6.8
ansible-playbook 2.10.9.post0
  config file = /ansible/ansible.cfg
  configured module search path = ['/home/runner/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.8/site-packages/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.8.3 (default, Aug 31 2020, 16:03:14) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]

SCORED | 5.4.1 | PATCH | Ensure password creation requirements are configured | Set pwquality config settings

Hi,

The regexp is looking for target config settings instead of just minlen/minclass with any value.

  • name: "SCORED | 5.4.1 | PATCH | Ensure password creation requirements are configured | Set pwquality config settings"
    lineinfile:
    state: present
    dest: /etc/security/pwquality.conf
    regexp: '^{{ item }}'
    line: '{{ item }}'

    with_items:
    - "minlen = {{ rhel8cis_pam_password.minlen }}"
    - "minclass = {{ rhel8cis_pam_password.minclass }}"

    when: rhel8cis_rule_5_4_1

Thanks.

Tasks 1.1.15 - 1.1.17 skipped

Describe the Issue
In task 1.1.15 - 1.1.17 it is supposed to set mount options for /dev/shm.
As /dev/shm is not listed in ansible_mounts this task will never get executed.
It's not listed even if /etc/fstab contains following line:
tmpfs /dev/shm tmpfs defaults,noexec,nodev,nosuid 0 0

Expected Behavior
Task will execute

Actual Behavior
Task is skipped

Environment :

  • Ansible Version: 2.9.24
  • Host Python Version: 3.6.8
  • Ansible Server Python Version: 3.6.8
  • Additional Details: Oracle Linux 8.4

Possible Solution
I'm using following as a workaround:

mount:
  path: /dev/shm
  src: tmpfs
  fstype: tmpfs
  state: present
  opts: defaults,noexec,nodev,nosuid

Unsupported parameters for (lineinfile) module: block, marker

Hello,

Running this on CentOS 8 using Ansible 2.9.21 and I'm getting the following.

TASK [/root/RHEL8-CIS : NOTSCORED | 4.2.1.4 | PATCH | Ensure logging is configured | mail.* log setting] ***************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Unsupported parameters for (lineinfile) module: block, marker Supported parameters include: attributes, backrefs, backup,       content, create, delimiter, directory_mode, firstmatch, follow, force, group, insertafter, insertbefore, line, mode, owner, path, regexp, remote_src, selevel, serole, setype, seuse      r, src, state, unsafe_writes, validate"}

Looking at the code in tasks/section_4/cis_4.2.1.x.yml on line 58 I can see that the task looks like this:

  - name: "NOTSCORED | 4.2.1.4 | PATCH | Ensure logging is configured | mail.* log setting"
    lineinfile:
	path: /etc/rsyslog.conf
	state: present
	regexp: '^mail\.\*(.*)$'
	marker: "# {mark} MAIL LOG SETTINGS (ANSIBLE MANAGED)"
	block: |
	  # mail logging additions to meet CIS standards
	  mail.*                                                  -/var/log/mail
	  mail.info                                               -/var/log/mail.info
	  mail.warning                                            -/var/log/mail.warning
	  mail.err                                                /var/log/mail.err
	insertafter: '# Log all the mail messages in one place.'

Reading though the documentation https://docs.ansible.com/ansible/2.9/modules/lineinfile_module.html it seems that
the following params block, marker are not supported in the module lineinfile

Should this be using blockinfile instead?

2.2.2 | PATCH | Ensure X Window System is not installed | remove packages if found

Hi,

Quick and simple one, xorg_x11_installed.stdout below has to be as variable and stdout_lines may be used.

  • name: "SCORED | 2.2.2 | PATCH | Ensure X Window System is not installed | remove packages if found"
    shell: "dnf remove {{ item }}"
    with_items:
    - xorg_x11_installed.stdout
    when: xorg_x11_installed.stdout | length > 0

Undefined variable in parse_etc_password.yml

Describe the Issue
Undefined variable in parse_etc_password.yml

5: - name: "PRELIM | {{ rhel8cis_passwd_tasks }} | Parse /etc/passwd"

Expected Behavior
I suspect it should be "5.5.2 | 6.2.7 | 6.2.8 6.2.20"

Actual Behavior
{{ rhel8cis_passwd_tasks }}

related to #61

Add the ability to select CIS Levels

CIS comes with level 1 and 2.
applying level 2 is not always possible, so those controls could be turned off in bulk.
Updated the appropriate controls and levels to only run if selected.

Alternative to fail with incompatible OS

Feature Request

  • At present, the first task in the role is to assess whether the operating system is RHEL8 and if not, fail. Is there a way around this/is it plausible to simply have the role 'skipped' instead, in the role itself?

Context: I am using Ansible as host configuration management within Red hat Satellite. In this scenario, there is no playbook running this role, but instead, a hostgroup which contains a mix of OS has a default set of Ansible roles and simply runs 'all ansible roles' against all hosts. In this scenario, when the OS is correctly evaluated as not being RHEL8, the role fails, failing the job and preventing all other (valid) roles from being applied

Summary of Request
Instead of failing when the detected OS is not RHEL8, the role should be skipped

Describe alternatives you've considered
In the context of how we're using the role, i'm not sure that there is an alternative to modifying the role

Suggested Code
in main.yml, rather than fail, perhaps an 'assert that' task or similar which does the same check, with the result registered and then added as a when criteria on the remaining includes so that the same result is achieved (no additional tasks are run) but the playbook is not 'failed'

CIS Control 5.2.13 incorrect value

Issue
CIS Control 5.2.13 "Ensure SSH Idle Timeout Interval is configured" states that "The recommended ClientAliveCountMax setting is 0". However after running the playbook, the interval is set to 3.

Expected Behavior
Value clientalivecountmax in /etc/ssh/sshd_config is set to 0

Actual Behavior
Value clientalivecountmax in /etc/ssh/sshd_config is set to 3

Control(s) Affected
5.2.13 Ensure SSH Idle Timeout Interval is configured

Environment:

  • Ansible Version: 2.10.8
  • Host Python Version: 3.9.2
  • Ansible Server Python Version: 3.9.2

Possible Solution
Change the file defaults/main.yml section rhel8cis_sshd parameter clientalivecountmax to 0.

Current 4.2.3 Ensure permissions on all logfiles are configured remediation will break RHEL8

Guys,

The CIS version v1.0.0.1 remediation will break an existing RHEL8 build; the remediation step:
find /var/log -type f -exec chmod g-wx,o-rwx "{}" + -o -type d -exec chmod g-w,o-rwx "{}" +
is not valid for Fedora and RHEL.

This has been fixed in the CIS v1.0.1 standard. It has been updated to:
find /var/log/ -type f -perm /g+wx,o+rwx -exec chmod g-wx,o-rwx "{}" +

Please update your code in both version tags... ;-))

README refers to non-exstinent reference benchmark

CIS RedHat Enterprise Linux 8 Benchmark v2.1.1 - 01-31-2017 does not exist. (It looks like this was reused from CIS RedHat Enterprise Linux 7 Benchmark v2.1.1 - 01-31-2017 , but some of the fields were not updated.)
I believe the correct reference document is CIS Red Hat Enterprise Linux 8 Benchmark v1.0.0 - 2019-09-30.

1.4.2 | L1 | PATCH | Ensure filesystem integrity is regularly checked] failed with default value

Describe the Issue
in devel and main branch:

TASK [/perso/VM/ansible/RHEL8-CIS : 1.4.2 | L1 | PATCH | Ensure filesystem integrity is regularly checked] ****************************************
fatal: [red-hat-test]: FAILED! => {"changed": false, "msg": "Will not manage /etc/crontab via cron_file, see documentation."}

It's forbiden in ansible/lib/ansible/modules/cron.py
https://github.com/ansible/ansible/blob/601d66c7e51b60781e97e4dcb800a39065c0c98d/lib/ansible/modules/cron.py#L618

Environment (please complete the following information):
pip list --verbose
Package Version Location Installer


ansible 5.0.1 /home/bdouxx/venv/lib/python3.9/site-packages pip
ansible-core 2.12.1 /home/bdouxx/venv/lib/python3.9/site-packages pip
cffi 1.15.0 /home/bdouxx/venv/lib/python3.9/site-packages pip
cryptography 36.0.1 /home/bdouxx/venv/lib/python3.9/site-packages pip
graphviz 0.19.1 /home/bdouxx/venv/lib/python3.9/site-packages pip
Jinja2 3.0.3 /home/bdouxx/venv/lib/python3.9/site-packages pip
MarkupSafe 2.0.1 /home/bdouxx/venv/lib/python3.9/site-packages pip
packaging 21.3 /home/bdouxx/venv/lib/python3.9/site-packages pip
pip 21.3.1 /home/bdouxx/venv/lib/python3.9/site-packages pip
pipdeptree 2.2.0 /home/bdouxx/venv/lib/python3.9/site-packages pip
pycparser 2.21 /home/bdouxx/venv/lib/python3.9/site-packages pip
pyparsing 3.0.6 /home/bdouxx/venv/lib/python3.9/site-packages pip
PyYAML 6.0 /home/bdouxx/venv/lib/python3.9/site-packages pip
resolvelib 0.5.4 /home/bdouxx/venv/lib/python3.9/site-packages pip
setuptools 59.6.0 /home/bdouxx/venv/lib/python3.9/site-packages pip
wheel 0.37.0 /home/bdouxx/venv/lib/python3.9/site-packages pip

-list-tags does not produce expected output

Describe the Issue
ansible-playbook site.yml –list-tags produces an error

Expected Behavior
According to the getting started page this should list all available tags

Actual Behavior
➜ RHEL8-CIS git:(devel) ✗ ansible-playbook site.yml –list-tags [DEPRECATION WARNING]: COMMAND_WARNINGS option, the command warnings feature is being removed. This feature will be removed from ansible-core in version 2.14. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. ERROR! the playbook: –list-tags could not be found

Control(s) Affected
What controls are being affected by the issue

Environment (please complete the following information):

  • Ansible Version: ansible [core 2.11.3]
  • Host Python Version: Python 3.9.7

Additional Notes
Anything additional goes here

Possible Solution
Enter a suggested fix here

item 6.2.7 failes with template error

TASK [RHEL8-CIS : SCORED | 6.2.7| AUDIT | Ensure users' home directories permissions are 750 or more restrictive] ********************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: TemplateRuntimeError: no test named '>='
fatal: [ansibletest.localnet]: FAILED! => {"msg": "Unexpected failure during module execution.", "stdout": ""}

I believe this is the trigger:
with_items: "{{ rhel8cis_passwd | selectattr('uid', '>=', rhel8cis_int_gid) | selectattr('uid', '!=', 65534) | map(attribute='dir' ) | list }}"

$ ansible --version
ansible 2.9.21
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/user/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Aug 13 2020, 02:51:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

Disabling CIS Level 2 Patching

Question
I am fairly confident that the issue is with my syntax but I cannot seem to figure out how to call your role and have it run only CIS level 1 patching.

Playbook

---
- name: RHEL CIS Hardening
  hosts: rheltester
  roles:
    - role: rhel_hardening
      tags:
        - level1-server
      vars:
        rhel8cis_level_1: true
        rhel8cis_level_2: false
        system_is_ec2: true
  vars:
    ansible_connection: ssh
    ansible_user: ec2-user
    ansible_ssh_private_key_file: ~/keys/privkey.pem
    ansible_ssh_extra_args: '-o StrictHostKeyChecking=no'

Hosts.ini

[rheltester]
a.b.c.d

Command

ansible-playbook -vv -i hosts.ini rhel-hardening-playbook.yml

Output

.
.
.
TASK [rhel_hardening : 1.7.1.3 | L2 | PATCH | Ensure SELinux policy is configured] ***********************************************************************************************************
task path: /Users/ps/IdeaProjects/ansible/roles/rhel_hardening/tasks/section_1/cis_1.7.1.x.yml:33
redirecting (type: modules) ansible.builtin.selinux to ansible.posix.selinux
[WARNING]: Reboot is required to set SELinux state to 'enforcing'
changed: [a.b.c.d] => {"changed": true, "configfile": "/etc/selinux/config", "msg": "Config SELinux state changed from 'disabled' to 'enforcing'", "policy": "targeted", "reboot_required": true, "state": "enforcing"}

It does the level 1 CIS patching just fine but it is also doing level 2 which I do not want.

Environment (please complete the following information):

  • ansible-playbook [core 2.11.3]
  • python version = 3.9.6 (default, Jun 29 2021, 05:25:02) [Clang 12.0.5 (clang-1205.0.22.9)]

Unused prelim code for 6.2.8 has incorrect bash expansion

In task "PRELIM | 6.2.8 | Gather local interactive user directories", the
getent passwd { {{ rhel8cis_int_gid }}..65535} results in failed bash expansion due to the space after the first {.

The code:
shell: "getent passwd { {{ rhel8cis_int_gid }}..65535} | cut -d: -f6 | sort -u | grep -v '/var/' | grep -v '/nonexistent/*' | grep -v '/run/*'"
could be rewritten with a join filter, e.g.:
shell: "{{ [ 'getent passwd {', '..65535} | cut -d: -f6 | sort -u | grep -v /var/ | grep -v /nonexistent/ | grep -v /run/' ] | join(rhel8cis_int_gid) }}"

However, the variables registered by this and the subsequent task in prelim.yml ("PRELIM | 6.2.8 | Set fact for home directory paths for interactive users") do not appear to be used anywhere else in the role. As the logic of these tasks does not seem to map exactly to the 6.2.8 rule in the benchmark, nor are these results used in task "SCORED | 6.2.8 | PATCH | Ensure users own their home directories" in section6.yml, I recommend removing these two tasks from prelim.yml.

User nobody should be excluded from ownership and uid does not equal gid

Describe the Issue
When user nobody (UID 65534) is included in setting ownership the role will manipulate / causing severe problems for the target system. Also, there is a variable rhel8cis_int_gid being used for comparison with uid. While this works since all newer systems use same gid and uid for normal users it may differ on some systems.

Expected Behavior
System should not be rendered unusable by running the role.

Actual Behavior
The root folder (/) gets chown to user nobody by the role causing severe problems.

Environment (please complete the following information):

  • Ansible Version: 2.9.27
  • Host Python Version: Python 3.6.8
  • Ansible Server Python Version: Python 3.6.8
  • Additional Details:

Additional Notes
The proposed solution has been tested and found to work

Possible Solution
Introduce two new variables, rhel8cis_int_uid and rhel8cis_int_uid_max. Set rhel8cis_int_uid to be 1000 and rhel8cis_int_uid_max to 65533. Use rhel8cis_int_uid when comparing with UIDs, this includes tasks for 6.2.x and templates for 4.1.9, 4.1.10, 4.1.12, 4.1.13 and 4.1.14.
Use rhel8cis_int_uid_max to prevent chown on / for user nobody in section 6.2.8. This has been fixed in 6.2.7 using a slightly different approach.

ansible_distribution_major_version should be treated as a string and not as an integer

Describe the Issue
pre_remediation_audit.yml is being skipped because ansible_distribution_major_version is tested as an integer and not as a string

Expected Behavior
Install git if not pesent

Actual Behavior
block "If using git for content set up" is skipped

Control(s) Affected
Audit failed to installed

Environment (please complete the following information):

  • Ansible Version: 2.9.6

Possible Solution
Compare to '8' and '7' instead of 8 and 7

- name: If using git for content set up
  block:
  - name: Install git (rh8 python3)
    package:
        name: git
        state: present
    when: ansible_distribution_major_version == '8'

  - name: Install git (rh7 python2)
    package:
        name: git
        state: present
    vars:
        ansible_python_interpreter: "{{ python2_bin }}"
    when: ansible_distribution_major_version == '7'

4.1.17 Ensure the audit configuration is immutable - Not correct set

Describe the Issue
Conform the CIS rule 4.1.17 "Ensure the audit configuration is immutable", this rule has to be the last rule in the config, for example /etc/audit/rules.d/99-finalize.rules. This ansible playbook sets the rule with the name rhel8cis_rule_4_1_17.rules which result in not being the last rule.

Expected Behavior
According the CIS, this has to be the last file and the last rule should have "-e 2"

Actual Behavior
Value plased in rhel8cis_rule_4_1_17.rules and that is not the last rule:
total 64
-rw-------. 1 root root 244 Oct 7 07:24 audit.rules
-rw-------. 1 root root 595 Oct 7 08:34 rhel8cis_rule_4_1_10.rules
-rw-------. 1 root root 176 Oct 7 08:34 rhel8cis_rule_4_1_11.rules
-rw-------. 1 root root 161 Oct 7 08:34 rhel8cis_rule_4_1_12.rules
-rw-------. 1 root root 2921 Oct 7 08:34 rhel8cis_rule_4_1_13.rules
-rw-------. 1 root root 239 Oct 7 08:34 rhel8cis_rule_4_1_14.rules
-rw-------. 1 root root 180 Oct 7 08:34 rhel8cis_rule_4_1_15.rules
-rw-------. 1 root root 39 Oct 7 08:34 rhel8cis_rule_4_1_16.rules
-rw-------. 1 root root 5 Oct 7 11:11 rhel8cis_rule_4_1_17.rules
-rw-------. 1 root root 65 Oct 7 08:34 rhel8cis_rule_4_1_3.rules
-rw-------. 1 root root 74 Oct 7 08:34 rhel8cis_rule_4_1_4.rules
-rw-------. 1 root root 101 Oct 7 08:34 rhel8cis_rule_4_1_5.rules
-rw-------. 1 root root 307 Oct 7 08:34 rhel8cis_rule_4_1_6.rules
-rw-------. 1 root root 81 Oct 7 08:34 rhel8cis_rule_4_1_7.rules
-rw-------. 1 root root 319 Oct 7 08:34 rhel8cis_rule_4_1_8.rules
-rw-------. 1 root root 753 Oct 7 08:34 rhel8cis_rule_4_1_9.rules

Control(s) Affected
4.1.17 Ensure the audit configuration is immutable

Environment (please complete the following information):

  • Ansible Version: 2.10.8
  • Host Python Version: 3.9.2
  • Ansible Server Python Version: 3.9.2
  • Additional Details:

Additional Notes
Great playbook, helpes me a lot!

Possible Solution
Change the name of the file.

rhel8stig_audit_complex not defined

I was getting and ansible error when arriving to line 214 of section6 as rhel8stig_audit_complex is not defined anywhere on the role.

by removing

changed_when:
            - rhel8stig_audit_complex

It works OK

typos in script all over, wont run

has anyone actually run this script as is? just pulled it down the other day and tried to run it...
tons of references to "rhel8cis_" that appear should be "cis_rhel8_"
please advise, it seems the naming structure was changed but some one forgot to change it everywhere...
this script will not run as is...

tmp.mount support

code is missing deploy custom tmp.mount and notify tmp.mount handler for when 'rhel8cis_tmp_svc: true' in Section 1 vars

Bug in 1.3.2/1.3.3

The regex's in item 1.3.2 and 1.3.3 conflict with each other. By running the role in step mode, you can verify that
"Defaults use_pty" in /etc/sudoers is present after 1.3.2, and then immediately replaced by
"Defaults logfile="/var/log/sudo.log"" in task 1.3.3, because the regex for both tasks is:

"^Defaults"

I suggest changing the regex for task 1.3.2 to '^Defaults (?!(logfile="{{ rhel8cis_varlog_location }}")).*'
and the regex for task 1.3.3 to '^Defaults (?!(use_pty)).*'

In the above two regex, there are 4 spaces between "Defaults" and the rest of the regex, but I can't get that to format correctly here.

1.4.2 - Ansible 2.12 Does Not Manage /etc/crontab

Describe the Issue
Latest release of Ansible 2.12 seems to error out when managing /etc/crontab. When running step 1.4.2, Ansible 2.12 will error with the following message:

TASK [/RHEL8-CIS : 1.4.2 | L1 | PATCH | Ensure filesystem integrity is regularly checked] ***
fatal: [example.com]: FAILED! => {"changed": false, "msg": "Will not manage /etc/crontab via cron_file, see documentation."}

Please refer to: https://docs.ansible.com/ansible-core/devel/collections/ansible/builtin/cron_module.html

The assumption is that this file is exclusively managed by the module, do not use if the file contains multiple entries, NEVER use for /etc/crontab.

Expected Behavior
While a user can modify the rhel8cis_aide_cron.cron_file setting, I would expect default configurations to handle this due to potentially unknown behavior when modifying default configurations.

Actual Behavior
Ansible will error and not modify the /etc/crontab file

Control(s) Affected
1.4.2

Environment (please complete the following information):
Ansible 2.12.2

Additional Notes
None

Possible Solution
By updating the rhel8cis_aide_cron to the following, and creating a daily file within /etc/cron.d, the command works. However, I'm not sure if this is a valid approach.

# AIDE cron settings
rhel8cis_aide_cron:
    cron_user: root
    cron_file: /etc/cron.d/0daily   <<<< This is the only change required
    aide_job: '/usr/sbin/aide --check'
    aide_minute: 0
    aide_hour: 5
    aide_day: '*'
    aide_month: '*'
    aide_weekday: '*'

Error with 4.1.1.3/4.1.1.4

When the items 4.1.1.3 and 4.1.1.4 are run one after the other, I got a /etc/default/grub file like this on a fresh deployment of CentOS 8

GRUB_DEVICE=LABEL=cloudimg-rootfs
GRUB_DISABLE_LINUX_UUID=true
GRUB_TIMEOUT=5
GRUB_TERMINAL="serial console"
GRUB_GFXPAYLOAD_LINUX=auto
GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200 no_timer_check nofb nomodeset gfxpayload=text"
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200 no_timer_check nofb nomodeset gfxpayload=text audit_backlog_limit=8192"
GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200 no_timer_check nofb nomodeset gfxpayload=text
GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200 no_timer_check nofb nomodeset gfxpayload=text audit_backlog_limit=8192 audit=1"

There is several lines of GRUB_CMDLINE_LINUX_DEFAULT and the second to last line has no ending ", which results in a error when the grub file is generated

RUNNING HANDLER [RHEL8-CIS : generate new grub config] ************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["grub2-mkconfig", "-o", "/boot/grub2/grub.cfg"], "delta": "0:00:00.369642", "end": "2021-03-30 12:33:11.910391", "msg": "non-zero return code", "rc": 2, "start": "2021-03-30 12:33:11.540749", "stderr": "/etc/default/grub: line 10: unexpected EOF while looking for matching `\"'", "stderr_lines": ["/etc/default/grub: line 10: unexpected EOF while looking for matching `\"'"], "stdout": "", "stdout_lines": []}
...ignoring

Generating new GRUB file

Vanilla load/test - keep getting this error, and I'm not sure where to go next:

fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'stat'\n\nThe error appears to be in '/etc/ansible/roles/RHEL8-CIS/handlers/main.yml': line 38, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: generate new grub config\n ^ here\n"}

Include statements deprecated in Ansible 2.12 - will be removed in 2.16

Describe the Issue
A clear and concise description of what the bug is.

[DEPRECATION WARNING]: "include" is deprecated, use include_tasks/import_tasks instead. This feature will be removed
 in version 2.16. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

Control(s) Affected
What controls are being affected by the issue
N/A
Environment (please complete the following information):

ansible [core 2.12.1]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110]
  jinja version = 2.11.3
  libyaml = True

Possible Solution
Need to rework all include statements with their include_X or import_X equivalents.

5.2.3 and 5.2.4 are not idempotent (use of command module)

These modules are not idempotent because of their use of the command module.

TASK [cis_hardening_el8 : SCORED | 5.2.3 | PATCH | Ensure permissions on SSH private host key files are configured] ***
changed: [ansible.lbhr.htm.lan] => (item=find /etc/ssh -xdev -type f -name 'ssh_host_*_key' -exec chown root:root {} \;)
changed: [ansible.lbhr.htm.lan] => (item=find /etc/ssh -xdev -type f -name 'ssh_host_*_key' -exec chmod 0600 {} \;)

TASK [cis_hardening_el8 : SCORED | 5.2.4 | PATCH | Ensure permissions on SSH public host key files are configured] ***
changed: [ansible.lbhr.htm.lan] => (item=find /etc/ssh -xdev -type f -name 'ssh_host_*_key.pub' -exec chmod 0644 {} \;)
changed: [ansible.lbhr.htm.lan] => (item=find /etc/ssh -xdev -type f -name 'ssh_host_*_key.pub' -exec chown root:root {} \;)

Section 6.2.9 should not recurse

Describe the Issue
In it's current form section 6.2.9 will recurse and find and "correct" all world writeable dot-files under /home. This causes problems when users have lots of dot-files, like in git repos.

Expected Behavior
The benchmark describes only dot-files in a users home directory, not recursed in all subdirectories.

Actual Behavior
A lot of files are found and "corrected", yet the should not be.

Control(s) Affected
Section 6.2.9

Environment (please complete the following information):

  • Ansible Version: 2.9.27
  • Host Python Version: 3.6.8
  • Ansible Server Python Version: N/A
  • Additional Details: No server used. Playbooks are run from client to target system

Additional Notes
The benchmark suggests using awk to find home folders from /etc/passwd. This does not seem like a good approach since centrally managed users do not have entries for centrally managed users.
Also, the current task does not include /root or any users created outside of /home. This should be added.

Possible Solution
Add -maxdepth 2 to the find statement in /tasks/section_6/cis_6.2.x.yml line 200.
Like so:
shell: find /home/ -maxdepth 2 -name "\.*" -perm /g+w,o+w

Error with rhel8cis_rule_6_1_1

The shell command rpm -Va --nomtime --nosize --nomd5 --nolinkto > /bin/{{ rhel8cis_6_1_1_packages.stdout_lines }} generates a /bin/'[.,' file.
Also, the rpm -qf step where we determine which package a file is in is missing.

Section 2.2.12 error "Could not find the requested service nfs: host" for NFS service

The NFS service definition in Section 2.2.12 lists the NFS service as just 'nfs' instead of 'nfs-server' when the 'nfs-utils' package is installed. Playbook errors out with "msg: Could not find the requested service nfs: host" when running full playbook or just 'nfs' tag. Changing the service from 'nfs' to 'nfs-server' satisfies the service check for section 2.2.12.

The issue is with the CIS benchmark for RHEL 8 version 1.0.0 document specifying the remediation step as running systemctl --now disable nfs instead of systemctl --now disable nfs-server which is necessary to satisfy the requirement of reducing the attack surface of the host if the host is not exporting shares. Understanding that the issue is with misrepresented information in the Benchmark document, the best approach for ensuring correct operation of this playbook would be to correct the service name from "nfs" to "nfs-server".

This issue was encountered on both RHEL 8.3 and CentOS 8.3. The NFS server service previously was named 'nfs' in RHEL/CentOS 6 but changed to 'nfs-server' sometime around RHEL 7.1 or 7.2.

Create Oracle Linux 8 playbook

Feature Request or Enhancement

  • Feature [x]
  • Enhancement []

Summary of Request
I've manage to test/run this playbook successfully against an Oracle Linux 8 deployment.

As OL8 is just a re-packaged RHEL8, there is very little difference.

The only tasks i needed to disable were:

  • 1.2.1
  • 1.2.2

Describe alternatives you've considered
Writing custom ansible playbooks for this is truly awful and the ansible-lockdown project is the only logical place i can see this type of work/effort taking place.

Mismatch between 4.1.12 and 4.1.13 rules

There's some mismatch between 4.1.12 Ensure successful file system mounts are collected and 4.1.13 Ensure use of privileged commands is collected implementation.
They has the same name and the implementation blocks dislocated.

Updates to Version Tagging

Hello,
I wanted to give an update on a tagging change that will take place on the next release, scheduled at some point in May. Without realizing that Ansible Galaxy needs version numbers in the Semantic format that excludes the preceding “v”, for example 1.2.1 vs v1.2., we have been using tags with the preceding v. This has caused our galaxy space to not update with our latest releases.

The plan going forward we plan to adjust the version number formatting on the first release for each repo in May. Please make note that if you are relying on release tags to keep up with latest versions, the numbering format will change. The cadence of the version numbers will continue and progress through as they have been, however the preceding “v” will be dropped from the tag.

George

3.1.1. Fails when IPv6 is disabled.

When I run check 3.1.1, the handler sysctl flush ipv4 route table is called.
Strangely, however, this handler also wants to do something with ipv6.

The output of the test is
`TASK [RHEL8_CIS : SCORED | 3.1.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv4 forwarding] **************************************************************************************************************************************
ok: [alrha001.acc.vlkintern.nl] => (item={'name': 'net.ipv4.ip_forward', 'value': 0})
changed: [alrha001.acc.vlkintern.nl] => (item={'name': 'net.ipv4.route.flush', 'value': 1})

TASK [RHEL8_CIS : SCORED | 3.1.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv6 forwarding] **************************************************************************************************************************************
skipping: [alrha001.acc.vlkintern.nl] => (item={'name': 'net.ipv6.conf.all.forwarding', 'value': 0})
skipping: [alrha001.acc.vlkintern.nl] => (item={'name': 'net.ipv6.route.flush', 'value': 1})

RUNNING HANDLER [RHEL8_CIS : sysctl flush ipv4 route table] *********************************************************************************************************************************************************************************
[WARNING]: The value 1 (type int) in a string field was converted to '1' (type string). If this does not look like what you expect, quote the entire value to ensure it does not change.

fatal: [alrha001.acc.vlkintern.nl]: FAILED! => {"changed": false, "msg": "Failed to reload sysctl: fs.suid_dumpable = 0\nkernel.randomize_va_space = 2\nnet.ipv4.conf.all.forwarding = 0\nnet.ipv4.conf.all.send_redirects = 0\nnet.ipv4.conf.default.send_redirects = 0\nnet.ipv4.conf.all.accept_source_route = 0\nnet.ipv4.conf.default.accept_source_route = 0\nnet.ipv4.conf.all.accept_redirects = 0\nnet.ipv4.conf.default.accept_redirects = 0\nnet.ipv4.conf.all.secure_redirects = 0\nnet.ipv4.conf.default.secure_redirects = 0\nnet.ipv4.conf.all.log_martians = 1\nnet.ipv4.conf.default.log_martians = 1\nnet.ipv4.icmp_echo_ignore_broadcasts = 1\nnet.ipv4.icmp_ignore_bogus_error_responses = 1\nnet.ipv4.conf.all.rp_filter = 1\nnet.ipv4.conf.default.rp_filter = 1\nnet.ipv4.tcp_syncookies = 1\nnet.ipv4.route.flush = 1\nnet.ipv4.ip_forward = 0\nsysctl: cannot stat /proc/sys/net/ipv6/route/flush: No such file or directory\nsysctl: cannot stat /proc/sys/net/ipv6/conf/all/forwarding: No such file or directory\n"}`

Notice that all variables are pertaining to ipv4, yet at the end the ipv6 files are not found. Which is worked as designed, because I do not want ipv6......

How to fix this ?

CIS rules broken that use replace module

Hi!

When running this role with Ansible 2.10.6 (and probably more) the task to ensure SELinux is enabled at boot time does not work:

TASK [cis_hardening_el8 : SCORED | 1.7.1.2 | PATCH | Ensure SELinux is not disabled in bootloader configuration] *****
fatal: [ansible.lbhr.htm.lan]: FAILED! => changed=false 
  msg: 'Unsupported parameters for (replace) module: follow Supported parameters include: after, attributes, backup, before, encoding, group, mode, owner, path, regexp, replace, selevel, serole, setype, seuser, unsafe_writes, validate'
...ignoring

1.3.2 and 1.3.3 are not idempotent (conflicting check/result)

The result of the first task (1.3.2) seems to break the check for the second task (1.3.3.)

Everytime I run this role against my system (it has run before on this system) it will change there parameters around.

TASK [cis_hardening_el8 : SCORED | 1.3.2 | PATCH | Ensure sudo commands use pty] *************************************
--- before: /etc/sudoers (content)
+++ after: /etc/sudoers (content)
@@ -85,7 +85,7 @@
 #
 # Defaults   env_keep += "HOME"
 
-Defaults    logfile="/var/log/sudo.log"
+Defaults    use_pty
 
 ## Next comes the main part: which users can run what software on 
 ## which machines (the sudoers file can be shared between multiple

changed: [ansible.lbhr.htm.lan]

TASK [cis_hardening_el8 : SCORED | 1.3.3 | PATCH | Ensure sudo log file exists] **************************************
--- before: /etc/sudoers (content)
+++ after: /etc/sudoers (content)
@@ -85,7 +85,7 @@
 #
 # Defaults   env_keep += "HOME"
 
-Defaults    use_pty
+Defaults    logfile="/var/log/sudo.log"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.