From a1126618a7b22475921834e166d339707ab04e3b Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 10:52:32 +0100 Subject: [PATCH 01/33] Added names Signed-off-by: Mark Bolwell --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 331d150..c25682f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -39,16 +39,16 @@ repos: rev: v1.5.0 hooks: - id: detect-secrets - name: Detect Secrets + name: Detect Secrets test - repo: https://github.com/gitleaks/gitleaks - rev: v8.24.3 + rev: v8.26.0 hooks: - id: gitleaks - name: GitLeaks + name: Run Gitleaks test - repo: https://github.com/ansible-community/ansible-lint - rev: v25.2.1 + rev: v25.5.0 hooks: - id: ansible-lint name: Ansible-lint @@ -67,7 +67,7 @@ repos: # - ansible-core>=2.10.1 - repo: https://github.com/adrienverge/yamllint.git - rev: v1.37.0 # or higher tag + rev: v1.37.1 # or higher tag hooks: - id: yamllint name: Check YAML Lint From f29fc9088cc8a31314bf0d00b37872daf10bb5b8 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 10:53:32 +0100 Subject: [PATCH 02/33] fixed var naming Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 4 ++-- tasks/section_5/cis_5.4.1.x.yml | 8 ++++---- tasks/section_5/cis_5.4.2.x.yml | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 9b19bf1..7d3b295 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -31,7 +31,7 @@ - name: "PRELIM | AUDIT | Interactive Users (reformat)" tags: always ansible.builtin.set_fact: - prelim_interactive_usernames: "{{ prelim_interactive_users | default([]) + [dict([('username', item.split(':')[0]), ('uid', item.split(':')[1]), ('home', item.split(':')[2])])] }}" + prelim_interactive_users: "{{ prelim_interactive_users | default([]) + [dict([('username', item.split(':')[0]), ('uid', item.split(':')[1]), ('home', item.split(':')[2])])] }}" loop: "{{ prelim_interactive_users_raw.stdout_lines }}" - name: "PRELIM | AUDIT | Interactive UIDs" @@ -203,7 +203,7 @@ tags: - always block: - - name: "PRELIM | AUDIT | Discover is wirelss adapter on system" + - name: "PRELIM | AUDIT | Discover is wireless adapter on system" ansible.builtin.command: find /sys/class/net/*/ -type d -name wireless register: discover_wireless_adapters changed_when: false diff --git a/tasks/section_5/cis_5.4.1.x.yml b/tasks/section_5/cis_5.4.1.x.yml index 1962101..7fcfb0b 100644 --- a/tasks/section_5/cis_5.4.1.x.yml +++ b/tasks/section_5/cis_5.4.1.x.yml @@ -29,7 +29,7 @@ - name: "5.4.1.1 | PATCH | Ensure password expiration is 365 days or less | Set existing users PASS_MAX_DAYS" when: - discovered_max_days.stdout_lines | length > 0 - - item in prelim_interactive_usernames | map(attribute='username') | list + - item in prelim_interactive_users | map(attribute='username') | list - rhel9cis_force_user_maxdays ansible.builtin.user: name: "{{ item }}" @@ -60,7 +60,7 @@ - name: "5.4.1.2 | PATCH | Ensure minimum password days is configured | Set existing users PASS_MIN_DAYS" when: - discovered_min_days.stdout_lines | length > 0 - - item in prelim_interactive_usernames | map(attribute='username') | list + - item in prelim_interactive_users | map(attribute='username') | list - rhel9cis_force_user_mindays ansible.builtin.user: name: "{{ item }}" @@ -91,7 +91,7 @@ - name: "5.4.1.3 | PATCH | Ensure password expiration warning days is configured | Set existing users WARN_DAYS" when: - discovered_warn_days.stdout_lines | length > 0 - - item in prelim_interactive_usernames | map(attribute='username') | list + - item in prelim_interactive_users | map(attribute='username') | list - rhel9cis_force_user_warnage ansible.builtin.command: "chage --warndays {{ rhel9cis_pass['warn_age'] }} {{ item }}" changed_when: true @@ -140,7 +140,7 @@ register: discovered_passwdlck_user_list - name: "5.4.1.5 | PATCH | Ensure inactive password lock is 30 days or less | Apply Inactive setting to existing accounts" - when: item in prelim_interactive_usernames | map(attribute='username') | list + when: item in prelim_interactive_users | map(attribute='username') | list ansible.builtin.command: chage --inactive {{ rhel9cis_inactivelock.lock_days }} "{{ item }}" changed_when: true loop: "{{ discovered_passwdlck_user_list.stdout_lines }}" diff --git a/tasks/section_5/cis_5.4.2.x.yml b/tasks/section_5/cis_5.4.2.x.yml index a8eb4d0..26985a3 100644 --- a/tasks/section_5/cis_5.4.2.x.yml +++ b/tasks/section_5/cis_5.4.2.x.yml @@ -195,7 +195,7 @@ - name: "5.4.2.7 | PATCH | Ensure system accounts do not have a valid login shell" when: - rhel9cis_rule_5_4_2_7 - - "item.id not in prelim_interactive_usernames | map(attribute='username')" + - "item.id not in prelim_interactive_users | map(attribute='username')" - item.id not in rhel9cis_system_users_shell - "'root' not in item.id" - rhel9cis_disruption_high @@ -220,7 +220,7 @@ when: - rhel9cis_rule_5_4_2_8 - rhel9cis_disruption_high - - "item.id not in prelim_interactive_usernames | map(attribute='username')" + - "item.id not in prelim_interactive_users | map(attribute='username')" - "'root' not in item.id" tags: - level1-server From 97abfaf9f81bf040441d5287970777b6b4d1be8e Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 15:41:12 +0100 Subject: [PATCH 03/33] updated passwd variable Signed-off-by: Mark Bolwell --- tasks/parse_etc_password.yml | 8 ++++---- tasks/section_5/cis_5.4.2.x.yml | 4 ++-- tasks/section_7/cis_7.2.x.yml | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tasks/parse_etc_password.yml b/tasks/parse_etc_password.yml index 9190421..c7ed865 100644 --- a/tasks/parse_etc_password.yml +++ b/tasks/parse_etc_password.yml @@ -7,12 +7,12 @@ ansible.builtin.shell: cat /etc/passwd | grep -v '^#' changed_when: false check_mode: false - register: prelim_passwd_file_audit + register: prelim_capture_passwd_file - - name: "PRELIM | 5.5.2 | 6.2.7 | 6.2.8 | 6.2.20 | Split passwd entries" + - name: "PRELIM | 5.4.2 | 7.2.8 | Split passwd entries" ansible.builtin.set_fact: - rhel9cis_passwd: "{{ prelim_passwd_file_audit.stdout_lines | map('regex_replace', ld_passwd_regex, ld_passwd_yaml) | map('from_yaml') | list }}" - loop: "{{ prelim_passwd_file_audit.stdout_lines }}" + prelim_captured_passwd_data: "{{ prelim_capture_passwd_file.stdout_lines | map('regex_replace', ld_passwd_regex, ld_passwd_yaml) | map('from_yaml') | list }}" + loop: "{{ prelim_capture_passwd_file.stdout_lines }}" vars: ld_passwd_regex: >- ^(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*) diff --git a/tasks/section_5/cis_5.4.2.x.yml b/tasks/section_5/cis_5.4.2.x.yml index 26985a3..37a4e11 100644 --- a/tasks/section_5/cis_5.4.2.x.yml +++ b/tasks/section_5/cis_5.4.2.x.yml @@ -212,7 +212,7 @@ ansible.builtin.user: name: "{{ item.id }}" shell: /usr/sbin/nologin - loop: "{{ rhel9cis_passwd }}" + loop: "{{ prelim_captured_passwd_data }}" loop_control: label: "{{ item.id }}" @@ -235,6 +235,6 @@ ansible.builtin.user: name: "{{ item.id }}" password_lock: true - loop: "{{ rhel9cis_passwd }}" + loop: "{{ prelim_captured_passwd_data }}" loop_control: label: "{{ item.id }}" diff --git a/tasks/section_7/cis_7.2.x.yml b/tasks/section_7/cis_7.2.x.yml index 8706877..a5e0a25 100644 --- a/tasks/section_7/cis_7.2.x.yml +++ b/tasks/section_7/cis_7.2.x.yml @@ -243,7 +243,7 @@ state: directory owner: "{{ item.id }}" group: "{{ item.gid }}" - loop: "{{ rhel9cis_passwd | selectattr('uid', '>=', prelim_min_int_uid | int) | selectattr('uid', '<=', prelim_max_int_uid | int) | list }}" + loop: "{{ prelim_captured_passwd_data | selectattr('uid', '>=', prelim_min_int_uid | int) | selectattr('uid', '<=', prelim_max_int_uid | int) | list }}" loop_control: label: "{{ item.id }}" @@ -315,6 +315,6 @@ ansible.builtin.file: path: '{{ item }}' mode: 'go-w' - owner: "{{ rhel9cis_passwd | selectattr('dir', 'in', prelim_interactive_users_raw.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='uid') | last }}" - group: "{{ rhel9cis_passwd | selectattr('dir', 'in', prelim_interactive_users_raw.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='gid') | last }}" + owner: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_raw.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='uid') | last }}" + group: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_raw.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='gid') | last }}" with_items: "{{ discovered_homedir_hidden_files.stdout_lines }}" From 7673c2ff00bb3b9716d602ed6a57665e4e7814c9 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 15:53:41 +0100 Subject: [PATCH 04/33] Added home directory discovery Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 7d3b295..4c170a1 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -34,6 +34,14 @@ prelim_interactive_users: "{{ prelim_interactive_users | default([]) + [dict([('username', item.split(':')[0]), ('uid', item.split(':')[1]), ('home', item.split(':')[2])])] }}" loop: "{{ prelim_interactive_users_raw.stdout_lines }}" +- name: "PRELIM | AUDIT | Interactive User accounts home directories" + tags: always + ansible.builtin.shell: > + grep -E -v '^(root|halt|sync|shutdown)' /etc/passwd | awk -F: '(!index($7, "sbin/nologin") && $7 != "/bin/nologin" && $7 != "/bin/false" && $7 != "/dev/null") { print $6 }' + changed_when: false + check_mode: false + register: prelim_interactive_users_home + - name: "PRELIM | AUDIT | Interactive UIDs" tags: always ansible.builtin.shell: > From 260005415c91ba6059df3bc13938a04904321a36 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 15:58:54 +0100 Subject: [PATCH 05/33] Aligned with public Signed-off-by: Mark Bolwell --- .pre-commit-config.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 331d150..ebc85d7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -39,16 +39,14 @@ repos: rev: v1.5.0 hooks: - id: detect-secrets - name: Detect Secrets - repo: https://github.com/gitleaks/gitleaks - rev: v8.24.3 + rev: v8.26.0 hooks: - id: gitleaks - name: GitLeaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.2.1 + rev: v25.4.0 hooks: - id: ansible-lint name: Ansible-lint @@ -67,7 +65,7 @@ repos: # - ansible-core>=2.10.1 - repo: https://github.com/adrienverge/yamllint.git - rev: v1.37.0 # or higher tag + rev: v1.37.1 # or higher tag hooks: - id: yamllint name: Check YAML Lint From f2c03f1e687067e52671eefc86354b1de422097d Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 16:11:36 +0100 Subject: [PATCH 06/33] variable networkmanager package and typo fixes Signed-off-by: Mark Bolwell --- defaults/main.yml | 11 ++++++----- tasks/section_3/cis_3.1.x.yml | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 871e85e..cc49b0a 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -12,7 +12,7 @@ os_check: true # Disruption is high ## Run tests that are considered higher risk and could have a system impact if not properly tested ## Default false -## Will be fine if clean new unconfigured build +## Will be fine if clean new un configured build rhel9cis_disruption_high: false ## Switching on/off specific baseline sections @@ -513,7 +513,7 @@ rhel9cis_rule_7_2_9: true ## Section 1 vars -## Ability to enabe debug on mounts to assist in troubleshooting +## Ability to enable debug on mounts to assist in troubleshooting # Mount point changes are set based upon facts created in Prelim # these then build the variable and options that is passed to the handler to set the mount point for the controls in section1. rhel9cis_debug_mount_data: false @@ -723,6 +723,7 @@ rhel9cis_ipv6_required: true ## 3.1.2 wireless network requirements # if wireless adapter found allow network manager to be installed rhel9cis_install_network_manager: false +rhel9cis_network_manager_package_name: NetworkManager # 3.3 System network parameters (host only OR host and router) # This variable governs whether specific CIS rules # concerned with acceptance and routing of packages are skipped. @@ -815,7 +816,7 @@ rhel9cis_sshd_clientalivecountmax: 3 rhel9cis_sshd_clientaliveinterval: 15 ## Control 5.1.12 - disable forwarding -# By Default this will also disablex11 forwarding +# By Default this will also disable x11 forwarding # set 'yes' if x11 is required this can be changed to run in /etc/ssh/ssh_config.d/50-redhat.conf rhel9cis_sshd_x11forwarding: 'no' @@ -1045,14 +1046,14 @@ rhel9cis_bash_umask: '0027' # 0027 or more restrictive # These are discovered via logins.def if set true rhel9cis_discover_int_uid: true # This variable sets the minimum number from which to search for UID -# Note that the value will be dynamically overwritten if variable `dicover_int_uid` has +# Note that the value will be dynamically overwritten if variable `discover_int_uid` has # been set to `true`. min_int_uid: 1000 ### Controls: # - Ensure local interactive user home directories exist # - Ensure local interactive users own their home directories # This variable sets the maximum number at which the search stops for UID -# Note that the value will be dynamically overwritten if variable `dicover_int_uid` has +# Note that the value will be dynamically overwritten if variable `discover_int_uid` has # been set to `true`. max_int_uid: 65533 diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index 68a66de..a20c0e9 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -39,7 +39,7 @@ warn_control_id: '3.1.2' block: - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Check for network-manager tool" - when: "'network-manager' in ansible_facts.packages" + when: "rhel9cis_network_manager_package_name in ansible_facts.packages" ansible.builtin.command: nmcli radio wifi changed_when: false failed_when: false @@ -48,19 +48,19 @@ - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Disable wireless if network-manager installed" when: - - "'network-manager' in ansible_facts.packages" + - "rhel9cis_network_manager_package_name in ansible_facts.packages" - "'enabled' in discovered_wifi_status.stdout" ansible.builtin.command: nmcli radio all off changed_when: discovered_nmcli_radio_off.rc == 0 register: discovered_nmcli_radio_off - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Warn about wireless if network-manager not installed" - when: "'network-manager' not in ansible_facts.packages" + when: "rhel9cis_network_manager_package_name not in ansible_facts.packages" ansible.builtin.debug: msg: "Warning!! You need to disable wireless interfaces manually since network-manager is not installed" - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Set warning count" - when: "'network-manager' not in ansible_facts.packages" + when: "rhel9cis_network_manager_package_name not in ansible_facts.packages" ansible.builtin.import_tasks: file: warning_facts.yml From 2256456f0e6979d7cd906e648671d940105cb166 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 16:12:31 +0100 Subject: [PATCH 07/33] align with public fixes Signed-off-by: Mark Bolwell --- tasks/audit_only.yml | 10 ---------- tasks/main.yml | 4 +++- tasks/prelim.yml | 20 ++++++++++++++++++-- tasks/section_5/cis_5.1.x.yml | 2 ++ tasks/section_7/cis_7.2.x.yml | 2 +- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/tasks/audit_only.yml b/tasks/audit_only.yml index 845d9d9..d6f20ea 100644 --- a/tasks/audit_only.yml +++ b/tasks/audit_only.yml @@ -1,15 +1,5 @@ --- -- name: Audit_Only | Create local Directories for hosts - when: fetch_audit_files - ansible.builtin.file: - mode: 'u+x,go-w' - path: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}" - recurse: true - state: directory - delegate_to: localhost - become: false - - name: Audit_only | Show Audit Summary when: audit_only ansible.builtin.debug: diff --git a/tasks/main.yml b/tasks/main.yml index f9f2bd2..f099e06 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -17,7 +17,9 @@ success_msg: "This role is running a supported version of ansible {{ ansible_version.full }} >= {{ min_ansible_version }}" - name: "Setup rules if container" - when: ansible_connection == 'docker' or ansible_facts.virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] + when: + - ansible_connection == 'docker' or + ansible_facts.virtualization_type in ["docker", "lxc", "openvz", "podman", "container" tags: - container_discovery - always diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 9b19bf1..ced76ce 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -31,9 +31,17 @@ - name: "PRELIM | AUDIT | Interactive Users (reformat)" tags: always ansible.builtin.set_fact: - prelim_interactive_usernames: "{{ prelim_interactive_users | default([]) + [dict([('username', item.split(':')[0]), ('uid', item.split(':')[1]), ('home', item.split(':')[2])])] }}" + prelim_interactive_users: "{{ prelim_interactive_users | default([]) + [dict([('username', item.split(':')[0]), ('uid', item.split(':')[1]), ('home', item.split(':')[2])])] }}" loop: "{{ prelim_interactive_users_raw.stdout_lines }}" +- name: "PRELIM | AUDIT | Interactive User accounts home directories" + tags: always + ansible.builtin.shell: > + grep -E -v '^(root|halt|sync|shutdown)' /etc/passwd | awk -F: '(!index($7, "sbin/nologin") && $7 != "/bin/nologin" && $7 != "/bin/false" && $7 != "/dev/null") { print $6 }' + changed_when: false + check_mode: false + register: prelim_interactive_users_home + - name: "PRELIM | AUDIT | Interactive UIDs" tags: always ansible.builtin.shell: > @@ -203,7 +211,7 @@ tags: - always block: - - name: "PRELIM | AUDIT | Discover is wirelss adapter on system" + - name: "PRELIM | AUDIT | Discover is wireless adapter on system" ansible.builtin.command: find /sys/class/net/*/ -type d -name wireless register: discover_wireless_adapters changed_when: false @@ -246,6 +254,14 @@ mode: 'go-rwx' state: touch +- name: "PRELIM | PATCH | sshd_config.d/50-redhat.conf exists" + when: + - rhel9cis_rule_5_1_10 or + rhel9cis_rule_5_1_11 + ansible.builtin.stat: + path: /etc/ssh/sshd_config.d/50-redhat.conf + register: discovered_sshd_50_redhat_file + - name: "PRELIM | AUDIT | Capture pam security related files" tags: always ansible.builtin.find: diff --git a/tasks/section_5/cis_5.1.x.yml b/tasks/section_5/cis_5.1.x.yml index 99176fd..eaee7de 100644 --- a/tasks/section_5/cis_5.1.x.yml +++ b/tasks/section_5/cis_5.1.x.yml @@ -276,6 +276,7 @@ notify: Restart sshd - name: "5.1.10 | PATCH | Ensure sshd DisableForwarding is enabled | override" + when: discovered_sshd_50_redhat_file.stat.exists ansible.builtin.lineinfile: path: /etc/ssh/sshd_config.d/50-redhat.conf regexp: ^(?i)(#|)\s*X11Forwarding @@ -298,6 +299,7 @@ - NIST800-53R5_IA-5 block: - name: "5.1.11 | PATCH | Ensure sshd GSSAPIAuthentication is disabled | redhat file" + when: discovered_sshd_50_redhat_file.stat.exists ansible.builtin.lineinfile: path: /etc/ssh/sshd_config.d/50-redhat.conf regexp: ^(?i)(#|)\s*GSSAPIAuthentication diff --git a/tasks/section_7/cis_7.2.x.yml b/tasks/section_7/cis_7.2.x.yml index 8706877..cb01c21 100644 --- a/tasks/section_7/cis_7.2.x.yml +++ b/tasks/section_7/cis_7.2.x.yml @@ -220,7 +220,7 @@ - name: "7.2.7 | AUDIT | Ensure no duplicate group names exist | Print warning about users with duplicate group names" when: discovered_group_check.stdout | length > 0 ansible.builtin.debug: - msg: "Warning!! The following group names are duplicates: {{ discovered_group_group_check.stdout_lines }}" + msg: "Warning!! The following group names are duplicates: {{ discovered_group_check.stdout_lines }}" - name: "7.2.7 | AUDIT | Ensure no duplicate group names exist | Set warning count" when: discovered_group_check.stdout | length > 0 From 2e3499ca8c6125ba237779ddb709889370583fd2 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 16:47:01 +0100 Subject: [PATCH 08/33] added missing square brace Signed-off-by: Mark Bolwell --- tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/main.yml b/tasks/main.yml index f099e06..e285e8d 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -19,7 +19,7 @@ - name: "Setup rules if container" when: - ansible_connection == 'docker' or - ansible_facts.virtualization_type in ["docker", "lxc", "openvz", "podman", "container" + ansible_facts.virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] tags: - container_discovery - always From f40d17df92588a7e97655fa9691805fd17b93c59 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Thu, 12 Jun 2025 12:42:44 -0400 Subject: [PATCH 09/33] Update eprep based tasks to grep/awk Signed-off-by: Frederick Witty --- tasks/main.yml | 2 +- tasks/section_1/cis_1.3.1.x.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index e285e8d..fe50b10 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -132,7 +132,7 @@ - rule_5.4.2.4 block: - name: "Ensure root password is set" - ansible.builtin.shell: passwd -S root | egrep -e "(Password set, SHA512 crypt|Password locked)" + ansible.builtin.shell: passwd -S root | grep -E "(Password set, SHA512 crypt|Password locked)" changed_when: false register: prelim_root_passwd_set diff --git a/tasks/section_1/cis_1.3.1.x.yml b/tasks/section_1/cis_1.3.1.x.yml index 198ae7b..17e138e 100644 --- a/tasks/section_1/cis_1.3.1.x.yml +++ b/tasks/section_1/cis_1.3.1.x.yml @@ -106,7 +106,7 @@ warn_control_id: '1.3.1.6' block: - name: "1.3.1.6 | AUDIT | Ensure no unconfined services exist | Find the unconfined services" - ansible.builtin.shell: ps -eZ | grep unconfined_service_t | egrep -vw "tr|ps|egrep|bash|awk" | tr ':' ' ' | awk '{ print $NF }' + ansible.builtin.shell: ps -eZ | awk -F':'' '/unconfined_service_t/ && $NF !~ /tr|ps|egrep|bash|awk/ {print $NF}' register: discovered_unconf_services failed_when: false changed_when: false From 3a0ee6e9f8ccea92c22bf5838e0a514ae63c76b7 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Thu, 12 Jun 2025 15:44:03 -0400 Subject: [PATCH 10/33] update 1.3.1.6 log to grep -E Signed-off-by: Frederick Witty --- tasks/section_1/cis_1.3.1.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_1/cis_1.3.1.x.yml b/tasks/section_1/cis_1.3.1.x.yml index 17e138e..ad7d844 100644 --- a/tasks/section_1/cis_1.3.1.x.yml +++ b/tasks/section_1/cis_1.3.1.x.yml @@ -106,7 +106,7 @@ warn_control_id: '1.3.1.6' block: - name: "1.3.1.6 | AUDIT | Ensure no unconfined services exist | Find the unconfined services" - ansible.builtin.shell: ps -eZ | awk -F':'' '/unconfined_service_t/ && $NF !~ /tr|ps|egrep|bash|awk/ {print $NF}' + ansible.builtin.shell: ps -eZ | grep unconfined_service_t | grep -Evw "tr|ps|egrep|bash|awk" | tr ':' ' ' | awk '{ print $NF }' register: discovered_unconf_services failed_when: false changed_when: false From 27c7ec3604c5d56520d4b2ea06d8ccc3df381f60 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 17:12:21 +0100 Subject: [PATCH 11/33] fixed typos Signed-off-by: Mark Bolwell --- tasks/section_1/cis_1.1.2.3.x.yml | 4 ++-- tasks/section_1/cis_1.1.2.4.x.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tasks/section_1/cis_1.1.2.3.x.yml b/tasks/section_1/cis_1.1.2.3.x.yml index 998d1ba..635648d 100644 --- a/tasks/section_1/cis_1.1.2.3.x.yml +++ b/tasks/section_1/cis_1.1.2.3.x.yml @@ -21,12 +21,12 @@ register: discovered_home_mount - name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | Absent" - when: discovered_dev_shm_mount is undefined + when: discovered_home_mount is undefined ansible.builtin.debug: msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" - name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | Present" - when: discovered_dev_shm_mount is undefined + when: discovered_home_mount is undefined ansible.builtin.import_tasks: file: warning_facts.yml diff --git a/tasks/section_1/cis_1.1.2.4.x.yml b/tasks/section_1/cis_1.1.2.4.x.yml index e0afd4e..f89fe3f 100644 --- a/tasks/section_1/cis_1.1.2.4.x.yml +++ b/tasks/section_1/cis_1.1.2.4.x.yml @@ -22,12 +22,12 @@ register: discovered_var_mount - name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | Absent" - when: discovered_dev_shm_mount is undefined + when: discovered_var_mount is undefined ansible.builtin.debug: msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" - name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | Present" - when: discovered_dev_shm_mount is undefined + when: discovered_var_mount is undefined ansible.builtin.import_tasks: file: warning_facts.yml From 6770e5a4ffbad121b1a59c7d91acd804aac087f5 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 17:13:53 +0100 Subject: [PATCH 12/33] added check_mode false to task Signed-off-by: Mark Bolwell --- tasks/auditd.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/auditd.yml b/tasks/auditd.yml index 7b86b94..0fa0b32 100644 --- a/tasks/auditd.yml +++ b/tasks/auditd.yml @@ -7,6 +7,7 @@ - name: "POST | AUDITD | Set supported_syscalls variable" ansible.builtin.shell: ausyscall --dump | awk '{print $2}' changed_when: false + check_mode: false failed_when: discovered_auditd_syscalls.rc not in [ 0, 1 ] register: discovered_auditd_syscalls From ce3ae8361e1aec615b4168bacd1e5bc964f06fc8 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 17:14:58 +0100 Subject: [PATCH 13/33] Updated logic for root password check Signed-off-by: Mark Bolwell --- tasks/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasks/main.yml b/tasks/main.yml index e285e8d..43ec09c 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -132,8 +132,9 @@ - rule_5.4.2.4 block: - name: "Ensure root password is set" - ansible.builtin.shell: passwd -S root | egrep -e "(Password set, SHA512 crypt|Password locked)" + ansible.builtin.shell: passwd -S root | grep -E "(Password set, SHA512 crypt|Password locked)" changed_when: false + failed_when: prelim_root_passwd_set.rc not in [ 0, 1 ] register: prelim_root_passwd_set - name: "Ensure root password is set" From 2eb85294c83f3c54a9c57a355f9b8609258c628c Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 17:15:42 +0100 Subject: [PATCH 14/33] Updated conditionals for audit steps Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index ced76ce..2e0dd95 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -4,9 +4,7 @@ # List users in order to look files inside each home directory - name: "PRELIM | Include audit specific variables" - when: - - run_audit or audit_only - - setup_audit + when: run_audit or audit_only or setup_audit tags: - setup_audit - run_audit @@ -14,9 +12,7 @@ file: audit.yml - name: "PRELIM | Include pre-remediation audit tasks" - when: - - run_audit or audit_only - - setup_audit + when: run_audit or audit_only or setup_audit tags: run_audit ansible.builtin.import_tasks: pre_remediation_audit.yml From 1537bf72dfa014f163ccfe1780bc9a0d899f3c57 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 17:16:26 +0100 Subject: [PATCH 15/33] 5-redhat.conf var naming Signed-off-by: Mark Bolwell --- Changelog.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Changelog.md b/Changelog.md index d09b13d..203a510 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,13 @@ # Changes to rhel9CIS + +## 2.0.1 - Based on CIS v2.0.0 + +- Thanks to @polski-g several issues and improvements added +- Improved testing for 50-redhat.conf for ssh +- 5.1.x regexp improvements +- Improved root password check + ## 2.0.0 - Based on CIS v2.0.0 - #325 - thanks to @mindrb From 2724faf1fc1b2934438b007e3822125953d98a78 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 17:17:00 +0100 Subject: [PATCH 16/33] 50-redhat.conf var naming update Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 2e0dd95..1eed552 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -256,7 +256,7 @@ rhel9cis_rule_5_1_11 ansible.builtin.stat: path: /etc/ssh/sshd_config.d/50-redhat.conf - register: discovered_sshd_50_redhat_file + register: prelim_sshd_50_redhat_file - name: "PRELIM | AUDIT | Capture pam security related files" tags: always From 02008339b4186099c8849a9f1bdf30312d65623e Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 17:18:22 +0100 Subject: [PATCH 17/33] updated regex Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.1.x.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tasks/section_5/cis_5.1.x.yml b/tasks/section_5/cis_5.1.x.yml index eaee7de..13ec292 100644 --- a/tasks/section_5/cis_5.1.x.yml +++ b/tasks/section_5/cis_5.1.x.yml @@ -279,7 +279,7 @@ when: discovered_sshd_50_redhat_file.stat.exists ansible.builtin.lineinfile: path: /etc/ssh/sshd_config.d/50-redhat.conf - regexp: ^(?i)(#|)\s*X11Forwarding + regexp: (?i)^(#|)\s*X11Forwarding line: 'X11Forwarding {{ rhel9cis_sshd_x11forwarding }}' validate: sshd -t -f %s notify: Restart sshd @@ -302,7 +302,7 @@ when: discovered_sshd_50_redhat_file.stat.exists ansible.builtin.lineinfile: path: /etc/ssh/sshd_config.d/50-redhat.conf - regexp: ^(?i)(#|)\s*GSSAPIAuthentication + regexp: (?i)^(#|)\s*GSSAPIAuthentication line: GSSAPIAuthentication no validate: sshd -t -f %s notify: Restart sshd @@ -310,7 +310,7 @@ - name: "5.1.11 | PATCH | Ensure sshd GSSAPIAuthentication is disabled | ssh config" ansible.builtin.lineinfile: path: "{{ rhel9cis_sshd_config_file }}" - regexp: ^(?i)(#|)\s*GSSAPIAuthentication + regexp: (?i)^(#|)\s*GSSAPIAuthentication line: GSSAPIAuthentication no validate: sshd -t -f %s notify: Restart sshd @@ -330,7 +330,7 @@ - NIST800-53R5_IA-5 ansible.builtin.lineinfile: path: "{{ rhel9cis_sshd_config_file }}" - regexp: ^(?i)(#|)\s*HostbasedAuthentication + regexp: (?i)^(#|)\s*HostbasedAuthentication line: 'HostbasedAuthentication no' validate: sshd -t -f %s notify: Restart sshd @@ -350,7 +350,7 @@ - NIST800-53R5_IA-5 ansible.builtin.lineinfile: path: "{{ rhel9cis_sshd_config_file }}" - regexp: ^(?i)(#|)\s*IgnoreRhosts + regexp: (?i)^(#|)\s*IgnoreRhosts line: 'IgnoreRhosts yes' insertbefore: "^Match" firstmatch: true @@ -368,7 +368,7 @@ - NIST800-53R5_CM-6 ansible.builtin.lineinfile: path: "{{ rhel9cis_sshd_config_file }}" - regexp: ^(?i)(#|)\s*LoginGraceTime + regexp: (?i)^(#|)\s*LoginGraceTime line: "LoginGraceTime {{ rhel9cis_sshd_logingracetime }}" insertbefore: "^Match" firstmatch: true @@ -388,7 +388,7 @@ - NIST800-53R5_SI-5 ansible.builtin.lineinfile: path: "{{ rhel9cis_sshd_config_file }}" - regexp: ^(?i)(#|)\s*LogLevel + regexp: (?i)^(#|)\s*LogLevel line: 'LogLevel {{ rhel9cis_ssh_loglevel }}' insertbefore: "^Match" firstmatch: true @@ -426,7 +426,7 @@ - NIST800-53R5_IA-5 ansible.builtin.lineinfile: path: "{{ rhel9cis_sshd_config_file }}" - regexp: ^(?i)(#|)\s*MaxStartups + regexp: (?i)^(#|)\s*MaxStartups line: 'MaxStartups {{ rhel9cis_ssh_maxstartups }}' validate: sshd -t -f %s notify: Restart sshd @@ -446,7 +446,7 @@ - NIST800-53R5_IA-5 ansible.builtin.lineinfile: path: "{{ rhel9cis_sshd_config_file }}" - regexp: ^(?i)(#|)\s*MaxSessions + regexp: (?i)^(#|)\s*MaxSessions line: 'MaxSessions {{ rhel9cis_ssh_maxsessions }}' validate: sshd -t -f %s notify: Restart sshd @@ -466,7 +466,7 @@ - NIST800-53R5_IA-5 ansible.builtin.lineinfile: path: "{{ rhel9cis_sshd_config_file }}" - regexp: ^(?i)(#|)\s*PermitEmptyPasswords + regexp: (?i)^(#|)\s*PermitEmptyPasswords line: 'PermitEmptyPasswords no' validate: sshd -t -f %s notify: Restart sshd @@ -484,7 +484,7 @@ - name: "5.1.20 | PATCH | Ensure sshd PermitRootLogin is disabled | config file" ansible.builtin.lineinfile: path: "{{ rhel9cis_sshd_config_file }}" - regexp: ^(?i)(#|)\s*PermitRootLogin + regexp: (?i)^(#|)\s*PermitRootLogin line: 'PermitRootLogin no' validate: sshd -t -f %s notify: Restart sshd @@ -510,7 +510,7 @@ - NIST800-53R5_IA-5 ansible.builtin.lineinfile: path: "{{ rhel9cis_sshd_config_file }}" - regexp: ^(?i)(#|)\s*PermitUserEnvironment + regexp: (?i)^(#|)\s*PermitUserEnvironment line: 'PermitUserEnvironment no' validate: sshd -t -f %s notify: Restart sshd @@ -530,7 +530,7 @@ - NIST800-53R5_IA-5 ansible.builtin.lineinfile: path: "{{ rhel9cis_sshd_config_file }}" - regexp: ^(?i)(#|)\s*UsePAM + regexp: (?i)^(#|)\s*UsePAM line: 'UsePAM yes' validate: sshd -t -f %s notify: Restart sshd From f892525a7cf43a48b887475f21f296552281050b Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 17:19:18 +0100 Subject: [PATCH 18/33] 5.1.10 and 5.1.11 updated variable naming Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.1.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/section_5/cis_5.1.x.yml b/tasks/section_5/cis_5.1.x.yml index 13ec292..3fd366c 100644 --- a/tasks/section_5/cis_5.1.x.yml +++ b/tasks/section_5/cis_5.1.x.yml @@ -276,7 +276,7 @@ notify: Restart sshd - name: "5.1.10 | PATCH | Ensure sshd DisableForwarding is enabled | override" - when: discovered_sshd_50_redhat_file.stat.exists + when: prelim_sshd_50_redhat_file.stat.exists ansible.builtin.lineinfile: path: /etc/ssh/sshd_config.d/50-redhat.conf regexp: (?i)^(#|)\s*X11Forwarding @@ -299,7 +299,7 @@ - NIST800-53R5_IA-5 block: - name: "5.1.11 | PATCH | Ensure sshd GSSAPIAuthentication is disabled | redhat file" - when: discovered_sshd_50_redhat_file.stat.exists + when: prelim_sshd_50_redhat_file.stat.exists ansible.builtin.lineinfile: path: /etc/ssh/sshd_config.d/50-redhat.conf regexp: (?i)^(#|)\s*GSSAPIAuthentication From b65504de6b89f746812e5c251e8eccad621567c6 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 17:20:40 +0100 Subject: [PATCH 19/33] Updated egrep Signed-off-by: Mark Bolwell --- tasks/section_1/cis_1.3.1.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_1/cis_1.3.1.x.yml b/tasks/section_1/cis_1.3.1.x.yml index 198ae7b..ad7d844 100644 --- a/tasks/section_1/cis_1.3.1.x.yml +++ b/tasks/section_1/cis_1.3.1.x.yml @@ -106,7 +106,7 @@ warn_control_id: '1.3.1.6' block: - name: "1.3.1.6 | AUDIT | Ensure no unconfined services exist | Find the unconfined services" - ansible.builtin.shell: ps -eZ | grep unconfined_service_t | egrep -vw "tr|ps|egrep|bash|awk" | tr ':' ' ' | awk '{ print $NF }' + ansible.builtin.shell: ps -eZ | grep unconfined_service_t | grep -Evw "tr|ps|egrep|bash|awk" | tr ':' ' ' | awk '{ print $NF }' register: discovered_unconf_services failed_when: false changed_when: false From 7e5fb97b9adb021bd4ecfa71939f8e1f8022865a Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 17:23:28 +0100 Subject: [PATCH 20/33] updated Signed-off-by: Mark Bolwell --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 203a510..7542aa1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ - Improved testing for 50-redhat.conf for ssh - 5.1.x regexp improvements - Improved root password check +- egrep command changed to grep -E ## 2.0.0 - Based on CIS v2.0.0 From 6ced990430e326cb9151046bb690c981fd49eb20 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Mon, 16 Jun 2025 14:58:21 -0400 Subject: [PATCH 21/33] Update handler naming change_requires_reboot to set reboot required Signed-off-by: Frederick Witty --- handlers/main.yml | 8 ++++---- tasks/prelim.yml | 8 ++------ tasks/section_1/cis_1.2.2.x.yml | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/handlers/main.yml b/handlers/main.yml index 1a3b66e..8ac3b22 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -150,7 +150,7 @@ ansible.posix.mount: path: "{{ mount_point }}" state: remounted - notify: Change_requires_reboot + notify: Set reboot required listen: "Remount /boot/efi" - name: Reload sysctl @@ -194,7 +194,7 @@ ansible.builtin.command: update-crypto-policies --set "{{ rhel9cis_full_crypto_policy }}" changed_when: true notify: - - Change_requires_reboot + - Set reboot required - Restart sshd - name: Restart firewalld @@ -255,7 +255,7 @@ when: discovered_auditd_immutable_check.stdout == '1' ansible.builtin.debug: msg: "Reboot required for auditd to apply new rules as immutable set" - notify: Change_requires_reboot + notify: Set reboot required - name: Stop auditd process ansible.builtin.command: systemctl kill auditd @@ -268,6 +268,6 @@ state: started listen: Restart auditd -- name: Change_requires_reboot +- name: Set reboot required ansible.builtin.set_fact: change_requires_reboot: true diff --git a/tasks/prelim.yml b/tasks/prelim.yml index ced76ce..2e0dd95 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -4,9 +4,7 @@ # List users in order to look files inside each home directory - name: "PRELIM | Include audit specific variables" - when: - - run_audit or audit_only - - setup_audit + when: run_audit or audit_only or setup_audit tags: - setup_audit - run_audit @@ -14,9 +12,7 @@ file: audit.yml - name: "PRELIM | Include pre-remediation audit tasks" - when: - - run_audit or audit_only - - setup_audit + when: run_audit or audit_only or setup_audit tags: run_audit ansible.builtin.import_tasks: pre_remediation_audit.yml diff --git a/tasks/section_1/cis_1.2.2.x.yml b/tasks/section_1/cis_1.2.2.x.yml index 2ccb59f..379b92d 100644 --- a/tasks/section_1/cis_1.2.2.x.yml +++ b/tasks/section_1/cis_1.2.2.x.yml @@ -13,4 +13,4 @@ ansible.builtin.package: name: "*" state: latest - notify: Change_requires_reboot + notify: Set reboot required From b38e7d06eb757c2af71f5fd8482afb48a97162fb Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Mon, 16 Jun 2025 15:14:08 -0400 Subject: [PATCH 22/33] var fixes for 1.1.2.3.x and 1.1.2.4.x Signed-off-by: Frederick Witty --- tasks/pre_remediation_audit.yml | 2 +- tasks/prelim.yml | 16 +++++----------- tasks/section_1/cis_1.1.2.3.x.yml | 4 ++-- tasks/section_1/cis_1.1.2.4.x.yml | 4 ++-- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index 61959fa..a2a37f1 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -46,7 +46,7 @@ remote_src: "{{ (audit_conf_source is contains('http')) | ternary(true, false) }}" extra_opts: "{{ (audit_conf_source is contains('github')) | ternary('--strip-components=1', []) }}" -- name: Pre Audit Setup | Check Goss is available +- name: Pre Audit Setup | Check goss is available when: run_audit block: - name: Pre Audit Setup | Check for goss file diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 2e0dd95..0e2b155 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -136,8 +136,7 @@ register: prelim_systemd_coredump - name: "PRELIM | PATCH | Setup crypto-policy" - when: - - rhel9cis_rule_1_6_1 + when: rhel9cis_rule_1_6_1 tags: - level1-server - level1-workstation @@ -185,15 +184,13 @@ grub2_path: /etc/grub2-efi.cfg - name: "PRELIM | AUDIT | Discover Gnome Desktop Environment" - tags: - - always + tags: always ansible.builtin.stat: path: /usr/share/gnome/gnome-version.xml register: prelim_gnome_present - name: "PRELIM | PATCH | Install dconf if gui installed" - when: - - rhel9cis_gui + when: rhel9cis_gui tags: - always ansible.builtin.package: @@ -251,9 +248,7 @@ state: touch - name: "PRELIM | PATCH | sshd_config.d/50-redhat.conf exists" - when: - - rhel9cis_rule_5_1_10 or - rhel9cis_rule_5_1_11 + when: rhel9cis_rule_5_1_10 or rhel9cis_rule_5_1_11 ansible.builtin.stat: path: /etc/ssh/sshd_config.d/50-redhat.conf register: discovered_sshd_50_redhat_file @@ -281,8 +276,7 @@ - name: "PRELIM | PATCH | Create journald config directory" when: - rhel9cis_syslog == 'journald' - - rhel9cis_rule_6_2_1_3 or - rhel9cis_rule_6_2_1_4 + - rhel9cis_rule_6_2_1_3 or rhel9cis_rule_6_2_1_4 tags: always ansible.builtin.file: path: /etc/systemd/journald.conf.d diff --git a/tasks/section_1/cis_1.1.2.3.x.yml b/tasks/section_1/cis_1.1.2.3.x.yml index 998d1ba..635648d 100644 --- a/tasks/section_1/cis_1.1.2.3.x.yml +++ b/tasks/section_1/cis_1.1.2.3.x.yml @@ -21,12 +21,12 @@ register: discovered_home_mount - name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | Absent" - when: discovered_dev_shm_mount is undefined + when: discovered_home_mount is undefined ansible.builtin.debug: msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" - name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | Present" - when: discovered_dev_shm_mount is undefined + when: discovered_home_mount is undefined ansible.builtin.import_tasks: file: warning_facts.yml diff --git a/tasks/section_1/cis_1.1.2.4.x.yml b/tasks/section_1/cis_1.1.2.4.x.yml index e0afd4e..f89fe3f 100644 --- a/tasks/section_1/cis_1.1.2.4.x.yml +++ b/tasks/section_1/cis_1.1.2.4.x.yml @@ -22,12 +22,12 @@ register: discovered_var_mount - name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | Absent" - when: discovered_dev_shm_mount is undefined + when: discovered_var_mount is undefined ansible.builtin.debug: msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" - name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | Present" - when: discovered_dev_shm_mount is undefined + when: discovered_var_mount is undefined ansible.builtin.import_tasks: file: warning_facts.yml From 38a173546cce29a2eb779a40ff5f805c706eb74d Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Mon, 16 Jun 2025 16:49:36 -0400 Subject: [PATCH 23/33] Update auditd with check_mode Signed-off-by: Frederick Witty --- tasks/auditd.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/auditd.yml b/tasks/auditd.yml index 7b86b94..0fa0b32 100644 --- a/tasks/auditd.yml +++ b/tasks/auditd.yml @@ -7,6 +7,7 @@ - name: "POST | AUDITD | Set supported_syscalls variable" ansible.builtin.shell: ausyscall --dump | awk '{print $2}' changed_when: false + check_mode: false failed_when: discovered_auditd_syscalls.rc not in [ 0, 1 ] register: discovered_auditd_syscalls From acacb7a6bc6582a5b1e706a9002fa6d74d054fae Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Mon, 16 Jun 2025 17:18:08 -0400 Subject: [PATCH 24/33] QA Fixes Signed-off-by: Frederick Witty --- tasks/main.yml | 7 ++----- tasks/pre_remediation_audit.yml | 1 + tasks/prelim.yml | 6 ++---- tasks/section_1/cis_1.1.1.x.yml | 3 +-- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index fe50b10..e106120 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -17,9 +17,7 @@ success_msg: "This role is running a supported version of ansible {{ ansible_version.full }} >= {{ min_ansible_version }}" - name: "Setup rules if container" - when: - - ansible_connection == 'docker' or - ansible_facts.virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] + when: ansible_connection == 'docker' or ansible_facts.virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] tags: - container_discovery - always @@ -101,8 +99,7 @@ - name: "Check account is not locked for {{ ansible_env.SUDO_USER }} | Assert local account not locked" # noqa name[template] ansible.builtin.assert: - that: - - not prelim_ansible_user_password_set.stdout.startswith("!") + that: not prelim_ansible_user_password_set.stdout.startswith("!") fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_env.SUDO_USER }} is locked - It can break access" success_msg: "The local account is not locked for {{ ansible_env.SUDO_USER }} user" diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index a2a37f1..80df209 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -1,4 +1,5 @@ --- + - name: Pre Audit Setup | Setup the LE audit when: setup_audit tags: setup_audit diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 0e2b155..3970db8 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -191,8 +191,7 @@ - name: "PRELIM | PATCH | Install dconf if gui installed" when: rhel9cis_gui - tags: - - always + tags: always ansible.builtin.package: name: dconf state: present @@ -201,8 +200,7 @@ when: - rhel9cis_rule_3_1_2 - not system_is_container - tags: - - always + tags: always block: - name: "PRELIM | AUDIT | Discover is wireless adapter on system" ansible.builtin.command: find /sys/class/net/*/ -type d -name wireless diff --git a/tasks/section_1/cis_1.1.1.x.yml b/tasks/section_1/cis_1.1.1.x.yml index adc094d..e67bb39 100644 --- a/tasks/section_1/cis_1.1.1.x.yml +++ b/tasks/section_1/cis_1.1.1.x.yml @@ -27,8 +27,7 @@ mode: 'go-rwx' - name: "1.1.1.1 | PATCH | Ensure cramfs kernel module is not available | Disable cramfs" - when: - - not system_is_container + when: not system_is_container community.general.modprobe: name: cramfs state: absent From d2de2783a80afc1155b3232c8e78c6ac0665a147 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 19 Jun 2025 16:31:37 +0100 Subject: [PATCH 25/33] added ability to fetch audit and update title Signed-off-by: Mark Bolwell --- tasks/audit_only.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tasks/audit_only.yml b/tasks/audit_only.yml index d6f20ea..a33cb94 100644 --- a/tasks/audit_only.yml +++ b/tasks/audit_only.yml @@ -1,10 +1,17 @@ --- +- name: Audit_only | Fetch audit files + when: + - fetch_audit_output + - audit_only + ansible.builtin.import_tasks: + file: fetch_audit_output.yml + - name: Audit_only | Show Audit Summary when: audit_only ansible.builtin.debug: msg: "{{ audit_results.split('\n') }}" -- name: Audit_only | Stop Playbook Audit Only selected +- name: Audit_only | Stop task for host as audit_only selected when: audit_only - ansible.builtin.meta: end_play + ansible.builtin.meta: end_host From 379b18455426c5288f3e21e7434576fc9dd68082 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 19 Jun 2025 16:32:20 +0100 Subject: [PATCH 26/33] added changed_when to fix false warning errors Signed-off-by: Mark Bolwell --- tasks/fetch_audit_output.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/fetch_audit_output.yml b/tasks/fetch_audit_output.yml index 563b699..e440185 100644 --- a/tasks/fetch_audit_output.yml +++ b/tasks/fetch_audit_output.yml @@ -8,6 +8,7 @@ src: "{{ item }}" dest: "{{ audit_output_destination }}" flat: true + changed_when: true failed_when: false register: discovered_audit_fetch_state loop: From aaea8352de3a8b18fa48808dfa4d6cbd69522197 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 19 Jun 2025 16:33:29 +0100 Subject: [PATCH 27/33] updated Signed-off-by: Mark Bolwell --- Changelog.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Changelog.md b/Changelog.md index 7542aa1..492516a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,11 @@ # Changes to rhel9CIS +## Based on CIS v2.0.0 + +Update to audit_only to allow fetching results +resolved false warning for fetch audit + ## 2.0.1 - Based on CIS v2.0.0 - Thanks to @polski-g several issues and improvements added From 82cc458d7a215c2b940228c59db3533ddc567b45 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 20 Jun 2025 11:32:31 +0100 Subject: [PATCH 28/33] Fix logic and notes for in crypto policy building Signed-off-by: Mark Bolwell --- Changelog.md | 1 + defaults/main.yml | 17 +++++++++-------- handlers/main.yml | 2 +- tasks/main.yml | 5 ++--- vars/main.yml | 6 ++++++ 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Changelog.md b/Changelog.md index 492516a..573afd4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Update to audit_only to allow fetching results resolved false warning for fetch audit +Improved documentation and variable compilation for crypto policies ## 2.0.1 - Based on CIS v2.0.0 diff --git a/defaults/main.yml b/defaults/main.yml index cc49b0a..23312e5 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -12,7 +12,7 @@ os_check: true # Disruption is high ## Run tests that are considered higher risk and could have a system impact if not properly tested ## Default false -## Will be fine if clean new un configured build +## Will be fine if clean new un-configured build rhel9cis_disruption_high: false ## Switching on/off specific baseline sections @@ -37,6 +37,7 @@ rhel9cis_level_2: true # Create managed not custom local_facts files create_benchmark_facts: true ansible_facts_path: /etc/ansible/facts.d + ## Section 1.6 - Mandatory Access Control # This variable governs whether SELinux is disabled or not. If SELinux is NOT DISABLED by setting # 'rhel9cis_selinux_disable' to 'true', the 1.6 subsection will be executed. @@ -111,7 +112,7 @@ audit_conf_dest: "/opt" # Where the audit logs are stored audit_log_dir: '/opt' -## Ability to collect and take audit files moving to a centralised location +## Ability to collect and take audit files moving to a centralized location # This enables the collection of the files from the host fetch_audit_output: false @@ -238,7 +239,7 @@ rhel9cis_rule_1_8_8: true rhel9cis_rule_1_8_9: true rhel9cis_rule_1_8_10: true -# Section 2 rules are controlling Services (Special Purpose Services, and service clients) +# Section 2 rules are controling Services (Special Purpose Services, and service clients) ## Configure Server Services rhel9cis_rule_2_1_1: true rhel9cis_rule_2_1_2: true @@ -579,8 +580,8 @@ rhel9cis_crypto_policy: 'DEFAULT' ## Control 1.6 # This variable contains the value of the crypto policy module(combinations of policies and # sub-policies) to be allowed as default setting. Allowed options are defined in 'vars/main.yml' file, -# using 'rhel9cis_allowed_crypto_policies_modules' variable. -rhel9cis_crypto_policy_module: '' +# using those listed in the 'rhel9cis_allowed_crypto_policies_modules' variable. +rhel9cis_additional_crypto_policy_module: '' ## Controls: # - 1.7.1 - Ensure message of the day is configured properly @@ -816,7 +817,7 @@ rhel9cis_sshd_clientalivecountmax: 3 rhel9cis_sshd_clientaliveinterval: 15 ## Control 5.1.12 - disable forwarding -# By Default this will also disable x11 forwarding +# By Default this will also disablex11 forwarding # set 'yes' if x11 is required this can be changed to run in /etc/ssh/ssh_config.d/50-redhat.conf rhel9cis_sshd_x11forwarding: 'no' @@ -1046,14 +1047,14 @@ rhel9cis_bash_umask: '0027' # 0027 or more restrictive # These are discovered via logins.def if set true rhel9cis_discover_int_uid: true # This variable sets the minimum number from which to search for UID -# Note that the value will be dynamically overwritten if variable `discover_int_uid` has +# Note that the value will be dynamically overwritten if variable `rhel9cis_discover_int_uid` has # been set to `true`. min_int_uid: 1000 ### Controls: # - Ensure local interactive user home directories exist # - Ensure local interactive users own their home directories # This variable sets the maximum number at which the search stops for UID -# Note that the value will be dynamically overwritten if variable `discover_int_uid` has +# Note that the value will be dynamically overwritten if variable `rhel9cis_discover_int_uid` has # been set to `true`. max_int_uid: 65533 diff --git a/handlers/main.yml b/handlers/main.yml index 1a3b66e..4bc5a08 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -186,7 +186,7 @@ - name: Update Crypto Policy ansible.builtin.set_fact: - rhel9cis_full_crypto_policy: "{{ rhel9cis_crypto_policy }}{% if rhel9cis_crypto_policy_module | length > 0 %}{{ rhel9cis_crypto_policy_module }}{% endif %}" + rhel9cis_full_crypto_policy: "{{ rhel9cis_crypto_policy }}{{ rhel9cis_crypto_policy_module }}:{{ rhel9cis_additional_crypto_policy_module }}" notify: Set Crypto Policy - name: Set Crypto Policy diff --git a/tasks/main.yml b/tasks/main.yml index 43ec09c..9bfcc51 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -61,7 +61,7 @@ - crypto - NIST800-53R5_SC-6 ansible.builtin.assert: - that: rhel9cis_crypto_policy_module in rhel9cis_allowed_crypto_policies_modules + that: rhel9cis_additional_crypto_policy_module in rhel9cis_allowed_crypto_policies_modules fail_msg: "Crypto policy module is not a permitted version" success_msg: "Crypto policy module is a permitted version" @@ -132,9 +132,8 @@ - rule_5.4.2.4 block: - name: "Ensure root password is set" - ansible.builtin.shell: passwd -S root | grep -E "(Password set, SHA512 crypt|Password locked)" + ansible.builtin.shell: passwd -S root | egrep -e "(Password set, SHA512 crypt|Password locked)" changed_when: false - failed_when: prelim_root_passwd_set.rc not in [ 0, 1 ] register: prelim_root_passwd_set - name: "Ensure root password is set" diff --git a/vars/main.yml b/vars/main.yml index 5eed07c..9337d58 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -7,10 +7,16 @@ rhel9cis_allowed_crypto_policies: - 'FUTURE' - 'FIPS' +# Following is left blank for ability to build string +rhel9cis_crypto_policy_module: '' + +# Do not adjust these are recognized as part of the CIS benchmark and used during testing rhel9cis_allowed_crypto_policies_modules: + # Recognized by CIS as possible extra options - 'OSPP' - 'AD-SUPPORT' - 'AD-SUPPORT-LEGACY' + # The following are already included in 1.6.x controls - 'NO-SHA1' - 'NO-SSHCBC' - 'NO-SSHETM' From 9db79097f91ead59e1a1dfa6a038fffad99184d8 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 20 Jun 2025 12:14:14 +0100 Subject: [PATCH 29/33] fixed crypto logic Signed-off-by: Mark Bolwell --- handlers/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handlers/main.yml b/handlers/main.yml index 4bc5a08..1894300 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -186,7 +186,7 @@ - name: Update Crypto Policy ansible.builtin.set_fact: - rhel9cis_full_crypto_policy: "{{ rhel9cis_crypto_policy }}{{ rhel9cis_crypto_policy_module }}:{{ rhel9cis_additional_crypto_policy_module }}" + rhel9cis_full_crypto_policy: "{{ rhel9cis_crypto_policy }}{{ rhel9cis_crypto_policy_module }}{% if rhel9cis_additional_crypto_policy_module | length > 0 %}:{{ rhel9cis_additional_crypto_policy_module }}{% endif %}" notify: Set Crypto Policy - name: Set Crypto Policy From 0ee2de5e208f902fd21e3c3a6053dfea1bc826c0 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Fri, 27 Jun 2025 12:04:29 -0400 Subject: [PATCH 30/33] Addresses #318 - Thank you @kodebach & @bgro Signed-off-by: Frederick Witty --- Changelog.md | 12 +++++++----- tasks/main.yml | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Changelog.md b/Changelog.md index 573afd4..52d568b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,11 +1,13 @@ # Changes to rhel9CIS +## 2.0.2 - Based on CIS v2.0.0 -## Based on CIS v2.0.0 - -Update to audit_only to allow fetching results -resolved false warning for fetch audit -Improved documentation and variable compilation for crypto policies +- Update to audit_only to allow fetching results +- resolved false warning for fetch audit +- fix root user check +- Improved documentation and variable compilation for crypto policies +- Addresses #318 - Thank you @kodebach & @bgro + - Improved logic for 5.2.4 to exclude rhel9cis_sudoers_exclude_nopasswd_list in pre-check tasks/main.yml ## 2.0.1 - Based on CIS v2.0.0 diff --git a/tasks/main.yml b/tasks/main.yml index f5a57db..9582bed 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -99,9 +99,9 @@ - name: "Check account is not locked for {{ ansible_env.SUDO_USER }} | Assert local account not locked" # noqa name[template] ansible.builtin.assert: - that: not prelim_ansible_user_password_set.stdout.startswith("!") + that: (not prelim_ansible_user_password_set.stdout.startswith("!")) or (ansible_env.SUDO_USER in rhel9cis_sudoers_exclude_nopasswd_list) fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_env.SUDO_USER }} is locked - It can break access" - success_msg: "The local account is not locked for {{ ansible_env.SUDO_USER }} user" + success_msg: "The local account is not locked for {{ ansible_env.SUDO_USER }} is not locked or included in the exception list for rule 5.2.4" - name: "Check authselect profile is selected" when: rhel9cis_allow_authselect_updates From 874890ee400eba6fc3b609796a685c1f7324cfa6 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Fri, 27 Jun 2025 12:06:18 -0400 Subject: [PATCH 31/33] Update site.yml hosts logic Signed-off-by: Frederick Witty --- site.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site.yml b/site.yml index f3f0fae..4386b04 100644 --- a/site.yml +++ b/site.yml @@ -1,7 +1,7 @@ --- - name: Apply ansible-lockdown hardening - hosts: all + hosts: "{{ hosts | default('all') }}" become: true roles: - role: "{{ playbook_dir }}" From 2142934148d33c6a1e7f71a9674f007847ae7fcb Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 1 Jul 2025 09:29:08 +0100 Subject: [PATCH 32/33] updated 6.3.3.5 Signed-off-by: Mark Bolwell --- templates/audit/99_auditd.rules.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/audit/99_auditd.rules.j2 b/templates/audit/99_auditd.rules.j2 index 4d9c0d3..4fa4516 100644 --- a/templates/audit/99_auditd.rules.j2 +++ b/templates/audit/99_auditd.rules.j2 @@ -56,8 +56,10 @@ -w /etc/issue -p wa -k system-locale -w /etc/issue.net -p wa -k system-locale -w /etc/hosts -p wa -k system-locale +-w /etc/hostname -p wa -k system-locale -w /etc/sysconfig/network -p wa -k system-locale -w /etc/sysconfig/network-scripts -p wa -k system-locale +-w /etc/NetworkManager -p wa -k system-locale {% endif %} {% if rhel9cis_rule_6_3_3_6 %} {% for proc in discovered_priv_procs.stdout_lines -%} From b8ed2dfdac24d7526cdfbe1db0f58c75491356d4 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 1 Jul 2025 09:37:25 +0100 Subject: [PATCH 33/33] updated Signed-off-by: Mark Bolwell --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 52d568b..8ca9c4f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ - Improved documentation and variable compilation for crypto policies - Addresses #318 - Thank you @kodebach & @bgro - Improved logic for 5.2.4 to exclude rhel9cis_sudoers_exclude_nopasswd_list in pre-check tasks/main.yml +- rule_6.3.3.5 updated for missing checks ## 2.0.1 - Based on CIS v2.0.0