From 683177e46fd0cfc8a3e4a4a98adbc3a4948d6b7f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 31 Mar 2025 12:33:56 +0100 Subject: [PATCH 001/139] issue #305 addressed Signed-off-by: Mark Bolwell --- tasks/section_6/cis_6.2.1.x.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tasks/section_6/cis_6.2.1.x.yml b/tasks/section_6/cis_6.2.1.x.yml index 3afa31c..2d861e8 100644 --- a/tasks/section_6/cis_6.2.1.x.yml +++ b/tasks/section_6/cis_6.2.1.x.yml @@ -96,15 +96,21 @@ - rule_6.2.1.4 block: - name: "6.2.1.4 | PATCH | Ensure only one logging system is in use | when rsyslog" - when: rhel9cis_syslog == "rsyslog" + when: + - rhel9cis_syslog == "rsyslog" + - "'systemd-journald' in ansible_facts.packages" ansible.builtin.systemd: name: systemd-journald state: stopped enabled: false - name: "6.2.1.4 | PATCH | Ensure only one logging system is in use | when journald" - when: rhel9cis_syslog == "journald" + when: + - rhel9cis_syslog == "journald" + - "'rsyslog' in ansible_facts.packages" ansible.builtin.systemd: name: rsyslog state: stopped enabled: false + register: discovered_rsyslog_service + From b616f70d862527715ffd6d0092a87efe3b3a1512 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 31 Mar 2025 12:35:07 +0100 Subject: [PATCH 002/139] addressed #306 Signed-off-by: Mark Bolwell --- tasks/section_2/cis_2.1.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_2/cis_2.1.x.yml b/tasks/section_2/cis_2.1.x.yml index e49e733..98ede95 100644 --- a/tasks/section_2/cis_2.1.x.yml +++ b/tasks/section_2/cis_2.1.x.yml @@ -657,7 +657,7 @@ - postfix - NIST800-53R5_CM-7 - rule_2.1.21 - notify: Restart_postfix + notify: Restart postfix ansible.builtin.lineinfile: path: /etc/postfix/main.cf regexp: "^(#)?inet_interfaces" From cedf510b94abb6220981d87b29cb349f5418f5c8 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 31 Mar 2025 12:36:27 +0100 Subject: [PATCH 003/139] addressed #309 Signed-off-by: Mark Bolwell --- tasks/section_2/cis_2.1.x.yml | 40 +++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tasks/section_2/cis_2.1.x.yml b/tasks/section_2/cis_2.1.x.yml index 98ede95..28e372d 100644 --- a/tasks/section_2/cis_2.1.x.yml +++ b/tasks/section_2/cis_2.1.x.yml @@ -25,7 +25,7 @@ when: - not rhel9cis_autofs_services - rhel9cis_autofs_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: autofs enabled: false @@ -57,7 +57,7 @@ when: - not rhel9cis_avahi_server - rhel9cis_avahi_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: "{{ item }}" enabled: false @@ -90,7 +90,7 @@ when: - not rhel9cis_dhcp_server - rhel9cis_dhcp_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: "{{ item }}" enabled: false @@ -123,7 +123,7 @@ when: - not rhel9cis_dns_server - rhel9cis_dns_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: named.service enabled: false @@ -153,7 +153,7 @@ when: - not rhel9cis_dnsmasq_server - rhel9cis_dnsmasq_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: dnsmasq.service enabled: false @@ -184,7 +184,7 @@ when: - not rhel9cis_samba_server - rhel9cis_samba_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: smb.service enabled: false @@ -215,7 +215,7 @@ when: - not rhel9cis_ftp_server - rhel9cis_ftp_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: vsftpd.service enabled: false @@ -249,7 +249,7 @@ when: - not rhel9cis_message_server - rhel9cis_message_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: "{{ item }}" enabled: false @@ -285,7 +285,7 @@ when: - not rhel9cis_nfs_server - rhel9cis_nfs_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: nfs-server.service enabled: false @@ -302,7 +302,7 @@ - nis - NIST800-53R5_CM-7 - rule_2.1.10 - notify: Systemd_daemon_reload + notify: Systemd daemon reload block: - name: "2.1.10 | PATCH | Ensure nis server services are not in use | Remove package" when: @@ -344,7 +344,7 @@ when: - not rhel9cis_print_server - rhel9cis_print_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: "{{ item }}" enabled: false @@ -378,7 +378,7 @@ when: - not rhel9cis_rpc_server - rhel9cis_rpc_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: "{{ item }}" enabled: false @@ -412,7 +412,7 @@ when: - not rhel9cis_rsync_server - rhel9cis_rsync_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: "{{ item }}" enabled: false @@ -445,7 +445,7 @@ when: - not rhel9cis_snmp_server - rhel9cis_snmp_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: snmpd.service enabled: false @@ -476,7 +476,7 @@ when: - not rhel9cis_telnet_server - rhel9cis_telnet_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: telnet.socket enabled: false @@ -506,7 +506,7 @@ when: - not rhel9cis_tftp_server - rhel9cis_tftp_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: "{{ item }}" enabled: false @@ -540,7 +540,7 @@ when: - not rhel9cis_squid_server - rhel9cis_squid_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: squid.service enabled: false @@ -580,7 +580,7 @@ when: - not rhel9cis_httpd_server - rhel9cis_httpd_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: httpd.service enabled: false @@ -591,7 +591,7 @@ when: - not rhel9cis_nginx_server - rhel9cis_nginx_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: ngnix.service enabled: false @@ -621,7 +621,7 @@ when: - not rhel9cis_xinetd_server - rhel9cis_xinetd_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: xinetd.service enabled: false From 7b1c8e9ef0f3654ef65e86606508ceca9d0e4b24 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 31 Mar 2025 12:37:58 +0100 Subject: [PATCH 004/139] additional fix for #309 Signed-off-by: Mark Bolwell --- tasks/section_3/cis_3.1.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index e8934d4..68a66de 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -86,7 +86,7 @@ when: - not rhel9cis_bluetooth_service - rhel9cis_bluetooth_mask - notify: Systemd_daemon_reload + notify: Systemd daemon reload ansible.builtin.systemd: name: bluetooth.service enabled: false From 82904557c7443a584988c5badf9bfa9f1550befd Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 31 Mar 2025 12:38:51 +0100 Subject: [PATCH 005/139] updated workflows Signed-off-by: Mark Bolwell --- .github/workflows/devel_pipeline_validation.yml | 1 + .github/workflows/main_pipeline_validation.yml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.github/workflows/devel_pipeline_validation.yml b/.github/workflows/devel_pipeline_validation.yml index c9328cb..10750a2 100644 --- a/.github/workflows/devel_pipeline_validation.yml +++ b/.github/workflows/devel_pipeline_validation.yml @@ -7,6 +7,7 @@ types: [opened, reopened, synchronize] branches: - devel + - benchmark* paths: - '**.yml' - '**.sh' diff --git a/.github/workflows/main_pipeline_validation.yml b/.github/workflows/main_pipeline_validation.yml index ab11c37..6792a00 100644 --- a/.github/workflows/main_pipeline_validation.yml +++ b/.github/workflows/main_pipeline_validation.yml @@ -7,6 +7,7 @@ types: [opened, reopened, synchronize] branches: - main + - latest paths: - '**.yml' - '**.sh' @@ -23,6 +24,7 @@ # A workflow run is made up of one or more jobs # that can run sequentially or in parallel jobs: + # This workflow contains a single job that tests the playbook playbook-test: # The type of runner that the job will run on From 576531e9862c596da454e1283cdd549cf6806827 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 31 Mar 2025 14:50:40 +0100 Subject: [PATCH 006/139] fetch audit and compliance facts added Signed-off-by: Mark Bolwell --- defaults/main.yml | 17 +++++++++ tasks/fetch_audit_output.yml | 46 +++++++++++++++++++++++ tasks/main.yml | 32 ++++++++++++++++ templates/etc/ansible/compliance_facts.j2 | 39 +++++++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 tasks/fetch_audit_output.yml create mode 100644 templates/etc/ansible/compliance_facts.j2 diff --git a/defaults/main.yml b/defaults/main.yml index da5ca20..f2bd882 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -33,6 +33,9 @@ rhel9cis_section7: true rhel9cis_level_1: true 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. @@ -107,6 +110,20 @@ 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 +# This enables the collection of the files from the host +fetch_audit_output: false + +# Method of getting,uploading the summary files +## Ensure access and permissions are avaiable for these to occur. +## options are +# fetch - fetches from server and moves to location on the ansible controller (could be a mount point available to controller) +# copy - copies file to a location available to the managed node +audit_output_collection_method: fetch + +# Location to put the audit files +audit_output_destination: /opt/audit_summaries/ + ### Goss Settings ## ####### END ######## diff --git a/tasks/fetch_audit_output.yml b/tasks/fetch_audit_output.yml new file mode 100644 index 0000000..c6f7b5e --- /dev/null +++ b/tasks/fetch_audit_output.yml @@ -0,0 +1,46 @@ +--- + +# Stage to copy audit output to a centralised location + +- name: "FETCH_AUDIT_FILES | Fetch files and copy to controller" + when: audit_output_collection_method == "fetch" + ansible.builtin.fetch: + src: "{{ item }}" + dest: "{{ audit_output_destination }}" + flat: true + failed_when: false + register: discovered_audit_fetch_state + loop: + - "{{ pre_audit_outfile }}" + - "{{ post_audit_outfile }}" + become: false + +# Added this option for continuity but could be changed by adjusting the variable audit_conf_dest +# Allowing backup to one location +- name: "FETCH_AUDIT_FILES | Copy files to location available to managed node" + when: audit_output_collection_method == "copy" + ansible.builtin.copy: + src: "{{ item }}" + dest: "{{ audit_output_destination }}" + mode: 'u-x,go-wx' + flat: true + failed_when: false + register: discovered_audit_fetch_copy_state + loop: + - pre_audit_outfile + - post_audit_outfile + +- name: "FETCH_AUDIT_FILES | Fetch files and copy to controller | Warning if issues with fetch_audit_files" + when: + - (discovered_audit_fetch_state is defined and not discovered_audit_fetch_state.changed) or + (discovered_audit_copy_state is defined and not discovered_audit_copy_state.changed) + block: + - name: "FETCH_AUDIT_FILES | Fetch files and copy to controller | Warning if issues with fetch_audit_files" + ansible.builtin.debug: + msg: "Warning!! Unable to write to localhost {{ audit_output_destination }} for audit file copy" + + - name: "FETCH_AUDIT_FILES | Fetch files and copy to controller | Warning if issues with fetch_audit_files" + vars: + warn_control_id: "FETCH_AUDIT_FILES" + ansible.builtin.import_tasks: + file: warning_facts.yml diff --git a/tasks/main.yml b/tasks/main.yml index a0a58f8..ccd6c1d 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -209,11 +209,43 @@ - name: "Run post_remediation audit" when: run_audit + tags: always ansible.builtin.import_tasks: file: post_remediation_audit.yml +- name: Add ansible file showing Benchmark and levels applied + when: Create_benchmark_facts + tags: + - always + - benchmark + block: + - name: Create ansible facts directory + ansible.builtin.file: + path: "{{ ansible_facts_path }}" + state: directory + owner: root + group: root + mode: 'u=rwx,go=rx' + + - name: Create ansible facts file + ansible.builtin.template: + src: etc/ansible/compliance_facts.j2 + dest: "{{ ansible_facts_path }}/compliance_facts.fact" + owner: root + group: root + mode: "u-x,go-wx" + +- name: Fetch audit files + when: + - fetch_audit_output + - run_audit + tags: always + ansible.builtin.import_tasks: + file: fetch_audit_output.yml + - name: "Show Audit Summary" when: run_audit + tags: always ansible.builtin.debug: msg: "{{ audit_results.split('\n') }}" diff --git a/templates/etc/ansible/compliance_facts.j2 b/templates/etc/ansible/compliance_facts.j2 new file mode 100644 index 0000000..1e7d896 --- /dev/null +++ b/templates/etc/ansible/compliance_facts.j2 @@ -0,0 +1,39 @@ +# CIS Hardening Carried out +# Added as part of ansible-lockdown CIS baseline +# provided by Mindpoint Group - A Tyto Athene Company + +[Benchmark_Details] +# Benchmark release +Benchmark_release = CIS-{{ benchmark_version }} +Benchmark_run_date = {{ '%Y-%m-%d - %H:%M:%S' | ansible.builtin.strftime }} +# If options set (doesn't mean it ran all controls) +level_1_hardening_enabled = {{ rhel9cis_level_1 }} +level_2_hardening_enabled = {{ rhel9cis_level_2 }} + +{% if ansible_run_tags | length > 0 %} +# If tags used to stipulate run level +{% if 'level1-server' in ansible_run_tags %} +Level_1_Server_tag_run = true +{% endif %} +{% if 'level2-server' in ansible_run_tags %} +Level_2_Server_tag_run = true +{% endif %} +{% if 'level1-workstation' in ansible_run_tags %} +Level_1_workstation_tag_run = true +{% endif %} +{% if 'level2-workstation' in ansible_run_tags %} +Level_2_workstation_tag_run = true +{% endif %} +{% endif %} + +[Benchmark_Audit_Details] +{% if run_audit %} +# Audit run +audit_file_location_local = {{ audit_log_dir }} +{% if not audit_only %} +audit_summary = {{ post_audit_results }} +{% endif %} +{% if fetch_audit_output %} +audit_files_location_central = {{ audit_output_destination }} +{% endif %} +{% endif %} From 04666c219c9a1eb751419852ba752c355b3040c1 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 31 Mar 2025 15:13:46 +0100 Subject: [PATCH 007/139] Added for #288 ansible_facts Signed-off-by: Mark Bolwell --- templates/etc/ansible/compliance_facts.j2 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/etc/ansible/compliance_facts.j2 b/templates/etc/ansible/compliance_facts.j2 index 1e7d896..ffa366c 100644 --- a/templates/etc/ansible/compliance_facts.j2 +++ b/templates/etc/ansible/compliance_facts.j2 @@ -2,7 +2,7 @@ # Added as part of ansible-lockdown CIS baseline # provided by Mindpoint Group - A Tyto Athene Company -[Benchmark_Details] +[benchmark_details] # Benchmark release Benchmark_release = CIS-{{ benchmark_version }} Benchmark_run_date = {{ '%Y-%m-%d - %H:%M:%S' | ansible.builtin.strftime }} @@ -26,14 +26,14 @@ Level_2_workstation_tag_run = true {% endif %} {% endif %} -[Benchmark_Audit_Details] +[benchmark_audit_details] {% if run_audit %} # Audit run -audit_file_location_local = {{ audit_log_dir }} +audit_file_local_location = {{ audit_log_dir }} {% if not audit_only %} audit_summary = {{ post_audit_results }} {% endif %} {% if fetch_audit_output %} -audit_files_location_central = {{ audit_output_destination }} +audit_files_centralized_location = {{ audit_output_destination }} {% endif %} {% endif %} From fc2e153ce90350576e8ae83b91893edca0bc9ddf Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 1 Apr 2025 07:55:08 +0100 Subject: [PATCH 008/139] updated section naming Signed-off-by: Mark Bolwell --- templates/etc/ansible/compliance_facts.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/etc/ansible/compliance_facts.j2 b/templates/etc/ansible/compliance_facts.j2 index ffa366c..f313bec 100644 --- a/templates/etc/ansible/compliance_facts.j2 +++ b/templates/etc/ansible/compliance_facts.j2 @@ -2,7 +2,7 @@ # Added as part of ansible-lockdown CIS baseline # provided by Mindpoint Group - A Tyto Athene Company -[benchmark_details] +[lockdown_details] # Benchmark release Benchmark_release = CIS-{{ benchmark_version }} Benchmark_run_date = {{ '%Y-%m-%d - %H:%M:%S' | ansible.builtin.strftime }} @@ -26,7 +26,7 @@ Level_2_workstation_tag_run = true {% endif %} {% endif %} -[benchmark_audit_details] +[lockdown_audit_details] {% if run_audit %} # Audit run audit_file_local_location = {{ audit_log_dir }} From 9bbf5b7a81d8a4db1048cc055318363df4c3c9cb Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 1 Apr 2025 08:08:28 +0100 Subject: [PATCH 009/139] updated var name to remove capital Signed-off-by: Mark Bolwell --- defaults/main.yml | 2 +- tasks/main.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index f2bd882..32c4679 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -34,7 +34,7 @@ rhel9cis_level_1: true rhel9cis_level_2: true # Create managed not custom local_facts files -Create_benchmark_facts: true +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 diff --git a/tasks/main.yml b/tasks/main.yml index ccd6c1d..57fd8fd 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -214,7 +214,7 @@ file: post_remediation_audit.yml - name: Add ansible file showing Benchmark and levels applied - when: Create_benchmark_facts + when: create_benchmark_facts tags: - always - benchmark From bd425a068d4b23e16d8793a1fb94a205323bd33c Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 1 Apr 2025 08:14:02 +0100 Subject: [PATCH 010/139] lint updates Signed-off-by: Mark Bolwell --- tasks/main.yml | 6 +++--- tasks/section_1/cis_1.4.x.yml | 2 +- tasks/section_6/cis_6.2.1.x.yml | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index 57fd8fd..00281da 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -116,7 +116,7 @@ fail_msg: "You still have the default name for your authselect profile" - name: "Check authselect profile is selected | Check current profile" - ansible.builtin.shell: authselect list + ansible.builtin.command: authselect list changed_when: false failed_when: prelim_authselect_current_profile.rc not in [ 0, 1 ] register: prelim_authselect_current_profile @@ -216,8 +216,8 @@ - name: Add ansible file showing Benchmark and levels applied when: create_benchmark_facts tags: - - always - - benchmark + - always + - benchmark block: - name: Create ansible facts directory ansible.builtin.file: diff --git a/tasks/section_1/cis_1.4.x.yml b/tasks/section_1/cis_1.4.x.yml index d3534cd..c6c3aac 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -57,7 +57,7 @@ - name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured | efi based system | Build Options" when: item not in discovered_efi_fstab.stdout ansible.builtin.set_fact: - efi_mount_opts_addition: "{{ efi_mount_opts_addition + ',' + item }}" + efi_mount_opts_addition: "{{ efi_mount_opts_addition + ',' + item }}" loop: "{{ efi_mount_options }}" - name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured | efi based system | Add mount options" diff --git a/tasks/section_6/cis_6.2.1.x.yml b/tasks/section_6/cis_6.2.1.x.yml index 2d861e8..fa75880 100644 --- a/tasks/section_6/cis_6.2.1.x.yml +++ b/tasks/section_6/cis_6.2.1.x.yml @@ -113,4 +113,3 @@ state: stopped enabled: false register: discovered_rsyslog_service - From 97baa4afe04097d319d36233e85732255a90f419 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 17:34:10 +0000 Subject: [PATCH 011/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/gitleaks/gitleaks: v8.24.0 → v8.24.2](https://github.com/gitleaks/gitleaks/compare/v8.24.0...v8.24.2) - [github.com/ansible-community/ansible-lint: v25.1.3 → v25.2.1](https://github.com/ansible-community/ansible-lint/compare/v25.1.3...v25.2.1) - [github.com/adrienverge/yamllint.git: v1.35.1 → v1.37.0](https://github.com/adrienverge/yamllint.git/compare/v1.35.1...v1.37.0) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4791982..c12360b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,12 +41,12 @@ repos: - id: detect-secrets - repo: https://github.com/gitleaks/gitleaks - rev: v8.24.0 + rev: v8.24.2 hooks: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.1.3 + rev: v25.2.1 hooks: - id: ansible-lint name: Ansible-lint @@ -65,7 +65,7 @@ repos: # - ansible-core>=2.10.1 - repo: https://github.com/adrienverge/yamllint.git - rev: v1.35.1 # or higher tag + rev: v1.37.0 # or higher tag hooks: - id: yamllint name: Check YAML Lint From ba57380a72a12f49342ac9e84e87e6600142b45a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 17:21:59 +0000 Subject: [PATCH 012/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/gitleaks/gitleaks: v8.24.2 → v8.24.3](https://github.com/gitleaks/gitleaks/compare/v8.24.2...v8.24.3) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c12360b..99408de 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: - id: detect-secrets - repo: https://github.com/gitleaks/gitleaks - rev: v8.24.2 + rev: v8.24.3 hooks: - id: gitleaks From 52f5f23b00b06d795e55bd94e10b2bd2723cd1e8 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 15 Apr 2025 11:04:33 +0100 Subject: [PATCH 013/139] improve ansible facts conditionals Signed-off-by: Mark Bolwell --- tasks/main.yml | 13 ++++++++----- templates/etc/ansible/compliance_facts.j2 | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index 00281da..e285e8d 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -213,13 +213,16 @@ ansible.builtin.import_tasks: file: post_remediation_audit.yml -- name: Add ansible file showing Benchmark and levels applied - when: create_benchmark_facts +- name: Add ansible file showing Benchmark and levels applied if audit details not present + when: + - create_benchmark_facts + - (post_audit_summary is defined) or + (ansible_local['compliance_facts']['lockdown_audit_details']['audit_summary'] is undefined and post_audit_summary is undefined) tags: - always - benchmark block: - - name: Create ansible facts directory + - name: Create ansible facts directory if audit facts not present ansible.builtin.file: path: "{{ ansible_facts_path }}" state: directory @@ -227,13 +230,13 @@ group: root mode: 'u=rwx,go=rx' - - name: Create ansible facts file + - name: Create ansible facts file and levels applied if audit facts not present ansible.builtin.template: src: etc/ansible/compliance_facts.j2 dest: "{{ ansible_facts_path }}/compliance_facts.fact" owner: root group: root - mode: "u-x,go-wx" + mode: 'u-x,go=r' - name: Fetch audit files when: diff --git a/templates/etc/ansible/compliance_facts.j2 b/templates/etc/ansible/compliance_facts.j2 index f313bec..f8725e1 100644 --- a/templates/etc/ansible/compliance_facts.j2 +++ b/templates/etc/ansible/compliance_facts.j2 @@ -29,6 +29,7 @@ Level_2_workstation_tag_run = true [lockdown_audit_details] {% if run_audit %} # Audit run +audit_run_date = {{ '%Y-%m-%d - %H:%M:%S' | ansible.builtin.strftime }} audit_file_local_location = {{ audit_log_dir }} {% if not audit_only %} audit_summary = {{ post_audit_results }} From 3d4bc2ab3d35bb1f58a56c1d42cf364f30010987 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 15 Apr 2025 11:07:15 +0100 Subject: [PATCH 014/139] Update name and conditionals Signed-off-by: Mark Bolwell --- tasks/fetch_audit_output.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tasks/fetch_audit_output.yml b/tasks/fetch_audit_output.yml index c6f7b5e..563b699 100644 --- a/tasks/fetch_audit_output.yml +++ b/tasks/fetch_audit_output.yml @@ -2,7 +2,7 @@ # Stage to copy audit output to a centralised location -- name: "FETCH_AUDIT_FILES | Fetch files and copy to controller" +- name: "POST | FETCH | Fetch files and copy to controller" when: audit_output_collection_method == "fetch" ansible.builtin.fetch: src: "{{ item }}" @@ -17,7 +17,7 @@ # Added this option for continuity but could be changed by adjusting the variable audit_conf_dest # Allowing backup to one location -- name: "FETCH_AUDIT_FILES | Copy files to location available to managed node" +- name: "POST | FETCH | Copy files to location available to managed node" when: audit_output_collection_method == "copy" ansible.builtin.copy: src: "{{ item }}" @@ -25,21 +25,21 @@ mode: 'u-x,go-wx' flat: true failed_when: false - register: discovered_audit_fetch_copy_state + register: discovered_audit_copy_state loop: - - pre_audit_outfile - - post_audit_outfile + - "{{ pre_audit_outfile }}" + - "{{ post_audit_outfile }}" -- name: "FETCH_AUDIT_FILES | Fetch files and copy to controller | Warning if issues with fetch_audit_files" +- name: "POST | FETCH | Fetch files and copy to controller | Warning if issues with fetch_audit_files" when: - - (discovered_audit_fetch_state is defined and not discovered_audit_fetch_state.changed) or - (discovered_audit_copy_state is defined and not discovered_audit_copy_state.changed) + - (audit_output_collection_method == "fetch" and not discovered_audit_fetch_state.changed) or + (audit_output_collection_method == "copy" and not discovered_audit_copy_state.changed) block: - - name: "FETCH_AUDIT_FILES | Fetch files and copy to controller | Warning if issues with fetch_audit_files" + - name: "POST | FETCH | Fetch files and copy to controller | Warning if issues with fetch_audit_files" ansible.builtin.debug: msg: "Warning!! Unable to write to localhost {{ audit_output_destination }} for audit file copy" - - name: "FETCH_AUDIT_FILES | Fetch files and copy to controller | Warning if issues with fetch_audit_files" + - name: "POST | FETCH | Fetch files and copy to controller | Warning if issues with fetch_audit_files" vars: warn_control_id: "FETCH_AUDIT_FILES" ansible.builtin.import_tasks: From ec57b85fdf5de6054fd7b42fe59975d6547241d6 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 15 Apr 2025 11:11:19 +0100 Subject: [PATCH 015/139] Updated 5.3.3.1.1 regex issue #315 thanks to @jrdbarnes Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.3.3.1.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_5/cis_5.3.3.1.x.yml b/tasks/section_5/cis_5.3.3.1.x.yml index 1730521..0aadbe3 100644 --- a/tasks/section_5/cis_5.3.3.1.x.yml +++ b/tasks/section_5/cis_5.3.3.1.x.yml @@ -23,7 +23,7 @@ - rhel9cis_disruption_high ansible.builtin.replace: path: "/etc/pam.d/{{ item }}-auth" - regexp: ^(\s*auth\s+(requisite|required|sufficient)\s+pam_faillock\.so)(.*)\s+deny\s*=\s*\S+(.*$) + regexp: ^(\s*auth\s+(?:requisite|required|sufficient)\s+pam_faillock\.so)(.*)\s+deny\s*=\s*\S+(.*$) replace: \1 \2\3 loop: - password From b04570dfe4086b7063632c48b433d6198ac5baf5 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 15 Apr 2025 11:40:49 +0100 Subject: [PATCH 016/139] removed legacy option Signed-off-by: Mark Bolwell --- tasks/audit_only.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tasks/audit_only.yml b/tasks/audit_only.yml index 1377f9f..39c9f7d 100644 --- a/tasks/audit_only.yml +++ b/tasks/audit_only.yml @@ -9,14 +9,6 @@ delegate_to: localhost become: false -- name: Audit_only | Get audits from systems and put in group dir - when: fetch_audit_files - ansible.builtin.fetch: - dest: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}/" - flat: true - mode: 'go-wx' - src: "{{ pre_audit_outfile }}" - - name: Audit_only | Show Audit Summary when: audit_only ansible.builtin.debug: From 4aeac7e6625133b4bac1aaed68a32a11c2752ab0 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 15 Apr 2025 11:41:46 +0100 Subject: [PATCH 017/139] typos and tidy up Signed-off-by: Mark Bolwell --- defaults/main.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 32c4679..eaf33a1 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,7 +1,8 @@ --- + # defaults file for rhel9-cis # WARNING: -# These values may be overriden by other vars-setting options(e.g. like the below 'container_vars_file'), as explained here: +# These values may be overridden by other vars-setting options(e.g. like the below 'container_vars_file'), as explained here: # https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable # Run the OS validation check @@ -36,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. @@ -85,7 +87,7 @@ audit_capture_files_dir: /some/location to copy to on control node # How to retrieve audit binary # Options are copy or download - detailed settings at the bottom of this file -# you will need to access to either github or the file already dowmloaded +# you will need to access to either github or the file already downloaded get_audit_binary_method: download ## if get_audit_binary_method - copy the following needs to be updated for your environment From ce43c573ee5435653a32119926bd94e47359da21 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 15 Apr 2025 12:51:42 +0100 Subject: [PATCH 018/139] update tags and issue #311 thanks to @rilatu Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.1.x.yml | 46 ++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/tasks/section_5/cis_5.1.x.yml b/tasks/section_5/cis_5.1.x.yml index 296ebf9..99176fd 100644 --- a/tasks/section_5/cis_5.1.x.yml +++ b/tasks/section_5/cis_5.1.x.yml @@ -6,7 +6,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - permissions - rule_5.1.1 - NIST800-53R5_AC-3 @@ -23,7 +23,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - permissions - rule_5.1.2 - NIST800-53R5_AC-3 @@ -53,7 +53,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.3 - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 @@ -166,7 +166,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.7 - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 @@ -195,6 +195,8 @@ path: "{{ rhel9cis_sshd_config_file }}" regexp: "^DenyUsers" line: "DenyUsers {{ rhel9cis_sshd_denyusers }}" + insertbefore: "^Match" + firstmatch: true validate: sshd -t -f %s notify: Restart sshd @@ -213,7 +215,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.8 - NIST800-53R5_CM-1 - NIST800-53R5_CM-2 @@ -231,7 +233,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.9 - NIST800-53R5_CM-1 - NIST800-53R5_CM-2 @@ -261,7 +263,7 @@ - level2-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.10 - NIST800-53R5_CM-7 block: @@ -287,7 +289,7 @@ - level1-server - level1-workstation - patch - - sshs + - sshd - rule_5.1.11 - NIST800-53R5_CM-1 - NIST800-53R5_CM-2 @@ -317,7 +319,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.12 - NIST800-53R5_CM-1 - NIST800-53R5_CM-2 @@ -337,7 +339,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.13 - NIST800-53R5_CM-1 - NIST800-53R5_CM-2 @@ -348,6 +350,8 @@ path: "{{ rhel9cis_sshd_config_file }}" regexp: ^(?i)(#|)\s*IgnoreRhosts line: 'IgnoreRhosts yes' + insertbefore: "^Match" + firstmatch: true validate: sshd -t -f %s notify: Restart sshd @@ -357,13 +361,15 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.14 - NIST800-53R5_CM-6 ansible.builtin.lineinfile: path: "{{ rhel9cis_sshd_config_file }}" regexp: ^(?i)(#|)\s*LoginGraceTime line: "LoginGraceTime {{ rhel9cis_sshd_logingracetime }}" + insertbefore: "^Match" + firstmatch: true validate: sshd -t -f %s notify: Restart sshd @@ -373,7 +379,7 @@ - level1-server - level1-workstation - patch - - sshs + - sshd - rule_5.1.15 - NIST800-53R5_AU-3 - NIST800-53R5_AU-12 @@ -382,6 +388,8 @@ path: "{{ rhel9cis_sshd_config_file }}" regexp: ^(?i)(#|)\s*LogLevel line: 'LogLevel {{ rhel9cis_ssh_loglevel }}' + insertbefore: "^Match" + firstmatch: true validate: sshd -t -f %s notify: Restart sshd @@ -391,7 +399,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.16 - NIST800-53R5_AU-3 ansible.builtin.lineinfile: @@ -407,7 +415,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.17 - NIST800-53R5_CM-1 - NIST800-53R5_CM-2 @@ -427,7 +435,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.18 - NIST800-53R5_CM-1 - NIST800-53R5_CM-2 @@ -447,7 +455,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.19 - NIST800-53R5_CM-1 - NIST800-53R5_CM-2 @@ -467,7 +475,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.20 - NIST800-53R5_AC-6 block: @@ -491,7 +499,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.21 - NIST800-53R5_CM-1 - NIST800-53R5_CM-2 @@ -511,7 +519,7 @@ - level1-server - level1-workstation - patch - - ssh + - sshd - rule_5.1.22 - NIST800-53R5_CM-1 - NIST800-53R5_CM-2 From de63984cd8ef4bd83163ab99dd7453862f943471 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Tue, 22 Apr 2025 16:10:53 -0400 Subject: [PATCH 019/139] Typo fixes Signed-off-by: Frederick Witty --- README.md | 2 +- defaults/main.yml | 4 ++-- templates/ansible_vars_goss.yml.j2 | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d3bf75a..098c50a 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ This is managed using tags: - 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. +The control found in defaults main also need to reflect this as this control the testing that takes place if you are using the audit component. ## Coming from a previous release diff --git a/defaults/main.yml b/defaults/main.yml index eaf33a1..071e55b 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1046,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/templates/ansible_vars_goss.yml.j2 b/templates/ansible_vars_goss.yml.j2 index ad44fb3..7cb906b 100644 --- a/templates/ansible_vars_goss.yml.j2 +++ b/templates/ansible_vars_goss.yml.j2 @@ -34,7 +34,7 @@ rhel9cis_selinux_disable: {{ rhel9cis_selinux_disable }} # UEFI boot('/etc/grub2-efi.cfg') or in case of BIOS legacy-boot('/etc/grub2.cfg'). rhel9cis_legacy_boot: {{ rhel9cis_legacy_boot }} -## Benchmark name used by audting control role +## Benchmark name used by auditing control role # The audit variable found at the base ## metadata for Audit benchmark benchmark_version: 'v2.0.0' @@ -151,7 +151,7 @@ rhel9cis_rule_1_8_8: {{ rhel9cis_rule_1_8_8 }} rhel9cis_rule_1_8_9: {{ rhel9cis_rule_1_8_9 }} rhel9cis_rule_1_8_10: {{ rhel9cis_rule_1_8_10 }} -# Section 2 rules are controling Services (Special Purpose Services, and service clients) +# Section 2 rules are controlling Services (Special Purpose Services, and service clients) ## Configure Server Services rhel9cis_rule_2_1_1: {{ rhel9cis_rule_2_1_1 }} rhel9cis_rule_2_1_2: {{ rhel9cis_rule_2_1_2 }} @@ -625,21 +625,21 @@ rhel9cis_authselect_custom_profile_name: {{ rhel9cis_authselect_custom_profile_n # These are discovered via logins.def if set true rhel9cis_discover_int_uid: {{ rhel9cis_discover_int_uid }} # 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 ## Section6 vars ## Control 6.1.2 AIDE schedule -# how aide sceduler runs can be one of cron or timer +# how aide scheduler runs can be one of cron or timer rhel9cis_aide_scan: {{ rhel9cis_aide_scan }} # These are the crontab settings for periodical checking of the filesystem's integrity using AIDE. From 7173eba3f68faf6e7e8b72f6d417798491a3cc36 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Tue, 22 Apr 2025 16:29:43 -0400 Subject: [PATCH 020/139] Typo fixes v2 Signed-off-by: Frederick Witty --- defaults/main.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 071e55b..9358939 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 @@ -46,7 +46,7 @@ rhel9cis_selinux_disable: false # UEFI boot('/etc/grub2-efi.cfg') or in case of BIOS legacy-boot('/etc/grub2.cfg'). rhel9cis_legacy_boot: false -## Benchmark name used by audting control role +## Benchmark name used by auditing control role # The audit variable found at the base ## metadata for Audit benchmark benchmark_version: 'v2.0.0' @@ -112,12 +112,12 @@ 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 # Method of getting,uploading the summary files -## Ensure access and permissions are avaiable for these to occur. +## Ensure access and permissions are available for these to occur. ## options are # fetch - fetches from server and moves to location on the ansible controller (could be a mount point available to controller) # copy - copies file to a location available to the managed node @@ -514,7 +514,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 @@ -722,7 +722,7 @@ rhel9cis_bluetooth_mask: false rhel9cis_ipv6_required: true ## 3.1.2 wireless network requirements -# if wireless adapetr found allow network manager to be installed +# if wireless adapter found allow network manager to be installed rhel9cis_install_network_manager: false # 3.3 System network parameters (host only OR host and router) # This variable governs whether specific CIS rules @@ -730,15 +730,15 @@ rhel9cis_install_network_manager: false rhel9cis_is_router: false # This variable governs if the task which updates sysctl(including sysctl reload) is executed. -# NOTE: The current default value is likely to be overriden by other further tasks(via 'set_fact'). +# NOTE: The current default value is likely to be overridden by other further tasks(via 'set_fact'). rhel9cis_sysctl_update: false # This variable governs if the task which flushes the IPv4 routing table is executed(forcing subsequent connections to # use the new configuration). -# NOTE: The current default value is likely to be overriden by other further tasks(via 'set_fact'). +# NOTE: The current default value is likely to be overridden by other further tasks(via 'set_fact'). rhel9cis_flush_ipv4_route: false # This variable governs if the task which flushes the IPv6 routing table is executed(forcing subsequent connections to # use the new configuration). -# NOTE: The current default value is likely to be overriden by other further tasks(via 'set_fact'). +# NOTE: The current default value is likely to be overridden by other further tasks(via 'set_fact'). rhel9cis_flush_ipv6_route: false # Section 4 vars @@ -890,13 +890,13 @@ rhel9cis_authselect_pkg_update: false # NOTE the risks if system is using SSSD # To create a new profile (best for greenfield fresh sites not configured) # This allows creation of a custom profile using an existing one to build from -# will only create if profiel does not already exist +# will only create if profile does not already exist ## options true or false rhel9cis_authselect_custom_profile_create: true ## Controls: # - 5.3.2.1 - Ensure custom authselect profile is used # Settings in place now will fail, they are placeholders from the control example. Due to the way many multiple -# options and ways to configure this control needs to be enabled and settings adjusted to minimise risk. +# options and ways to configure this control needs to be enabled and settings adjusted to minimize risk. # This variable configures the name of the custom profile to be created and selected. # To be changed from default - cis_example_profile @@ -1046,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 `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 From 350b30dfe4d117395dcf25ae21cab713c0440c59 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Tue, 22 Apr 2025 16:32:47 -0400 Subject: [PATCH 021/139] prelim_ prefix added to max_int_uid and min_int_uid Signed-off-by: Frederick Witty --- defaults/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 9358939..385d160 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1048,14 +1048,14 @@ 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 `rhel9cis_discover_int_uid` has # been set to `true`. -min_int_uid: 1000 +prelim_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 `rhel9cis_discover_int_uid` has # been set to `true`. -max_int_uid: 65533 +prelim_max_int_uid: 65533 ## Section6 vars ## Control 6.1.x - allow aide to be configured From 42024903e3eb83901f44dc4bf8596e785ad77d46 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Wed, 23 Apr 2025 12:47:22 -0400 Subject: [PATCH 022/139] revamp set facts premlim_ max_int_uid and prelim_min_int_uid Signed-off-by: Frederick Witty --- defaults/main.yml | 4 ++-- tasks/prelim.yml | 21 ++++++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 385d160..9358939 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1048,14 +1048,14 @@ 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 `rhel9cis_discover_int_uid` has # been set to `true`. -prelim_min_int_uid: 1000 +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 `rhel9cis_discover_int_uid` has # been set to `true`. -prelim_max_int_uid: 65533 +max_int_uid: 65533 ## Section6 vars ## Control 6.1.x - allow aide to be configured diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 1ec355b..dbd1493 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -320,24 +320,27 @@ patterns: '*.conf,*.rules' register: prelim_auditd_conf_files -- name: "PRELIM | AUDIT | Discover Interactive UID MIN and MIN from logins.def" +- name: "PRELIM | AUDIT | Discover Interactive UID_MIN and UID_MAX from /etc/login.defs" when: rhel9cis_discover_int_uid tags: always block: - - name: "PRELIM | AUDIT | Capture UID_MIN information from logins.def" - ansible.builtin.shell: grep -w "^UID_MIN" /etc/login.defs | awk '{print $NF}' + - name: "PRELIM | AUDIT | Capture UID_MIN from /etc/login.defs" + ansible.builtin.command: awk '/^UID_MIN/ {print $2}' /etc/login.defs changed_when: false + failed_when: false register: prelim_uid_min_id - - name: "PRELIM | AUDIT | Capture UID_MAX information from logins.def" - ansible.builtin.shell: grep -w "^UID_MAX" /etc/login.defs | awk '{print $NF}' + - name: "PRELIM | AUDIT | Capture UID_MAX from /etc/login.defs" + ansible.builtin.command: awk '/^UID_MAX/ {print $2}' /etc/login.defs changed_when: false + failed_when: false register: prelim_uid_max_id - - name: "PRELIM | AUDIT | Set Fact for interactive uid/gid" - ansible.builtin.set_fact: - prelim_min_int_uid: "{{ prelim_uid_min_id.stdout }}" - prelim_max_int_uid: "{{ prelim_uid_max_id.stdout }}" +- name: "PRELIM | AUDIT | Set facts for interactive UID/GID ranges" + tags: always + ansible.builtin.set_fact: + prelim_min_int_uid: "{{ prelim_uid_min_id.stdout | default(min_int_uid) }}" + prelim_max_int_uid: "{{ prelim_uid_max_id.stdout | default(max_int_uid) }}" - name: "PRELIM | AUDIT | Gather the package facts after prelim" tags: From e27e413f943d00253c3c4d702cbc6bb6d0efaf9b Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Wed, 23 Apr 2025 16:04:16 -0400 Subject: [PATCH 023/139] Update URL in defaults/main Signed-off-by: Frederick Witty --- defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults/main.yml b/defaults/main.yml index 9358939..91261b7 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -102,7 +102,7 @@ audit_content: git # If using either archive, copy, get_url: ## Note will work with .tar files - zip will require extra configuration ### If using get_url this is expecting github url in tar.gz format e.g. -### https://github.com/ansible-lockdown/UBUNTU22-CIS-Audit/archive/refs/heads/benchmark-v1.0.0.tar.gz +### https://github.com/ansible-lockdown/RHEL9-CIS-Audit/archive/refs/heads/benchmark-v1.0.0.tar.gz audit_conf_source: "some path or url to copy from" # Destination for the audit content to be placed on managed node From dd909b48c8aff1f5fb63560eb611ccd8084e0b62 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Fri, 25 Apr 2025 11:47:17 -0400 Subject: [PATCH 024/139] Fix for #320 thank you @kodebach Signed-off-by: Frederick Witty --- Changelog.md | 4 ++++ .../policies/modules/NO-SSHWEAKCIPHERS.pmod.j2 | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 4bd1c86..34b9c2c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,9 @@ # Changes to rhel9CIS +## 2.0.0 - Based on CIS v2.0.0 + +- #320 - thanks to @kodebach + ## 1.1.6 - Based on CIS v1.0.0 - #190 - thanks to @ipruteanu-sie diff --git a/templates/etc/crypto-policies/policies/modules/NO-SSHWEAKCIPHERS.pmod.j2 b/templates/etc/crypto-policies/policies/modules/NO-SSHWEAKCIPHERS.pmod.j2 index d325a11..393cf88 100644 --- a/templates/etc/crypto-policies/policies/modules/NO-SSHWEAKCIPHERS.pmod.j2 +++ b/templates/etc/crypto-policies/policies/modules/NO-SSHWEAKCIPHERS.pmod.j2 @@ -1,4 +1,4 @@ # This is a subpolicy to disable weak ciphers # for the SSH protocol (libssh and OpenSSH) # Carried out as part of CIS Benchmark rules combined 1.6.6 and 5.1.4 -cipher@SSH ={% if rhel9cis_rule_1_6_6 %} -CHACHA20-POLY1305{% endif %}{% if rhel9cis_rule_5_1_5 %} -3DES-CBC -AES-128-CBC -AES-192-CBC -AES-256-CBC{% endif %} +cipher@SSH ={% if rhel9cis_rule_1_6_6 %} -CHACHA20-POLY1305{% endif %}{% if rhel9cis_rule_5_1_4 %} -3DES-CBC -AES-128-CBC -AES-192-CBC -AES-256-CBC{% endif %} From 48c05f038f24e660a94a1c8db9f53f23eabb5158 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Fri, 25 Apr 2025 14:36:58 -0400 Subject: [PATCH 025/139] Fix for #322 thank @mindrb Signed-off-by: Frederick Witty --- Changelog.md | 3 ++- defaults/main.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 34b9c2c..4accf38 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,7 +2,8 @@ ## 2.0.0 - Based on CIS v2.0.0 -- #320 - thanks to @kodebach +- #322 - thanks to @mindrb +- #320 - thanks to @anup-ad ## 1.1.6 - Based on CIS v1.0.0 diff --git a/defaults/main.yml b/defaults/main.yml index 91261b7..6a360fa 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -588,7 +588,7 @@ rhel9cis_crypto_policy_module: '' # - 1.7.2 - Ensure local login warning banner is configured properly # - 1.7.3 - Ensure remote login warning banner is configured properly # This variable stores the content for the Warning Banner(relevant for issue, issue.net, motd). -rhel9cis_warning_banner: Authorized uses only. All activity may be monitored and reported. +rhel9cis_warning_banner: Authorized users only. All activity may be monitored and reported. # End Banner ## Control 1.8.x - Settings for GDM From 5e2e4db20e955f90a024b17d92626a82bff461c8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 19 May 2025 17:24:24 +0000 Subject: [PATCH 026/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/gitleaks/gitleaks: v8.24.3 → v8.26.0](https://github.com/gitleaks/gitleaks/compare/v8.24.3...v8.26.0) - [github.com/ansible-community/ansible-lint: v25.2.1 → v25.4.0](https://github.com/ansible-community/ansible-lint/compare/v25.2.1...v25.4.0) - [github.com/adrienverge/yamllint.git: v1.37.0 → v1.37.1](https://github.com/adrienverge/yamllint.git/compare/v1.37.0...v1.37.1) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 99408de..ebc85d7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,12 +41,12 @@ repos: - id: detect-secrets - repo: https://github.com/gitleaks/gitleaks - rev: v8.24.3 + rev: v8.26.0 hooks: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.2.1 + rev: v25.4.0 hooks: - id: ansible-lint name: Ansible-lint @@ -65,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 4948d3cb095955447032292831c907733b355151 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 23 May 2025 14:22:30 +0100 Subject: [PATCH 027/139] added ignore comments in file Signed-off-by: Mark Bolwell --- tasks/parse_etc_password.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/parse_etc_password.yml b/tasks/parse_etc_password.yml index 86c1cac..70f79c6 100644 --- a/tasks/parse_etc_password.yml +++ b/tasks/parse_etc_password.yml @@ -4,7 +4,7 @@ tags: always block: - name: "PRELIM | 5.5.2 | 6.2.7 | 6.2.8 | 6.2.20 | Parse /etc/passwd" - ansible.builtin.command: cat /etc/passwd + ansible.builtin.command: cat /etc/passwd | grep -v '^#' changed_when: false check_mode: false register: prelim_passwd_file_audit From 8d5a32bc392ce53c9d94f0e6aeff7c07a572de29 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 23 May 2025 14:25:42 +0100 Subject: [PATCH 028/139] added rhel9cis_rsyslog_ansiblemanage conditional Signed-off-by: Mark Bolwell --- tasks/section_6/main.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tasks/section_6/main.yml b/tasks/section_6/main.yml index dda7ee5..dbff078 100644 --- a/tasks/section_6/main.yml +++ b/tasks/section_6/main.yml @@ -20,7 +20,9 @@ file: cis_6.2.2.x.yml - name: "SECTION | 6.2.3 | Configure rsyslog" - when: rhel9cis_syslog == 'rsyslog' + when: + - rhel9cis_syslog == 'rsyslog' + - rhel9cis_rsyslog_ansiblemanaged ansible.builtin.import_tasks: file: cis_6.2.3.x.yml From 2b37d0d7321dec9511f61a0064764ac779b8cb4e Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 23 May 2025 14:30:17 +0100 Subject: [PATCH 029/139] added check_mode logic Signed-off-by: Mark Bolwell --- tasks/section_6/cis_6.1.x.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tasks/section_6/cis_6.1.x.yml b/tasks/section_6/cis_6.1.x.yml index c000fe1..1db531b 100644 --- a/tasks/section_6/cis_6.1.x.yml +++ b/tasks/section_6/cis_6.1.x.yml @@ -58,6 +58,10 @@ dest: /var/lib/aide/aide.db.gz remote_src: true mode: 'ug-wx,o-rwx' + register: aide_db_cp + failed_when: + - not ansible_check_mode + - aide_db_cp.failed - name: "6.1.2 | PATCH | Ensure filesystem integrity is regularly checked" when: @@ -119,4 +123,7 @@ /usr/sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512 /usr/sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512 /usr/sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512 - validate: aide -D --config %s + register: aide_file_integrity_check + failed_when: + - not ansible_check_mode + - aide_file_integrity_check.failed From 15bf03c75490746568ef21a610236fc714f0630c Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 23 May 2025 14:34:30 +0100 Subject: [PATCH 030/139] added check mode logic Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index dbd1493..a0fc2fe 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -25,6 +25,7 @@ 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 $1 }' changed_when: false + check_mode: false register: prelim_interactive_usernames - name: "PRELIM | AUDIT | Interactive User accounts home directories" @@ -32,6 +33,7 @@ ansible.builtin.shell: > grep -E -v '^(root|halt|sync|shutdown)' /etc/passwd | awk -F: '(!index($7, "sbin/nologin") && $7 != "/bin/nologin" && $7 != "/bin/false") { print $6 }' changed_when: false + check_mode: false register: prelim_interactive_users_home - name: "PRELIM | AUDIT | Interactive UIDs" @@ -39,6 +41,7 @@ ansible.builtin.shell: > grep -E -v '^(root|halt|sync|shutdown)' /etc/passwd | awk -F: '(!index($7, "sbin/nologin") && $7 != "/bin/nologin" && $7 != "/bin/false") { print $3 }' changed_when: false + check_mode: false register: prelim_interactive_uids - name: "PRELIM | AUDIT | Capture /etc/password variables" @@ -64,6 +67,7 @@ ansible.builtin.shell: | mount | awk '{print $1, $3, $5, $6}' changed_when: false + check_mode: false register: prelim_mount_output - name: PRELIM | AUDIT | Section 1.1 | Retrieve mount options - build fact # This is inherited and used in mountpoints tasks @@ -100,6 +104,7 @@ ansible.builtin.command: rpm -q gpg-pubkey --qf '%{NAME}-%{VERSION}-%{RELEASE}\t%{SUMMARY}\n' # noqa command-instead-of-module changed_when: false failed_when: false + check_mode: false register: prelim_check_gpg_imported - name: "PRELIM | AUDIT | Import gpg keys | Check Package" # noqa command-instead-of-module @@ -328,12 +333,14 @@ ansible.builtin.command: awk '/^UID_MIN/ {print $2}' /etc/login.defs changed_when: false failed_when: false + check_mode: false register: prelim_uid_min_id - name: "PRELIM | AUDIT | Capture UID_MAX from /etc/login.defs" ansible.builtin.command: awk '/^UID_MAX/ {print $2}' /etc/login.defs changed_when: false failed_when: false + check_mode: false register: prelim_uid_max_id - name: "PRELIM | AUDIT | Set facts for interactive UID/GID ranges" From daf5a3f4621adf7e357f2422aedecef7ccfc14f9 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 23 May 2025 15:01:16 +0100 Subject: [PATCH 031/139] changed command to shell for grep Signed-off-by: Mark Bolwell --- tasks/parse_etc_password.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/parse_etc_password.yml b/tasks/parse_etc_password.yml index 70f79c6..9190421 100644 --- a/tasks/parse_etc_password.yml +++ b/tasks/parse_etc_password.yml @@ -4,7 +4,7 @@ tags: always block: - name: "PRELIM | 5.5.2 | 6.2.7 | 6.2.8 | 6.2.20 | Parse /etc/passwd" - ansible.builtin.command: cat /etc/passwd | grep -v '^#' + ansible.builtin.shell: cat /etc/passwd | grep -v '^#' changed_when: false check_mode: false register: prelim_passwd_file_audit From 0e61e796c6633c127fa7bdf10e6c2535ec7dd98e Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Fri, 23 May 2025 11:00:13 -0400 Subject: [PATCH 032/139] Fix for #325 thank you @mindrb Signed-off-by: Frederick Witty --- Changelog.md | 2 +- tasks/section_6/cis_6.2.2.1.x.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 4accf38..edcb223 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,7 +2,7 @@ ## 2.0.0 - Based on CIS v2.0.0 -- #322 - thanks to @mindrb +- #322, #325 - thanks to @mindrb - #320 - thanks to @anup-ad ## 1.1.6 - Based on CIS v1.0.0 diff --git a/tasks/section_6/cis_6.2.2.1.x.yml b/tasks/section_6/cis_6.2.2.1.x.yml index 945c2e4..aa2415d 100644 --- a/tasks/section_6/cis_6.2.2.1.x.yml +++ b/tasks/section_6/cis_6.2.2.1.x.yml @@ -35,7 +35,7 @@ regexp: "{{ item.regexp }}" line: "{{ item.line }}" loop: - - { regexp: 'URL=', line: 'URL={{ rhel9cis_remote_log_server }}'} + - { regexp: 'URL=', line: 'URL={{ rhel9cis_journal_upload_url }}'} - { regexp: 'ServerKeyFile=', line: 'ServerKeyFile={{ rhel9cis_journal_upload_serverkeyfile }}'} - { regexp: 'ServerCertificateFile=', line: 'ServerCertificateFile={{ rhel9cis_journal_servercertificatefile }}'} - { regexp: 'TrustedCertificateFile=', line: 'TrustedCertificateFile={{ rhel9cis_journal_trustedcertificatefile }}'} From f83e5a69a2399c47e139b356c4c8714a9005257b Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 23 May 2025 16:05:01 +0100 Subject: [PATCH 033/139] interactive users ilogic improvements thanks to @polski-g Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 16 +++++++--------- tasks/section_5/cis_5.4.1.x.yml | 8 ++++---- tasks/section_5/cis_5.4.2.x.yml | 4 ++-- tasks/section_7/cis_7.2.x.yml | 8 ++++---- vars/main.yml | 3 +++ 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index a0fc2fe..c1edb39 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -23,18 +23,16 @@ - name: "PRELIM | AUDIT | Interactive Users" 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 $1 }' + 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 $1":"$3":"$6 }' changed_when: false check_mode: false - register: prelim_interactive_usernames + register: prelim_interactive_users_raw -- name: "PRELIM | AUDIT | Interactive User accounts home directories" +- name: "PRELIM | AUDIT | Interactive Users (reformat)" 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") { print $6 }' - changed_when: false - check_mode: false - register: prelim_interactive_users_home + ansible.builtin.set_fact: + prelim_interactive_usernames: "{{ 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" tags: always @@ -205,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 6a492e5..1962101 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.stdout + - item in prelim_interactive_usernames | 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.stdout + - item in prelim_interactive_usernames | 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.stdout + - item in prelim_interactive_usernames | 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.stdout + when: item in prelim_interactive_usernames | 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 12390b3..a8eb4d0 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.stdout" + - "item.id not in prelim_interactive_usernames | 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.stdout" + - "item.id not in prelim_interactive_usernames | map(attribute='username')" - "'root' not in item.id" tags: - level1-server diff --git a/tasks/section_7/cis_7.2.x.yml b/tasks/section_7/cis_7.2.x.yml index cc1825c..8706877 100644 --- a/tasks/section_7/cis_7.2.x.yml +++ b/tasks/section_7/cis_7.2.x.yml @@ -256,7 +256,7 @@ etype: group permissions: rx state: present - loop: "{{ prelim_interactive_users_home.stdout_lines }}" + loop: "{{ prelim_interactive_users | map(attribute='home') | list }}" - name: "7.2.8 | PATCH | Ensure local interactive user home directories are configured | Set other ACL" when: not system_is_container @@ -266,7 +266,7 @@ etype: other permissions: 0 state: present - loop: "{{ prelim_interactive_users_home.stdout_lines }}" + loop: "{{ prelim_interactive_users | map(attribute='home') | list }}" - name: "7.2.9 | PATCH | Ensure local interactive user dot files access is configured" when: @@ -315,6 +315,6 @@ ansible.builtin.file: path: '{{ item }}' mode: 'go-w' - owner: "{{ rhel9cis_passwd | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='uid') | last }}" - group: "{{ rhel9cis_passwd | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='gid') | last }}" + 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 }}" with_items: "{{ discovered_homedir_hidden_files.stdout_lines }}" diff --git a/vars/main.yml b/vars/main.yml index cdca90d..5eed07c 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -22,6 +22,9 @@ rhel9cis_allowed_crypto_policies_modules: warn_control_list: "" warn_count: 0 +# list of dicts of interactive users, filled in during prelim.yml +prelim_interactive_users: [] + # Default empty values for 1.4.2 efi_mount_opts_addition: '' From f564135e72384a79f2f99f0ac9d0bf7d90bddfdc Mon Sep 17 00:00:00 2001 From: polski_g Date: Thu, 8 May 2025 11:17:29 -0400 Subject: [PATCH 034/139] Check for existence of sshd_config.d/50-redhat.conf before trying to modify it Signed-off-by: polski-g --- tasks/prelim.yml | 8 ++++++++ tasks/section_5/cis_5.1.x.yml | 2 ++ 2 files changed, 10 insertions(+) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index c1edb39..b8f39d6 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -246,6 +246,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 From 4e49532e2030320148fcb272dca5a2950b4e2575 Mon Sep 17 00:00:00 2001 From: polski_g Date: Thu, 8 May 2025 10:52:21 -0400 Subject: [PATCH 035/139] Variablize network-manager package name Signed-off-by: polski-g --- defaults/main.yml | 1 + tasks/section_3/cis_3.1.x.yml | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 6a360fa..c55f93a 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -724,6 +724,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. 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 fb9577f7d9c5f4f41efce4454ab626f1a579f367 Mon Sep 17 00:00:00 2001 From: polski_g Date: Thu, 8 May 2025 10:53:27 -0400 Subject: [PATCH 036/139] Fix typo in variable name discovered_group_check Signed-off-by: polski-g --- tasks/section_7/cis_7.2.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 68579ae85e7ff7613bd9ae89f66fd96cd57374f8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 May 2025 17:23:15 +0000 Subject: [PATCH 037/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/ansible-community/ansible-lint: v25.4.0 → v25.5.0](https://github.com/ansible-community/ansible-lint/compare/v25.4.0...v25.5.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ebc85d7..ddcc701 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,7 +46,7 @@ repos: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.4.0 + rev: v25.5.0 hooks: - id: ansible-lint name: Ansible-lint From d136bfa381f6b2766782fbca28b60b1c1def55e6 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 10:22:30 +0100 Subject: [PATCH 038/139] Updated variable naming for interactive_users Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 2 +- tasks/section_5/cis_5.4.1.x.yml | 8 ++++---- tasks/section_5/cis_5.4.2.x.yml | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index c1edb39..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" 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 5dc2541731f3e544939f44d112a94bc6af015974 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 14:57:29 +0100 Subject: [PATCH 039/139] Updated passwd variable name Signed-off-by: Mark Bolwell --- tasks/parse_etc_password.yml | 6 +++--- tasks/section_5/cis_5.4.2.x.yml | 4 ++-- tasks/section_7/cis_7.2.x.yml | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tasks/parse_etc_password.yml b/tasks/parse_etc_password.yml index 9190421..9f137cb 100644 --- a/tasks/parse_etc_password.yml +++ b/tasks/parse_etc_password.yml @@ -7,11 +7,11 @@ 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 }}" + 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_passwd_file_audit.stdout_lines }}" vars: ld_passwd_regex: >- 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..c63ee2f 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_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='uid') | last }}" + group: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='gid') | last }}" with_items: "{{ discovered_homedir_hidden_files.stdout_lines }}" From c4070c341b99a7ca2a76de22bc41e545d0fbf88f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 15:35:34 +0100 Subject: [PATCH 040/139] Updated logic on 7.2.9 tasks Signed-off-by: Mark Bolwell --- tasks/section_7/cis_7.2.x.yml | 64 ++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/tasks/section_7/cis_7.2.x.yml b/tasks/section_7/cis_7.2.x.yml index c63ee2f..90da743 100644 --- a/tasks/section_7/cis_7.2.x.yml +++ b/tasks/section_7/cis_7.2.x.yml @@ -286,8 +286,8 @@ vars: warn_control_id: '7.2.9' block: - - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Check for files" - ansible.builtin.shell: find /home/ -name "\.*" + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured" + ansible.builtin.shell: find {{ prelim_interactive_users_home.stdout_lines | list | join(' ') }} -name "\.*" -type f changed_when: false failed_when: discovered_homedir_hidden_files.rc not in [ 0, 1 ] check_mode: false @@ -296,25 +296,63 @@ - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Warning on files found" when: - discovered_homedir_hidden_files.stdout | length > 0 - - rhel9cis_dotperm_ansiblemanaged + - not rhel9cis_dotperm_ansiblemanaged ansible.builtin.debug: msg: - - "Warning!! We have discovered group or world-writable dot files on your system and this host is configured for manual intervention. Please investigate these files further." + - "Warning!! Please investigate that hidden files found in users home directories match control requirements." - - name: "7.2.9 | PATCH | Ensure local interactive user dot files access is configured | Set warning count" + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Set warning count" when: - discovered_homedir_hidden_files.stdout | length > 0 - - rhel9cis_dotperm_ansiblemanaged + - not rhel9cis_dotperm_ansiblemanaged ansible.builtin.import_tasks: file: warning_facts.yml - - name: "7.2.9 | PATCH | Ensure local interactive user dot files access is configured | Changes files if configured" + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured" when: - discovered_homedir_hidden_files.stdout | length > 0 - rhel9cis_dotperm_ansiblemanaged - ansible.builtin.file: - path: '{{ item }}' - mode: 'go-w' - owner: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='uid') | last }}" - group: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='gid') | last }}" - with_items: "{{ discovered_homedir_hidden_files.stdout_lines }}" + block: + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Changes files if configured .bash_history & .netrc" + when: + - discovered_homedir_hidden_files.stdout | length > 0 + - item | basename in ['.bash_history','.netrc'] + ansible.builtin.file: + path: "{{ item }}" + mode: 'u-x,go-rwx' + failed_when: discovered_dot_bash_history_to_change.state not in '[ file, absent ]' + register: discovered_dot_bash_history_to_change + loop: "{{ discovered_homedir_hidden_files.stdout_lines }}" + + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Changes files if configured file mode" + ansible.builtin.file: + path: '{{ item }}' + mode: 'u-x,go-wx' + failed_when: discovered_dot_bash_history_to_change.state not in '[ file, absent ]' + register: discovered_dot_bash_history_to_change + loop: "{{ discovered_homedir_hidden_files.stdout_lines }}" + + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Changes files ownerships" + ansible.builtin.file: + path: "{{ item }}" + owner: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='uid') | last }}" + group: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='gid') | last }}" + failed_when: discovered_dot_bash_history_to_change.state not in '[ file, absent ]' + register: discovered_dot_bash_history_to_change + loop: "{{ discovered_homedir_hidden_files.stdout_lines }}" + + - name: "7.2.9 | PATCH | Ensure local interactive user dot files access is configured | Changes files if configured" + ansible.builtin.file: + path: '{{ item }}' + mode: 'go-w' + owner: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='uid') | last }}" + group: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='gid') | last }}" + with_items: "{{ discovered_homedir_hidden_files.stdout_lines }}" + + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | rename .forward or .rhosts files" + when: + - item | basename in ['.forward','.rhosts'] + - item is not search ("CIS") + ansible.builtin.command: "mv {{ item }} {{ item }}_CIS_TOBEREVIEWED" + changed_when: true + loop: "{{ discovered_homedir_hidden_files.stdout_lines }}" From 210535bf4f14b00b5f9de8c7dab8c291e646f7bf Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 15:36:04 +0100 Subject: [PATCH 041/139] updated loop var name Signed-off-by: Mark Bolwell --- tasks/parse_etc_password.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/parse_etc_password.yml b/tasks/parse_etc_password.yml index 9f137cb..c7ed865 100644 --- a/tasks/parse_etc_password.yml +++ b/tasks/parse_etc_password.yml @@ -12,7 +12,7 @@ - name: "PRELIM | 5.4.2 | 7.2.8 | Split passwd entries" ansible.builtin.set_fact: 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_passwd_file_audit.stdout_lines }}" + loop: "{{ prelim_capture_passwd_file.stdout_lines }}" vars: ld_passwd_regex: >- ^(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*) From f740d89b54c77aca6056571fad56124f6907f018 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 15:36:39 +0100 Subject: [PATCH 042/139] Added user home 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 cb475d336892def111d1817363afa48aa1ff6ed4 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 28 May 2025 16:10:28 +0100 Subject: [PATCH 043/139] fixed typo on post audit file name Signed-off-by: Mark Bolwell --- tasks/post_remediation_audit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index 54d5785..68e7035 100644 --- a/tasks/post_remediation_audit.yml +++ b/tasks/post_remediation_audit.yml @@ -33,7 +33,7 @@ when: audit_format == "documentation" block: - name: Post Audit | Capture audit data if documentation format - ansible.builtin.shell: tail -2 "{{ pre_audit_outfile }}" | tac | tr '\n' ' ' + ansible.builtin.shell: tail -2 "{{ post_audit_outfile }}" | tac | tr '\n' ' ' changed_when: false register: post_audit_summary From 30d7e3a7616e9d938c8c208cfe6003c053f84255 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Jun 2025 17:25:10 +0000 Subject: [PATCH 044/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/gitleaks/gitleaks: v8.26.0 → v8.27.0](https://github.com/gitleaks/gitleaks/compare/v8.26.0...v8.27.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ddcc701..79d19fb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: - id: detect-secrets - repo: https://github.com/gitleaks/gitleaks - rev: v8.26.0 + rev: v8.27.0 hooks: - id: gitleaks From 1bff329a058de7a7148108f3423cf5a636287edf Mon Sep 17 00:00:00 2001 From: polski-g Date: Tue, 3 Jun 2025 11:35:05 -0400 Subject: [PATCH 045/139] auditd: ensure check mode runs non-destructive call to ausyscall --dump Signed-off-by: polski-g --- 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 5226f14b3e61eb23e740aac886520ddd309e7242 Mon Sep 17 00:00:00 2001 From: polski-g Date: Fri, 6 Jun 2025 10:03:47 -0400 Subject: [PATCH 046/139] fetch of auditd logfile should run in check_mode Signed-off-by: polski-g --- tasks/prelim.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index ced76ce..0081cc6 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -317,6 +317,7 @@ tags: always ansible.builtin.shell: grep ^log_file /etc/audit/auditd.conf | awk '{ print $NF }' changed_when: false + check_mode: false register: prelim_auditd_logfile - name: "PRELIM | AUDIT | Audit conf and rules files | list files" From 2ce05a345ddb7ddc3c4c00d121ef3b05c91dbb4c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 17:24:11 +0000 Subject: [PATCH 047/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/gitleaks/gitleaks: v8.27.0 → v8.27.2](https://github.com/gitleaks/gitleaks/compare/v8.27.0...v8.27.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 79d19fb..cbcb7a4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: - id: detect-secrets - repo: https://github.com/gitleaks/gitleaks - rev: v8.27.0 + rev: v8.27.2 hooks: - id: gitleaks From 30bb04b1d487b19b8663bda48283a9c457340b8b Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 12 Jun 2025 12:10:44 +0100 Subject: [PATCH 048/139] updates root password check 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 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 From 9f50effd30052ff24c0a02c8e47c6b7e437238cd Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 10:01:10 +0100 Subject: [PATCH 049/139] updated logic Signed-off-by: Mark Bolwell --- tasks/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/main.yml b/tasks/main.yml index fe50b10..43ec09c 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -134,6 +134,7 @@ - name: "Ensure root password is set" 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 51b20d383d98965bf44290388edbc9322bcb7a28 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 10:07:27 +0100 Subject: [PATCH 050/139] Renamed variable to prelim 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 ced76ce..0a3c42a 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -260,7 +260,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 b2308ac31097f1e44bffb0e0c2a9b7978c47f891 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 10:07:55 +0100 Subject: [PATCH 051/139] fixed typos in logic 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 18fc4ea585f7f3812e391ebc0ca75cf2528f741e Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 10:08:56 +0100 Subject: [PATCH 052/139] updated conditional var name and regex best practices Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.1.x.yml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tasks/section_5/cis_5.1.x.yml b/tasks/section_5/cis_5.1.x.yml index eaee7de..3fd366c 100644 --- a/tasks/section_5/cis_5.1.x.yml +++ b/tasks/section_5/cis_5.1.x.yml @@ -276,10 +276,10 @@ 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 + regexp: (?i)^(#|)\s*X11Forwarding line: 'X11Forwarding {{ rhel9cis_sshd_x11forwarding }}' validate: sshd -t -f %s notify: Restart sshd @@ -299,10 +299,10 @@ - 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 + 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 7bef2eda62c06b670893f13111f45a5d87a04650 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 10:12:27 +0100 Subject: [PATCH 053/139] added check_mode false 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 ca14eeb1476ef4594de5ecc1ac658300663ee971 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 10:18:26 +0100 Subject: [PATCH 054/139] updated Signed-off-by: Mark Bolwell --- Changelog.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Changelog.md b/Changelog.md index edcb223..83157e9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,12 @@ # 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 - #322, #325 - thanks to @mindrb From 35d0bf9c4be05139e540edad74873690e57d576f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 13:19:14 +0100 Subject: [PATCH 055/139] updated auditing conditionals 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 0a3c42a..1eed552 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 3173b74481ebcab6448bc37ed0c863313a8d77a8 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 17:21:45 +0100 Subject: [PATCH 056/139] updated grep command 1.3.1.6 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 3ea5b92259d5998129b0274043571c66ab44dac3 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 16 Jun 2025 17:22:31 +0100 Subject: [PATCH 057/139] updated Signed-off-by: Mark Bolwell --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 83157e9..ede8f72 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,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 908ac57db767d6952c057db34d55faaa87a998e6 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 19 Jun 2025 16:26:01 +0100 Subject: [PATCH 058/139] enabled fetch report and updated title Signed-off-by: Mark Bolwell --- tasks/audit_only.yml | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/tasks/audit_only.yml b/tasks/audit_only.yml index 39c9f7d..a33cb94 100644 --- a/tasks/audit_only.yml +++ b/tasks/audit_only.yml @@ -1,19 +1,17 @@ --- -- 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 | 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 515d5c3bf77a87385aea862e496e8502a5a50141 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 19 Jun 2025 16:26:48 +0100 Subject: [PATCH 059/139] added changed_when to resolve false warning message 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 72dfe581e970267fe500ee84365439a0f16c6fe6 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 19 Jun 2025 16:27:53 +0100 Subject: [PATCH 060/139] updated Signed-off-by: Mark Bolwell --- Changelog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Changelog.md b/Changelog.md index edcb223..57ac1bc 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +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 +fix root user check + ## 2.0.0 - Based on CIS v2.0.0 - #322, #325 - thanks to @mindrb From bd1547313a69a7750ad1a312796b35e081346646 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 20 Jun 2025 11:28:19 +0100 Subject: [PATCH 061/139] Fix logic and notes for in crypto policy building Signed-off-by: Mark Bolwell --- Changelog.md | 1 + defaults/main.yml | 4 ++-- handlers/main.yml | 2 +- tasks/main.yml | 2 +- vars/main.yml | 6 ++++++ 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index 3cb8dad..331a17e 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 fix root user check +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 c55f93a..23312e5 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -580,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 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..25bb7bc 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" 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 37f4d0c9f09c34410c9b8893de37f5046d9db347 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 20 Jun 2025 12:15:13 +0100 Subject: [PATCH 062/139] 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 fc2f5895ced1fbee59d117f05d86b925b8b7912a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 17:27:59 +0000 Subject: [PATCH 063/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/ansible-community/ansible-lint: v25.5.0 → v25.6.1](https://github.com/ansible-community/ansible-lint/compare/v25.5.0...v25.6.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cbcb7a4..a4d0a42 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,7 +46,7 @@ repos: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.5.0 + rev: v25.6.1 hooks: - id: ansible-lint name: Ansible-lint From 5ed6abd5d330939df5dd17efa46784fccf33bea1 Mon Sep 17 00:00:00 2001 From: "Tomuta, Diana Maria (T CST SCC-RO)" Date: Thu, 26 Jun 2025 13:29:42 +0300 Subject: [PATCH 064/139] Fixing issue https://code.siemens.com/infosec-pss-gov/security-crafter-baseline-automations/ansible-lockdown/rhel9-cis/-/issues/42 . Signed-off-by: Diana-Maria Dumitru --- 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..6c852e3 100644 --- a/templates/audit/99_auditd.rules.j2 +++ b/templates/audit/99_auditd.rules.j2 @@ -58,6 +58,8 @@ -w /etc/hosts -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/hostname -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 ed699a50ba5991beb4d5e93b0ec8e51f32d81677 Mon Sep 17 00:00:00 2001 From: Diana-Maria Dumitru Date: Thu, 26 Jun 2025 13:35:51 +0300 Subject: [PATCH 065/139] Fixing issue https://code.siemens.com/infosec-pss-gov/security-crafter-baseline-automations/ansible-lockdown/rhel9-cis/-/issues/43 . Signed-off-by: Diana-Maria Dumitru --- tasks/auditd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/auditd.yml b/tasks/auditd.yml index 0fa0b32..9ada459 100644 --- a/tasks/auditd.yml +++ b/tasks/auditd.yml @@ -25,7 +25,7 @@ dest: /etc/audit/rules.d/99_auditd.rules owner: root group: root - mode: 'u-x,go-wx' + mode: 'u-x,g-wx,o-rwx' diff: "{{ discovered_auditd_rules_file.stat.exists }}" # Only run diff if not a new file register: discovered_auditd_rules_template_updated notify: From 23338ccd314d433049606b36114d6d32c004d5e3 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Fri, 27 Jun 2025 11:12:07 -0400 Subject: [PATCH 066/139] Addresses #318 - Thank you @kodebach & @bgro Signed-off-by: Frederick Witty --- Changelog.md | 12 +++++++----- tasks/main.yml | 5 ++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Changelog.md b/Changelog.md index 331a17e..53cf91d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,11 +1,13 @@ # Changes to rhel9CIS -## Based on CIS v2.0.0 +## 2.0.1 - Based on CIS v2.0.0 -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 +- 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 task/main.yml ## 2.0.1 - Based on CIS v2.0.0 diff --git a/tasks/main.yml b/tasks/main.yml index 25bb7bc..460acc8 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -101,10 +101,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 {{ 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 ac276f34fc8e5773e232fc51b90446df796b9fb5 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Fri, 27 Jun 2025 11:15:19 -0400 Subject: [PATCH 067/139] ChangeLog versioning fix Signed-off-by: Frederick Witty --- Changelog.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 53cf91d..b6db646 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,13 +1,13 @@ # Changes to rhel9CIS -## 2.0.1 - Based on CIS v2.0.0 +## 2.0.2 - Based on CIS v2.0.0 - 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 task/main.yml + - 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 From 7ec2c9bf5efa92a2b90697d7d9f4d239dc08f4e7 Mon Sep 17 00:00:00 2001 From: davidalexander83 Date: Wed, 2 Jul 2025 12:32:20 +1000 Subject: [PATCH 068/139] Fix re.error due to (?i) not at start of re 6.2.2.3 and 6.2.2.4 cause issues due to current re syntax: ^(?i)(\s*compress=) re.error: global flags not at the start of the expression at position 1 Fix removes ^ which resolves issue without affecting functionality. Signed-off-by: davidalexander83 --- tasks/section_6/cis_6.2.2.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/section_6/cis_6.2.2.x.yml b/tasks/section_6/cis_6.2.2.x.yml index a57efe2..fe0f8c4 100644 --- a/tasks/section_6/cis_6.2.2.x.yml +++ b/tasks/section_6/cis_6.2.2.x.yml @@ -50,7 +50,7 @@ - name: "6.2.2.3 | PATCH | Ensure journald Compress is configured | comment out current entries" ansible.builtin.replace: path: /etc/systemd/journald.conf - regexp: ^(?i)(\s*compress=) + regexp: (?i)(\s*compress=) replace: '#\1' - name: "6.2.2.4 | PATCH | Ensure journald Storage is configured" @@ -76,5 +76,5 @@ - name: "6.2.2.4 | PATCH | Ensure journald Storage is configured | comment out current entries" ansible.builtin.replace: path: /etc/systemd/journald.conf - regexp: ^(?i)(\s*storage=) + regexp: (?i)(\s*storage=) replace: '#\1' From 55744fe599d9764a0d261b9075aa997ddfcdea26 Mon Sep 17 00:00:00 2001 From: "Tomuta, Diana Maria (T CST SCC-RO)" Date: Wed, 2 Jul 2025 13:48:17 +0300 Subject: [PATCH 069/139] Fixing documentation of the vars. Signed-off-by: Diana-Maria Dumitru --- defaults/main.yml | 673 ++++++++++++++++++++++++++++------------------ 1 file changed, 410 insertions(+), 263 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 23312e5..71fe932 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -134,6 +134,7 @@ audit_output_destination: /opt/audit_summaries/ # PLEASE NOTE: These work in coordination with the section # group variables and tags. # You must enable an entire section in order for the variables below to take effect. +## Section 1 Fixes # Section 1 is Initial setup (FileSystem Configuration, Configure Software Updates, Filesystem Integrity Checking, Secure Boot Settings, # Additional Process Hardening, Mandatory Access Control, Command Line Warning Banners, and GNOME Display Manager) # Filesystem kernel modules @@ -180,7 +181,6 @@ rhel9cis_rule_1_1_2_7_1: true rhel9cis_rule_1_1_2_7_2: true rhel9cis_rule_1_1_2_7_3: true rhel9cis_rule_1_1_2_7_4: true - # Package Mgmt # Config Pkg Repos rhel9cis_rule_1_2_1_1: true @@ -189,7 +189,6 @@ rhel9cis_rule_1_2_1_3: true rhel9cis_rule_1_2_1_4: true # Package updates rhel9cis_rule_1_2_2_1: true - # Selinux rhel9cis_rule_1_3_1_1: true rhel9cis_rule_1_3_1_2: true @@ -199,17 +198,14 @@ rhel9cis_rule_1_3_1_5: true rhel9cis_rule_1_3_1_6: true rhel9cis_rule_1_3_1_7: true rhel9cis_rule_1_3_1_8: true - # Bootloader rhel9cis_rule_1_4_1: true rhel9cis_rule_1_4_2: true - # Additional Process Hardening rhel9cis_rule_1_5_1: true rhel9cis_rule_1_5_2: true rhel9cis_rule_1_5_3: true rhel9cis_rule_1_5_4: true - # Config system wide Crypto rhel9cis_rule_1_6_1: true rhel9cis_rule_1_6_2: true @@ -218,7 +214,6 @@ rhel9cis_rule_1_6_4: true rhel9cis_rule_1_6_5: true rhel9cis_rule_1_6_6: true rhel9cis_rule_1_6_7: true - # Command line warning banners rhel9cis_rule_1_7_1: true rhel9cis_rule_1_7_2: true @@ -226,7 +221,6 @@ rhel9cis_rule_1_7_3: true rhel9cis_rule_1_7_4: true rhel9cis_rule_1_7_5: true rhel9cis_rule_1_7_6: true - # Gnome Display Manager rhel9cis_rule_1_8_1: true rhel9cis_rule_1_8_2: true @@ -239,8 +233,9 @@ rhel9cis_rule_1_8_8: true rhel9cis_rule_1_8_9: true rhel9cis_rule_1_8_10: true -# Section 2 rules are controling Services (Special Purpose Services, and service clients) -## Configure Server Services +## Section 2 Fixes +# Section 2 rules are controlling Services (Special Purpose Services, and service clients) +# Configure Server Services rhel9cis_rule_2_1_1: true rhel9cis_rule_2_1_2: true rhel9cis_rule_2_1_3: true @@ -263,21 +258,18 @@ rhel9cis_rule_2_1_19: true rhel9cis_rule_2_1_20: true rhel9cis_rule_2_1_21: true rhel9cis_rule_2_1_22: true - -## Configure Client Services +# Configure Client Services rhel9cis_rule_2_2_1: true rhel9cis_rule_2_2_2: true rhel9cis_rule_2_2_3: true rhel9cis_rule_2_2_4: true rhel9cis_rule_2_2_5: true - -## Configure Time Synchronization +# Configure Time Synchronization rhel9cis_rule_2_3_1: true rhel9cis_rule_2_3_2: true rhel9cis_rule_2_3_3: true - -## Job Schedulers -### cron +# Job Schedulers +# cron rhel9cis_rule_2_4_1_1: true rhel9cis_rule_2_4_1_2: true rhel9cis_rule_2_4_1_3: true @@ -286,15 +278,16 @@ rhel9cis_rule_2_4_1_5: true rhel9cis_rule_2_4_1_6: true rhel9cis_rule_2_4_1_7: true rhel9cis_rule_2_4_1_8: true -### at +# at rhel9cis_rule_2_4_2_1: true -# Section 3 Network -## Network Devices +## Section 3 Fixes +# Section 3 rules are used for securely configuring the network configuration(kernel params, ACL, Firewall settings) +# Network Devices rhel9cis_rule_3_1_1: true rhel9cis_rule_3_1_2: true rhel9cis_rule_3_1_3: true -## Network Kernel Modules +# Network Kernel Modules rhel9cis_rule_3_2_1: true rhel9cis_rule_3_2_2: true rhel9cis_rule_3_2_3: true @@ -312,8 +305,10 @@ rhel9cis_rule_3_3_9: true rhel9cis_rule_3_3_10: true rhel9cis_rule_3_3_11: true -# Section 4 Firewalls -## Firewall utility +## Section 4 Fixes +# Section 4 rules are Logging and Auditing (Configure System Accounting (auditd), +# Configure Data Retention, and Configure Logging) +# Firewall utility rhel9cis_rule_4_1_1: true rhel9cis_rule_4_1_2: true ## Configure firewalld @@ -325,8 +320,10 @@ rhel9cis_rule_4_3_2: true rhel9cis_rule_4_3_3: true rhel9cis_rule_4_3_4: true -## Section 5 -## 5.1. Configure SSH Server +## Section 5 Fixes +# Section 5 rules control Access, Authentication, and Authorization (Configure time-based job schedulers, +# Configure sudo, Configure SSH Server, Configure PAM and User Accounts and Environment) +# Configure SSH Server rhel9cis_rule_5_1_1: true rhel9cis_rule_5_1_2: true rhel9cis_rule_5_1_3: true @@ -349,7 +346,7 @@ rhel9cis_rule_5_1_19: true rhel9cis_rule_5_1_20: true rhel9cis_rule_5_1_21: true rhel9cis_rule_5_1_22: true -## 5.2 Configure Privilege Escalation +# 5.2 Configure Privilege Escalation rhel9cis_rule_5_2_1: true rhel9cis_rule_5_2_2: true rhel9cis_rule_5_2_3: true @@ -381,7 +378,7 @@ rhel9cis_rule_5_3_3_2_6: true rhel9cis_rule_5_3_3_2_7: true rhel9cis_rule_5_3_3_2_8: true # 5.3.3.3 Configure pam_pwhistory module -# This are added as part of 5.3.2.4 using jinja2 template +# These are added as part of 5.3.2.4 using jinja2 template rhel9cis_rule_5_3_3_3_1: true rhel9cis_rule_5_3_3_3_2: true rhel9cis_rule_5_3_3_3_3: true @@ -412,17 +409,18 @@ rhel9cis_rule_5_4_3_1: true rhel9cis_rule_5_4_3_2: true rhel9cis_rule_5_4_3_3: true -# Section 6 Logging and Auditing -## 6.1 Configure Integrity Checking +## Section 6 Fixes +# Section 6 rules control Logging and Auditing +# Configure Integrity Checking rhel9cis_rule_6_1_1: true rhel9cis_rule_6_1_2: true rhel9cis_rule_6_1_3: true -## 6.2.1 Configure systemd-journald service +# 6.2.1 Configure systemd-journald service rhel9cis_rule_6_2_1_1: true rhel9cis_rule_6_2_1_2: true rhel9cis_rule_6_2_1_3: true rhel9cis_rule_6_2_1_4: true -## 6.2.2.x Configure journald +# 6.2.2.x Configure journald rhel9cis_rule_6_2_2_1_1: true rhel9cis_rule_6_2_2_1_2: true rhel9cis_rule_6_2_2_1_3: true @@ -430,7 +428,7 @@ rhel9cis_rule_6_2_2_1_4: true rhel9cis_rule_6_2_2_2: true rhel9cis_rule_6_2_2_3: true rhel9cis_rule_6_2_2_4: true -## 6.2.3 Configure rsyslog +# 6.2.3 Configure rsyslog rhel9cis_rule_6_2_3_1: true rhel9cis_rule_6_2_3_2: true rhel9cis_rule_6_2_3_3: true @@ -439,20 +437,20 @@ rhel9cis_rule_6_2_3_5: true rhel9cis_rule_6_2_3_6: true rhel9cis_rule_6_2_3_7: true rhel9cis_rule_6_2_3_8: true -## 6.2.4 Configure Logfiles +# 6.2.4 Configure Logfiles rhel9cis_rule_6_2_4_1: true -## 6.3 Configure Auditing -## 6.3.1 Configure auditd Service +# 6.3 Configure Auditing +# 6.3.1 Configure auditd Service rhel9cis_rule_6_3_1_1: true rhel9cis_rule_6_3_1_2: true rhel9cis_rule_6_3_1_3: true rhel9cis_rule_6_3_1_4: true -## 6.3.2 Configure Data Retention +# 6.3.2 Configure Data Retention rhel9cis_rule_6_3_2_1: true rhel9cis_rule_6_3_2_2: true rhel9cis_rule_6_3_2_3: true rhel9cis_rule_6_3_2_4: true -## 6.3.3 Configure auditd Rules +# 6.3.3 Configure auditd Rules rhel9cis_rule_6_3_3_1: true rhel9cis_rule_6_3_3_2: true rhel9cis_rule_6_3_3_3: true @@ -474,7 +472,7 @@ rhel9cis_rule_6_3_3_18: true rhel9cis_rule_6_3_3_19: true rhel9cis_rule_6_3_3_20: true rhel9cis_rule_6_3_3_21: true -## 6.3.4 Configure auditd File Access +# 6.3.4 Configure auditd File Access rhel9cis_rule_6_3_4_1: true rhel9cis_rule_6_3_4_2: true rhel9cis_rule_6_3_4_3: true @@ -486,8 +484,9 @@ rhel9cis_rule_6_3_4_8: true rhel9cis_rule_6_3_4_9: true rhel9cis_rule_6_3_4_10: true -# Section 7 System Maintenance -## 7.1 System File Permissions +## Section 7 Fixes +# Section 7 rules control System Maintenance +# System File Permissions rhel9cis_rule_7_1_1: true rhel9cis_rule_7_1_2: true rhel9cis_rule_7_1_3: true @@ -501,7 +500,7 @@ rhel9cis_rule_7_1_10: true rhel9cis_rule_7_1_11: true rhel9cis_rule_7_1_12: true rhel9cis_rule_7_1_13: true -## 7.2 Local User and Group Settings +# 7.2 Local User and Group Settings rhel9cis_rule_7_2_1: true rhel9cis_rule_7_2_2: true rhel9cis_rule_7_2_3: true @@ -530,12 +529,12 @@ rhel9cis_tmp_svc: false # Setting to `true` will allow a test on the package and force the import of the key rhel9cis_force_gpg_key_import: true -## Control 1.2.4 +## Control 1.2.1.3 # When installing RHEL from authorized Red Hat source, RHEL will come with default YUM repository. NOT having a default YUM # repo ('rhel9cis_rhel_default_repo' set as 'false'), in conjunction with 'rhel9cis_rule_enable_repogpg' set as 'True', will enable the tasks # which check the GPG signatures for all the individual YUM repositories. rhel9cis_rhel_default_repo: true -## Control 1.2.4 +## Control 1.2.1.3 # When 'rhel9cis_rule_enable_repogpg' is set to 'true'(in conjunction with 'rhel9cis_rhel_default_repo':'false'), conditions are met for # enabling the GPG signatures-check for all the individual YUM repositories. If GPG signatures-check is enabled on repositories which do not # support it(like RedHat), installation of packages will fail. @@ -547,7 +546,7 @@ rhel9cis_rule_enable_repogpg: true # and may prevent some services from running. Requires SELinux not being disabled (by # having 'rhel9cis_selinux_disable' var set as 'true'), otherwise setting will be ignored. rhel9cis_selinux_pol: targeted -## Control 1.6.1.3|4 - SELinux configured and not disabled +## Control 1.3.1.3|4|5 - SELinux policy settings # This variable contains a specific SELinux mode, respectively: # - 'enforcing': SELinux policy IS enforced, therefore denies operations based on SELinux policy # rules. If system was installed with SELinux, this is enabled by default. @@ -569,7 +568,7 @@ rhel9cis_bootloader_password_hash: 'grub.pbkdf2.sha512.changethispassword' # pr # This variable governs whether a bootloader password should be set in '/boot/grub2/user.cfg' file. rhel9cis_set_boot_pass: true -## Control 1.6 +## Controls 1.6.x # This variable contains the value to be set as the system-wide crypto policy. Current rule enforces NOT USING # 'LEGACY' value(as it is less secure, it just ensures compatibility with legacy systems), therefore # possible values for this variable are, as explained by RedHat docs: @@ -577,12 +576,21 @@ rhel9cis_set_boot_pass: true # -'FUTURE': conservative security level that is believed to withstand any near-term future attacks # -'FIPS': A level that conforms to the FIPS140-2 requirements rhel9cis_crypto_policy: 'DEFAULT' -## Control 1.6 +## Controls 1.6.x and Controls 5.1.x +# 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, which currently are: +# - 'OSPP' +# - 'AD-SUPPORT' +# - 'AD-SUPPORT-LEGACY' +rhel9cis_crypto_policy_module: '' +## Controls 1.6.x # 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 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 # - 1.7.2 - Ensure local login warning banner is configured properly @@ -592,7 +600,12 @@ rhel9cis_warning_banner: Authorized users only. All activity may be monitored an # End Banner ## Control 1.8.x - Settings for GDM -## 1.8 GDM graphical interface +# This variable governs whether rules dealing with GUI specific packages(and/or their settings) should +# be executed either to: +# - secure GDM, if GUI is needed('rhel9cis_gui: true') +# - or remove GDM and X-Windows-system, if no GUI is needed('rhel9cis_gui: false') +# The value of this variable is set automatically, if gnome is present this variable +# will always have `true` as a value, and `false` otherwise. rhel9cis_gui: "{{ prelim_gnome_present.stat.exists | default(false) }}" # This variable specifies the GNOME configuration database file to which configurations are written. # (See "https://help.gnome.org/admin/system-admin-guide/stable/dconf-keyfiles.html.en") @@ -640,92 +653,145 @@ rhel9cis_chrony_server_makestep: "1.0 3" # improve the reliability, because multiple sources will need to correspond with each other. rhel9cis_chrony_server_minsources: 2 -# Service configuration -# Options are -# Service -# - false - removes package -# - true - leaves package installed -# Mask -# - false - leaves service in current status -# - true - sets service name to masked -# -# Setting both Service and Mask to false will remove the package if exists +### +### The set of rules that make up section 2.1, are used for ensuring that +### certain services are not installed on the OS. +### The following list of variables contain two types: the ones that end in '_services', and the ones that end in '_mask' +### in '_mask'. For completely removing a service both those variables referencing that service shall be set to 'false'. +### For masking a service the type that ends in '_mask' shall be set to 'true'. +### Set this variable to `true` to keep service `autofs`; otherwise, the service is uninstalled. +### + +########################################### + +## Controls 2.1.x - Configure Server Services +# Set this variable to `true` to keep service `autofs`; otherwise, the service is uninstalled. rhel9cis_autofs_services: false +# Set this variable to `true` to mask service `autofs`. rhel9cis_autofs_mask: false +# Set this variable to `true` to keep service `avahi`; otherwise, the service is uninstalled. rhel9cis_avahi_server: false +# Set this variable to `true` to mask service `avahi`. rhel9cis_avahi_mask: false +# Set this variable to `true` to keep service `dhcp`; otherwise, the service is uninstalled. rhel9cis_dhcp_server: false +# Set this variable to `true` to mask service `dhcp`. rhel9cis_dhcp_mask: false +# Set this variable to `true` to keep service `dns`; otherwise, the service is uninstalled. rhel9cis_dns_server: false +# Set this variable to `true` to mask service `dns`. rhel9cis_dns_mask: false +# Set this variable to `true` to keep service `dnsmasq`; otherwise, the service is uninstalled. rhel9cis_dnsmasq_server: false +# Set this variable to `true` to mask service `dnsmasq`. rhel9cis_dnsmasq_mask: false +# Set this variable to `true` to keep service `samba`; otherwise, the service is uninstalled. rhel9cis_samba_server: false +# Set this variable to `true` to mask service `samba`. rhel9cis_samba_mask: false +# Set this variable to `true` to keep service `ftp`; otherwise, the service is uninstalled. rhel9cis_ftp_server: false +# Set this variable to `true` to mask service `ftp`. rhel9cis_ftp_mask: false +# Set this variable to `true` to keep service `message`; otherwise, the service is uninstalled. rhel9cis_message_server: false # This is for messaging dovecot and cyrus-imap +# Set this variable to `true` to mask service `message`. rhel9cis_message_mask: false +# Set this variable to `true` to keep service `nfs`; otherwise, the service is uninstalled. rhel9cis_nfs_server: true +# Set this variable to `true` to mask service `nfs`. rhel9cis_nfs_mask: true +# Set this variable to `true` to keep service `nis`; otherwise, the service is uninstalled. rhel9cis_nis_server: true # set to mask if nis client required +# Set this variable to `true` to mask service `nis`. rhel9cis_nis_mask: false +# Set this variable to `true` to keep service `print`; otherwise, the service is uninstalled. rhel9cis_print_server: false # replaces cups +# Set this variable to `true` to mask service `print`. rhel9cis_print_mask: false +# Set this variable to `true` to keep service `rpc`; otherwise, the service is uninstalled. rhel9cis_rpc_server: true +# Set this variable to `true` to mask service `rpc`. rhel9cis_rpc_mask: true +# Set this variable to `true` to keep service `rsync`; otherwise, the service is uninstalled. rhel9cis_rsync_server: false +# Set this variable to `true` to mask service `rsync`. rhel9cis_rsync_mask: false +# Set this variable to `true` to keep service `snmp`; otherwise, the service is uninstalled. rhel9cis_snmp_server: false +# Set this variable to `true` to mask service `snmp`. rhel9cis_snmp_mask: false +# Set this variable to `true` to keep service `telnet`; otherwise, the service is uninstalled. rhel9cis_telnet_server: false +# Set this variable to `true` to mask service `telnet`. rhel9cis_telnet_mask: false +# Set this variable to `true` to keep service `tftp`; otherwise, the service is uninstalled. rhel9cis_tftp_server: false +# Set this variable to `true` to mask service `tftp`. rhel9cis_tftp_mask: false +# Set this variable to `true` to keep service `squid`; otherwise, the service is uninstalled. rhel9cis_squid_server: false +# Set this variable to `true` to mask service `squid`. rhel9cis_squid_mask: false +# Set this variable to `true` to keep service `httpd`; otherwise, the service is uninstalled. rhel9cis_httpd_server: false +# Set this variable to `true` to mask service `httpd`. rhel9cis_httpd_mask: false +# Set this variable to `true` to keep service `nginx`; otherwise, the service is uninstalled. rhel9cis_nginx_server: false +# Set this variable to `true` to mask service `nginx`. rhel9cis_nginx_mask: false +# Set this variable to `true` to keep service `xinetd`; otherwise, the service is uninstalled. rhel9cis_xinetd_server: false +# Set this variable to `true` to mask service `xinetd`. rhel9cis_xinetd_mask: false +# Set this variable to `true` to keep service `xwindow`; otherwise, the service is uninstalled. rhel9cis_xwindow_server: false # will remove mask not an option + +## Control 2.1.21 - Ensure mail transfer agent is configured for local-only mode +# This variable if set to 'false', ensures that the mail transfer agent is configured for +# local-only mode. rhel9cis_is_mail_server: false -## Section 2.3 Service clients +## Section 2.2 Service clients +## Control - 2.2.1 - Ensure FTP client is not installed +# Set this variable to `true` to keep package `ftp`; otherwise, the package is uninstalled. rhel9cis_ftp_client: false +## Control - 2.2.2 - Ensure LDAP client is not installed +# Set this variable to `true` to keep package `openldap-clients`; otherwise, the package is uninstalled. rhel9cis_openldap_clients_required: false +## Control - 2.2.3 - Ensure nis client is not installed +# Set this variable to `true` to keep package `nis`(`ypbind`); otherwise, the package is uninstalled. rhel9cis_ypbind_required: false # Same package as NIS server +## Control - 2.2.4 - Ensure telnet client is not installed +# Set this variable to `true` to keep package `telnet`; otherwise, the package is uninstalled. rhel9cis_telnet_required: false +## Control - 2.2.5 - Ensure tftp client is not installed +# Set this variable to `true` to keep package `tftp`; otherwise, the package is uninstalled. rhel9cis_tftp_client: false ## Section 3 vars -## Sysctl -# Service configuration -# Options are -# Service -# - false - removes package -# - true - leaves package installed -# Mask -# - false - leaves service in current status -# - true - sets service name to masked -# -# Setting both Service and Mask to false will remove the package if exists -# -rhel9cis_bluetooth_service: false -rhel9cis_bluetooth_mask: false -## 3.1 IPv6 requirement toggle +## Control 3.1.1 - Ensure IPv6 status is identified # This variable governs whether ipv6 is enabled or disabled. rhel9cis_ipv6_required: true -## 3.1.2 wireless network requirements +## Control 3.1.2 - Ensure wireless interfaces are disabled # if wireless adapter found allow network manager to be installed rhel9cis_install_network_manager: false +# This variable holds the name of the network manager package, and it is used +# as a conditional to implement control 3.1.2. If the network manager package +# is present on the system then the control will be implemented! rhel9cis_network_manager_package_name: NetworkManager -# 3.3 System network parameters (host only OR host and router) + +## Control 3.1.3 - Ensure bluetooth services are not in use +# Set this variable to `true` to keep service `bluetooth`; otherwise, the service is uninstalled. +rhel9cis_bluetooth_service: false +# Set this variable to `true` to mask service `bluetooth`. +rhel9cis_bluetooth_mask: false + +## Controls 3.3.x 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. rhel9cis_is_router: false @@ -742,7 +808,8 @@ rhel9cis_flush_ipv4_route: false # NOTE: The current default value is likely to be overridden by other further tasks(via 'set_fact'). rhel9cis_flush_ipv6_route: false -# Section 4 vars +## Section 4 vars + ### Firewall Service to install and configure - Options are: # 1) either 'firewalld' # 2) or 'nftables' @@ -752,27 +819,27 @@ rhel9cis_flush_ipv6_route: false #### masked = leave package if installed and mask the service rhel9cis_firewall: firewalld -## Control 4.2.x - Ensure firewalld default zone is set +## Control 4.2.2 - Ensure firewalld loopback traffic is configured # This variable will set the firewalld default zone(that is used for everything that is not explicitly bound/assigned # to another zone): if there is no zone assigned to a connection, interface or source, only the default zone is used. rhel9cis_default_zone: public -## Controls 4.3.x nftables - -## 4.3.1 Ensure nftables base chains exist -# This variable governs if a nftables base chain(entry point for packets from the networking stack) will be automatically -# created, if needed. Without a chain, a hook for input, forward, and delete, packets that would flow through those -# chains will not be touched by nftables. -rhel9cis_nft_tables_autochaincreate: true - -## 4.3.2 Create tables if required +## Controls 4.3.x +# This variable governs if a table will be automatically created in nftables. Without a table (no default one), nftables +# will not filter network traffic, so if this variable is set to 'false' and no tables exist, an alarm will be triggered! rhel9cis_nft_tables_autonewtable: true # This variable stores the name of the table to be used when configuring nftables(creating chains, configuring loopback # traffic, established connections, default deny). If 'rhel9cis_nft_tables_autonewtable' is set as true, a new table will # be created using as name the value stored by this variable. rhel9cis_nft_tables_tablename: filter -## Section5 vars +## Control 4.3.1 - Ensure nftables base chains exist +# This variable governs if a nftables base chain(entry point for packets from the networking stack) will be automatically +# created, if needed. Without a chain, a hook for input, forward, and delete, packets that would flow through those +# chains will not be touched by nftables. +rhel9cis_nft_tables_autochaincreate: true + +## Section 5 vars ## Section 5.1 - SSH @@ -781,32 +848,30 @@ rhel9cis_nft_tables_tablename: filter # Otherwise, the default value is '/etc/ssh/ssh_config'. rhel9cis_sshd_config_file: /etc/ssh/sshd_config -## Controls: -## - 5.1.7 - Ensure SSH access is limited +## Control 5.1.7 - Ensure sshd access is configured # This variable, if specified, configures a list of USER name patterns, separated by spaces, to allow SSH # access for users whose user name matches one of the patterns. This is done # by setting the value of `AllowUsers` option in `/etc/ssh/sshd_config` file. # If an USER@HOST format will be used, the specified user will be allowed only on that particular host. rhel9cis_sshd_allowusers: "{% if ansible_facts.user_id != 'root' %}{{ ansible_facts.user_id }}{% elif ansible_env.SUDO_USER is defined %}{{ ansible_env.SUDO_USER }}{% endif %}" - +## Control 5.1.7 - Ensure sshd access is configured # (String) This variable, if specified, configures a list of GROUP name patterns, separated by spaces, to allow SSH access # for users whose primary group or supplementary group list matches one of the patterns. This is done # by setting the value of `AllowGroups` option in `/etc/ssh/sshd_config` file. rhel9cis_sshd_allowgroups: "" - +## Control 5.1.7 - Ensure sshd access is configured # This variable, if specified, configures a list of USER name patterns, separated by spaces, to prevent SSH access # for users whose user name matches one of the patterns. This is done # by setting the value of `DenyUsers` option in `/etc/ssh/sshd_config` file. # If an USER@HOST format will be used, the specified user will be restricted only on that particular host. rhel9cis_sshd_denyusers: "nobody" - +## Control 5.1.7 - Ensure sshd access is configured # This variable, if specified, configures a list of GROUP name patterns, separated by spaces, # to prevent SSH access for users whose primary group or supplementary group list matches one of the patterns. This is done # by setting the value of `DenyGroups` option in `/etc/ssh/sshd_config` file. rhel9cis_sshd_denygroups: "" -## - 5.1.9 - ClientAlive and CountMax -# default settings allow 45 seconds e.g. count x interval +## Control 5.1.9 - Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured # This variable sets the maximum number of unresponsive "keep-alive" messages # that can be sent from the server to the client before the connection is considered # inactive and thus, closed. @@ -816,17 +881,19 @@ rhel9cis_sshd_clientalivecountmax: 3 # keep the connection alive and prevent it being terminated due to inactivity. rhel9cis_sshd_clientaliveinterval: 15 -## Control 5.1.12 - disable forwarding +## Control 5.1.10 - Ensure sshd DisableForwarding is enabled # 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 +# This variable's value is used in the `/etc/ssh/ssh_config.d/50-redhat.conf` file to +# disable X11Forwarding. If X11 is required, set this variable's value to `yes`! rhel9cis_sshd_x11forwarding: 'no' -## - 5.2.14 - Ensure SSH LoginGraceTime is set to one minute or less +## Control 5.1.14 - Ensure SSH LoginGraceTime is set to one minute or less # This variable specifies the amount of seconds allowed for successful authentication to # the SSH server. rhel9cis_sshd_logingracetime: 60 -## Control 5.2.15 - Ensure SSH LogLevel is appropriate +## Control 5.1.15 - Ensure SSH LogLevel is appropriate # This variable is used to control the verbosity of the logging produced by the SSH server. # The options for setting it are as follows: # - `QUIET`: Minimal logging; @@ -838,19 +905,19 @@ rhel9cis_sshd_logingracetime: 60 # - `DEBUG(x)`: Whereas x = debug level 1 to 3, DEBUG=DEBUG1. rhel9cis_ssh_loglevel: INFO -## Control 5.1.16 MaxAuthTries configured +## Control 5.1.16 - Ensure sshd MaxAuthTries is configured # The MaxAuthTries parameter specifies the maximum number of authentication # attempts permitted per connection. When the login failure count reaches half the # number, error messages will be written to the syslog file detailing the login failure. rhel9cis_ssh_maxauthtries: '4' -## Control 5.1.17 MaxStartups +## Control 5.1.17 - Ensure sshd MaxStartups is configured # The MaxStartups parameter specifies the maximum number of concurrent unauthenticated connections to the SSH daemon. rhel9cis_ssh_maxstartups: '10:30:60' -## Control 5.1.18 - Ensure SSH MaxSessions is set to 10 or less +## Control 5.1.18 - Ensure sshd MaxSessions is configured # This variable value specifies the maximum number of open sessions that are permitted from -# a given location +# a given location. CIS recommends it to be 10 or less. rhel9cis_ssh_maxsessions: 4 ## Control 5.2.x - Ensure sudo log file exists @@ -859,162 +926,201 @@ rhel9cis_ssh_maxsessions: 4 # This variable defines the path and file name of the sudo log file. rhel9cis_sudolog_location: "/var/log/sudo.log" -## Control 5.2.x -Ensure sudo authentication timeout is configured correctly +## Control 5.2.4 - Ensure users must provide password for escalation +# The following variable specifies a list of users that should not be required to provide a password +# for escalation. Feel free to edit it according to your needs. +rhel9cis_sudoers_exclude_nopasswd_list: + - ec2-user + - vagrant + +## Control 5.2.6 - Ensure sudo authentication timeout is configured correctly # This variable sets the duration (in minutes) during which a user's authentication credentials # are cached after successfully authenticating using "sudo". This allows the user to execute # multiple commands with elevated privileges without needing to re-enter their password for each # command within the specified time period. CIS requires a value of at most 15 minutes. rhel9cis_sudo_timestamp_timeout: 15 -## Control 5.2.4 -# This will leave NOPASSWD intact for these users -rhel9cis_sudoers_exclude_nopasswd_list: - - ec2-user - - vagrant - -## Control 5.2 - Ensure access to the 'su' command is restricted +## Control 5.2.7 - Ensure access to the 'su' command is restricted # This variable determines the name of the group of users that are allowed to use the su command. # CIS requires that such a group be CREATED(named according to site policy) and be kept EMPTY. rhel9cis_sugroup: sugroup -## 5.3.x PAM and Authselect +## Controls 5.3.x PAM and Authselect # Do not use authselect if: # Your host is part of Linux Identity Management. # Joining your host to an IdM domain with the ipa-client-install command automatically configures SSSD authentication on your host. # Your host is part of Active Directory via SSSD. # Calling the realm join command to join your host to an Active Directory domain automatically configures SSSD authentication on your host. rhel9cis_allow_authselect_updates: true -## +## Control 5.3.1.2 - Ensure latest version of authselect is installed +# The following variables controls the implementation of control 5.3.1.2. +# If you want the latest version to be installed set this variable's value +# to `true`. rhel9cis_authselect_pkg_update: false # NOTE the risks if system is using SSSD or using ipa-client-install ## PAM AND Authselect -# To create a new profile (best for greenfield fresh sites not configured) -# This allows creation of a custom profile using an existing one to build from -# will only create if profile does not already exist -## options true or false -rhel9cis_authselect_custom_profile_create: true -## Controls: -# - 5.3.2.1 - Ensure custom authselect profile is used -# Settings in place now will fail, they are placeholders from the control example. Due to the way many multiple -# options and ways to configure this control needs to be enabled and settings adjusted to minimize risk. +## Controls 5.3.x + # This variable configures the name of the custom profile to be created and selected. -# To be changed from default - cis_example_profile +# To be changed from default - cis_example_profile. This setting needs to be adjusted +# in order to minimise risk. rhel9cis_authselect_custom_profile_name: cis_example_profile # Name of the existing authselect profile to copy - options can be found with # ```authselect list``` on the host to be configured rhel9cis_authselect_default_profile_to_copy: "sssd --symlink-meta" -## Controls -# - 5.3.3. - Ensure lockout for failed password attempts is configured -# - 5.5.3 - Ensure password reuse is limited -# - 5.5.4 - Ensure password hashing algorithm is SHA-512 -# - 5.4.2 - Ensure authselect includes with-faillock -# - 5.3.3.1.1 +## Control 5.3.3.1.1 - # This variable sets the amount of tries a password can be entered, before a user is locked. rhel9cis_pam_faillock_deny: 5 -# - 5.3.3.1.2 +## Control 5.3.3.2, 5.3.2.2 # This variable sets the amount of time a user will be unlocked after the max amount of -# password failures. +# password failures. rhel9cis_pam_faillock_unlock_time: 900 -# This variable represents the number of password change cycles, after which -# an user can re-use a password. -# CIS requires a value of 5 or more. -# 5.3.3.1.3 Locking even deny root or root unlock times -# rhel9cis_pamroot_lock_option options are -# even_deny_root -# root_unlock_time = {{ rhel9cis_root_unlock_time }} -rhel9cis_root_unlock_time: 60 -rhel9cis_pamroot_lock_option: even_deny_root -# rhel9cis_pamroot_lock_option: "root_unlock_time = {{ rhel9cis_root_unlock_time }}" -# 5.3.3.2.1 - password difok +## Control 5.3.3.1.3 - Ensure password failed attempts lockout includes root account +# This variable is used in the task that ensures that even the root account +# is included in the password failed attempts lockout measure. +# The following variable is used in the 'regexp' field. This field is used to find the +# line in the file. If the line matches the regular expression, it will be replaced +# with the line parameter's value. +rhel9cis_pamroot_lock_option: even_deny_root + +## Control 5.3.3.2.1 - Ensure password number of changed characters is configured +# This variable holds the path to the configuration file that will be created (or overwritten if already existing) +# in order to implement the 'Ensure password number of changed characters is configured' control. rhel9cis_passwd_difok_file: etc/security/pwquality.conf.d/50-pwdifok.conf # pragma: allowlist secret +# This variable's value represents the minimum number of characters that must be different between +# the new password and the old password. It helps ensure that users don't create new passwords that +# are too similar to their previous ones, enhancing security. CIS states that this value should be at least 2. rhel9cis_passwd_difok_value: 2 -# 5.3.3.2.2 - password minlength +## Control 5.3.3.2.2 - Ensure minimum password length is configured +# This variable holds the path to the configuration file that will be created (or overwritten if already existing) +# in order to implement the 'Ensure minimum password length is configured' control. rhel9cis_passwd_minlen_file: etc/security/pwquality.conf.d/50-pwlength.conf # pragma: allowlist secret +# This variable specifies the minimum length that a password must have to be considered valid. +# CIS states that this value should be at least 14. rhel9cis_passwd_minlen_value: 14 -# 5.3.3.2.3 - password complex +## Control 5.3.3.2.3 - Ensure password complexity is configured +# The following variable holds the path to the configuration file that will be created (or overwritten if already existing) +# in order to implement the 'Ensure password complexity is configured' control. rhel9cis_passwd_complex_file: etc/security/pwquality.conf.d/50-pwcomplexity.conf # pragma: allowlist secret -# Choose if using minclass or credits options -# Options are: minclass or credits -# ensure only one is selected +# This variable holds the options for configuring the password complexity. +# Options supported are: 'minclass' or 'credits'. rhel9cis_passwd_complex_option: minclass # pragma: allowlist secret +# The following variable sets the password complexity via 'minclass'. The 'minclass' option provides +# the minimum number of classes of characters required in a new password. (digits, uppercase, lowercase, others). e.g. +# For example a value of 4 would mean that it requires digits, uppercase, lower case, and special characters. rhel9cis_passwd_minclass: 4 -# rhel9cis_passwd_complex: credits +# The following variables set the password complexity via the 'credits' option. +# Each of the variables represents a requirement for complexity. +# The 'dcredit' variable is the maximum credit for having digits in the new password. +# If less than 0 it is the minimum number of digits in the new password. +# e.g. dcredit = -1 requires at least one digit rhel9cis_passwd_dcredit: -1 +# The 'ucredit' variable is the maximum credit for having uppercase characters in the new password. +# If less than 0 it is the minimum number of uppercase characters in the new password. +# e.g. ucredit = -1 requires at least one uppercase character rhel9cis_passwd_ucredit: -2 +# The 'ocredit' variable is the maximum credit for having other characters in the new password. +# If less than 0 it is the minimum number of other characters in the new password. +# e.g. ocredit = -1 requires at least one special character rhel9cis_passwd_ocredit: 0 +# The 'lcredit' variable is the maximum credit for having lowercase characters in the new password. +# If less than 0 it is the minimum number of lowercase characters in the new password. +# e.g. lcredit = -1 requires at least one lowercase character rhel9cis_passwd_lcredit: -2 -# 5.3.3.2.4 - password maxrepeat +## Control 5.3.3.2.4 - Ensure password same consecutive characters is configured +# This variable holds the path to the configuration file that will be created (or overwritten if already existing) +# in order to implement the 'Ensure password same consecutive characters is configured' control. rhel9cis_passwd_maxrepeat_file: etc/security/pwquality.conf.d/50-pwrepeat.conf # pragma: allowlist secret +# The following variable sets the maximum number of allowed same consecutive characters in a new password. rhel9cis_passwd_maxrepeat_value: 3 -# 5.3.3.2.5 - password maxsequence +## Control 5.3.3.2.5 - Ensure password maximum sequential characters is configured +# This variable holds the path to the configuration file that will be created (or overwritten if already existing) +# in order to implement the 'Ensure password maximum sequential characters is configured' control. rhel9cis_passwd_maxsequence_file: etc/security/pwquality.conf.d/50-pwmaxsequence.conf # pragma: allowlist secret +# The following variable sets the maximum length of monotonic character sequences in the new password. +# Examples of such sequence are '12345' or 'fedcb' . The check is disabled if the value is 0 . rhel9cis_passwd_maxsequence_value: 3 -# 5.3.3.2.6 - password dictcheck +## Control 5.3.3.2.6 - Ensure password dictionary check is enabled +# This variable holds the path to the configuration file that will be created (or overwritten if already existing) +# in order to implement the 'Ensure password dictionary check is enabled' control rhel9cis_passwd_dictcheck_file: etc/security/pwquality.conf.d/50-pwdictcheck.conf # pragma: allowlist secret +# The following variable's value sets whether to check for the words from the cracklib dictionary. +# When set to '1', this option enables dictionary checks, ensuring that passwords are not based on common +# dictionary words, which helps prevent users from choosing easily guessable passwords. +# When set to '0', dictionary checks are disabled. CIS states that it shall always be set to '1'. rhel9cis_passwd_dictcheck_value: 1 -# 5.3.3.2.7 - password quality enforce -rhel9cis_passwd_quality_enforce_file: etc/security/pwquality.conf.d/50-pwquality_enforce.conf # pragma: allowlist secret +# This variable is used in one of the config files to ensure password quality checking is enforced rhel9cis_passwd_quality_enforce_value: 1 -# 5.3.3.2.8 - password quality enforce for root included with 5.3.3.2.7 +## Control 5.3.3.2.7 - Ensure password quality is enforced for the root user +# This variable holds the path to the configuration file that will be created (or overwritten if already existing) +# in order to implement the 'Ensure password quality is enforced for the root user' control. rhel9cis_passwd_quality_enforce_root_file: etc/security/pwquality.conf.d/50-pwroot.conf # pragma: allowlist secret +# The following variable enforces that the root user must adhere to the same password quality policies as other users. rhel9cis_passwd_quality_enforce_root_value: enforce_for_root # pragma: allowlist secret -# PWhistory -## 5.3.3.3.1 remember history -# rhel9cis_pamd_pwhistory_remember: - is the number of old passwords to remember +## Control 5.3.3.3.1 - Ensure password history remember is configured +# This variable represents the number of password change cycles, after which +# a user can re-use a password. CIS requires a value of 24 or more. rhel9cis_pamd_pwhistory_remember: 24 -# 5.3.3.4.x +## Controls 5.3.3.4.3, 5.4.1.4 +# The following variable's value represents the hashing algorithm used rhel9cis_passwd_hash_algo: sha512 # pragma: allowlist secret -## Control 5.6.1.1 - Ensure password expiration is 365 days or less +## Control 5.4.1.1 - Ensure password expiration is 365 days or less # This variable governs after how many days a password expires. # CIS requires a value of 365 or less. rhel9cis_pass_max_days: 365 -## Control 5.6.1.2 - Ensure minimum days between password changes is 7 or more +# The following variable allows the forcing of setting user_max_days for logins. +# This can break current connecting user access +rhel9cis_force_user_maxdays: false +## Control 5.4.1.2 - Ensure minimum days between password changes is 7 or more # This variable specifies the minimum number of days allowed between changing # passwords. CIS requires a value of at least 1. rhel9cis_pass_min_days: 7 -## Control 5.6.1.3 - Ensure password expiration warning days is 7 or more +# The following variable allows the force setting of minimum days between changing the password +# This can break current connecting user access +rhel9cis_force_user_mindays: false +## Control 5.4.1.3 - Ensure password expiration warning days is 7 or more # This variable governs, how many days before a password expires, the user will be warned. # CIS requires a value of at least 7. rhel9cis_pass_warn_age: 7 +#The following variable allows the forcing of number of days before warning users of password expiry +# This can break current connecting user access +rhel9cis_force_user_warnage: false -## Control 5.4.1.x - Ensure inactive password lock is 30 days or less +## Control 5.4.1.5 - Ensure inactive password lock is configured rhel9cis_inactivelock: # This variable specifies the number of days of inactivity before an account will be locked. # CIS requires a value of 30 days or less. lock_days: 30 -## 5.4.1.x Allow the forcing of setting user_max_days for logins. -# This can break current connecting user access -rhel9cis_force_user_maxdays: false - -## 5.4.1.x Allow the force setting of minimum days between changing the password -# This can break current connecting user access -rhel9cis_force_user_mindays: false - -## 5.4.1.x Allow the forcing of of number of days before warning users of password expiry -# This can break current connecting user access -rhel9cis_force_user_warnage: false - -## Control 5.4.1.x - Ensure all users last password change date is in the past +## Control 5.4.1.6 - Ensure all users last password change date is in the past # Allow ansible to expire password for account with a last changed date in the future. Setting it # to 'false' will just display users in violation, while 'true' will expire those users passwords. rhel9cis_futurepwchgdate_autofix: true -# 5.4.2.x +## Control 5.4.2.6 - Ensure root user umask is configured +# The following variable specifies the "umask" to configure for the root user. +# The user file-creation mode mask ( umask ) is used to determine the file +# permission for newly created directories and files. In Linux, the default +# permissions for any newly created directory is 0777 ( rwxrwxrwx ), and for +# any newly created file it is 0666 ( rw-rw-rw- ). The umask modifies the default +# Linux permissions by restricting (masking) these permissions. The umask is not +# simply subtracted, but is processed bitwise. Bits set in the umask are cleared +# in the resulting file mode. CIS recommends setting 'umask' to '0027' or more +# restrictive. rhel9cis_root_umask: '0027' # 0027 or more restrictive ## Control 5.4.2.7 - Ensure system accounts are secured | Set nologin @@ -1036,52 +1142,38 @@ rhel9cis_shell_session_timeout: 900 # - `/etc/bash.bashrc`. rhel9cis_shell_session_file: /etc/profile.d/tmout.sh -## Control 5.4.3.2 bash umask +## Control 5.4.3.3 - Ensure default user umask is configured +# The following variable specifies the "umask" to set in the `/etc/bash.bashrc` and `/etc/profile`. +# The value needs to be `027` or more restrictive to comply with CIS standards. rhel9cis_bash_umask: '0027' # 0027 or more restrictive -### Controls: -# - 5.6.2 - Ensure system accounts are secured -# - 6.2.10 - Ensure local interactive user home directories exist -# - 6.2.11 - Ensure local interactive users own their home directories -# UID settings for interactive users -# 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 `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 `rhel9cis_discover_int_uid` has -# been set to `true`. -max_int_uid: 65533 +## Section 6 vars -## Section6 vars -## Control 6.1.x - allow aide to be configured +## Control 6.1.1 - Ensure AIDE is installed # AIDE is a file integrity checking tool, similar in nature to Tripwire. # While it cannot prevent intrusions, it can detect unauthorized changes # to configuration files by alerting when the files are changed. Review # the AIDE quick start guide and AIDE documentation before proceeding. -# By setting this variable to `true`, all of the settings related to AIDE will be applied! +# By setting this variable to `true`, all the settings related to AIDE +# will be applied! rhel9cis_config_aide: true - -# If DB file older than below will automatically rebuild DB +# This variable sets a maximum allowed age of the AIDE database file until +# the file is rebuilt. If the file is older than the value below, the role +# will automatically rebuild the database file. # e.g. options:1w = 1 week, 1d = 1day 1h = 1 hour rhel9cis_aide_db_file_age: 1w - -# If aide already setup this forces a new DB to be created +# If AIDE is already setup this variable forces a new database +# file to be created. rhel9cis_aide_db_recreate: false - -# allows to change db file, not config need to be adjusted too +# This variable is used to check if there is already an existing database file +# created by AIDE on the target system. If it is not present, the role will generate +# a database file with the same name as the value of this variable. rhel9cis_aide_db_file: /var/lib/aide/aide.db.gz -## Control 6.1.2 AIDE cron settings - -## How the aide schedule is run either cron or timer +## Control 6.1.2 - Ensure filesystem integrity is regularly checked +# The following variable sets how AIDE is scanned. +# Available options are either cron or timer. rhel9cis_aide_scan: cron - # These are the crontab settings for periodical checking of the filesystem's integrity using AIDE. # The sub-settings of this variable provide the parameters required to configure # the cron job on the target system. @@ -1117,13 +1209,12 @@ rhel9cis_aide_cron: # can be given in the range `0-7` (both `0` and `7` represent Sunday); several weekdays # can be concatenated with commas. aide_weekday: '*' -# + ## Preferred method of logging ## Whether rsyslog or journald preferred method for local logging ## Controls 6.2.1.x | Configure systemd-journald service ## Controls 6.2.2.x | Configured journald ## Controls 6.2.3.x | Configure rsyslog - # This variable governs which logging service should be used, choosing between 'rsyslog' # or 'journald'(CIS recommendation) will trigger the execution of the associated subsection, as the-best # practices are written wholly independent of each other. @@ -1158,36 +1249,31 @@ rhel9cis_journald_runtimekeepfree: 100G # ATTENTION: Uncomment the keyword below when values are set! rhel9cis_journald_maxfilesec: 1month -## Control 6.2.2.1.2 - Ensure systemd-journal-remote is configured +## Control 6.2.2.1.2 - Ensure systemd-journal-upload authentication is configured # 'rhel9cis_journal_upload_url' is the ip address to upload the journal entries to # URL value may specify either just the hostname or both the protocol and hostname. 'https' is the default. The port # number may be specified after a colon (":"), otherwise 19532 will be used by default. rhel9cis_journal_upload_url: 192.168.50.42 -## The paths below have the default paths/files, but allow user to create custom paths/filenames - ## Control 6.2.2.1.2 - Ensure systemd-journal-remote is configured # This variable specifies the path to the private key file used by the remote journal # server to authenticate itself to the client. This key is used alongside the server's -# public certificate to establish secure communication. +# public certificate to establish secure communication. The path below has the default +# path/file, but it is also allowed for a user to create its custom path/filename. rhel9cis_journal_upload_serverkeyfile: "/etc/ssl/private/journal-upload.pem" ## Control 6.2.2.1.2 - Ensure systemd-journal-remote is configured # This variable specifies the path to the public certificate file of the remote journal -# server. This certificate is used to verify the authenticity of the remote server. +# server. This certificate is used to verify the authenticity of the remote server. The path +# below has the default path/file, but it is also allowed for a user to create its custom +# path/filename. rhel9cis_journal_servercertificatefile: "/etc/ssl/certs/journal-upload.pem" ## Control 6.2.2.1.2 - Ensure systemd-journal-remote is configured # This variable specifies the path to a file containing one or more public certificates # of certificate authorities (CAs) that the client trusts. These trusted certificates are used -# to validate the authenticity of the remote server's certificate. +# to validate the authenticity of the remote server's certificate. The path below has the default +## path/file, but it is also allowed for a user to create its custom path/filename. rhel9cis_journal_trustedcertificatefile: "/etc/ssl/ca/trusted.pem" # ATTENTION: Uncomment the keyword below when values are set! -# Control 6.2.3.x - Ensure rsyslog is not configured to receive logs from a remote client -# This variable expresses whether the system is used as a log server or not. If set to: -# - 'false', current system will act as a log CLIENT, thus it should NOT receive data from other hosts. -# - 'true', current system will act as a log SERVER, enabling centralised log management(by protecting log integrity -# from local attacks on remote clients) -rhel9cis_system_is_log_server: false - ## Control 6.2.3.5 | PATCH | Ensure logging is configured # This variable governs if current Ansible role should manage syslog settings # in /etc/rsyslog.conf file, namely mail, news and misc(warn, messages) @@ -1229,27 +1315,40 @@ rhel9cis_remote_log_retrycount: 100 # of rsyslog forwarding must be enabled('rhel9cis_remote_log_server: true'). rhel9cis_remote_log_queuesize: 1000 +# Control 6.2.3.7 - Ensure rsyslog is not configured to receive logs from a remote client +# This variable expresses whether the system is used as a log server or not. If set to: +# - 'false', current system will act as a log CLIENT, thus it should NOT receive data from other hosts. +# - 'true', current system will act as a log SERVER, enabling centralised log management(by protecting log integrity +# from local attacks on remote clients) +rhel9cis_system_is_log_server: false + ## Control 6.2.3.8 rsyslog rotate -# This variable configures whether to set your own rsyslog logrotate setting alternate to logrotate default settings -# Please refer to logrotate options to match your site requirements -# This sets when to rotate +# This variable configures whether to set your own rsyslog logrotate setting +# alternate to logrotate default settings. Please refer to logrotate options +# to match your site requirements +# This variable sets when to rotate rhel9cis_rsyslog_logrotate_rotated_when: weekly -# This sets how many rotations of the file to keep +# This variable sets how many rotations of the file to keep rhel9cis_rsyslog_logrotate_rotatation_keep: 4 -# This defines whether to set various options or not -# these are taken from logrotate options -# Setting -# true will carry out the setting. -# false will either set no/not or not add the option +# The following variable defines whether to set the compress option +# or not. Setting it to `true` will carry out the setting. rhel9cis_rsyslog_logrotate_compress: true +# The following variable defines whether to set the missingok option +# or not. Setting it to `true` will carry out the setting. rhel9cis_rsyslog_logrotate_missingok: true +# The following variable defines whether to set the notifempty option +# or not. Setting it to `true` will carry out the setting. rhel9cis_rsyslog_logrotate_notifempty: true +# The following variable defines whether to set extra options that can +# be defined in the `rhel9cis_rsyslog_logrotate_create_opts` variable +# The variable can be found underneath this variable, in a commented +# state. rhel9cis_rsyslog_logrotate_create: true # Extra options that can be added according to rsyslog documentation # Uncomment and add the required options e.g. mode owner group # rhel9cis_rsyslog_logrotate_create_opts: -## Control 6.3.2.1 - Ensure audit_backlog_limit is sufficient +## Control 6.3.1.3 - Ensure audit_backlog_limit is sufficient # This variable represents the audit backlog limit, i.e., the maximum number of audit records that the # system can buffer in memory, if the audit subsystem is unable to process them in real-time. # Buffering in memory is useful in situations, where the audit system is overwhelmed @@ -1258,13 +1357,14 @@ rhel9cis_rsyslog_logrotate_create: true rhel9cis_audit_back_log_limit: 8192 ## Controls 6.3.2.x - What to do when log files fill up + ## Control 6.3.2.1 - Ensure audit log storage size is configured # This variable specifies the maximum size in MB that an audit log file can reach # before it is archived or deleted to make space for the new audit data. # This should be set based on your sites policy. CIS does not provide a specific value. rhel9cis_auditd_max_log_file_size: 10 -## Control 6.3.2.2 +## Control 6.3.2.2 - Ensure audit logs are not automatically deleted # This variable determines what action the audit system should take when the maximum # size of a log file is reached. # The options for setting this variable are as follows: @@ -1276,36 +1376,63 @@ rhel9cis_auditd_max_log_file_size: 10 # CIS prescribes the value `keep_logs`. rhel9cis_auditd_max_log_file_action: keep_logs -## Control 6.3.2.3 -# This variable determines how the system should act in case of issues with disk -# The disk_full_action parameter tells the system what action to take when no free space is available on the partition that holds the audit log files. +## Control 6.3.2.3 - Ensure system is disabled when audit logs are full +# This variable determines how the system should act in case of issues with the disk. +# The disk_full_action parameter tells the system what action to take when no free space is +# available on the partition that holds the audit log files. # Valid values are ignore, syslog, rotate, exec, suspend, single, and halt. -# -# The disk_error_action parameter tells the system what action to take when an error is detected on the partition that holds the audit log files. -# Valid values are ignore, syslog, exec, suspend, single, and halt. -# # CIS prescribes # disk_full_action parameter: -# Set to halt - the auditd daemon will shutdown the system when the disk partition containing the audit logs becomes full. -# Set to single - the auditd daemon will put the computer system in single user mode when the disk partition containing the audit logs becomes full. -# -# disk_error_action parameter: -# Set to halt - the auditd daemon will shutdown the system when an error is detected on the partition that holds the audit log files. -# Set to single - the auditd daemon will put the computer system in single user mode when an error is detected on the partition that holds the audit log files. -# Set to syslog - the auditd daemon will issue no more than 5 consecutive warnings to syslog when an error is detected on the partition that holds the audit log files. +# Set to halt - the auditd daemon will shutdown the system when the disk partition containing +# the audit logs becomes full. +# Set to single - the auditd daemon will put the computer system in single user mode when the +# disk partition containing the audit logs becomes full. rhel9cis_auditd_disk_full_action: halt +# This variable determines how the system should act in case of issues with the disk. +# The disk_error_action parameter tells the system what action to take when an error is detected +# on the partition that holds the audit log files. +# Valid values are ignore, syslog, exec, suspend, single, and halt. +# disk_error_action parameter: +# Set to halt - the auditd daemon will shutdown the system when an error is detected on the +# partition that holds the audit log files. +# Set to single - the auditd daemon will put the computer system in single user mode when +# an error is detected on the partition that holds the audit log files. +# Set to syslog - the auditd daemon will issue no more than 5 consecutive warnings to syslog +# when an error is detected on the partition that holds the audit log files. rhel9cis_auditd_disk_error_action: syslog -# Control 6.3.2.4 -# Wait to do when space left is low. -# The space_left_action parameter tells the system what action to take when the system has detected that it is starting to get low on disk space. -# Valid values are ignore, syslog, rotate, email, exec, suspend, single, and halt. -# The admin_space_left_action parameter tells the system what action to take when the system has detected that it is low on disk space. -# Valid values are ignore, syslog, rotate, email, exec, suspend, single, and halt. +# Control 6.3.2.4 - Ensure system warns when audit logs are low on space +# This variable tells the system what action to take when the system has detected +# that it is starting to get low on disk space. +# The options for setting this variable are as follows: +# "ignore" - the system does nothing when presented with the aforementioned issue; +# "syslog" - a message is sent to the system log about disk space running low; +# "email" - the system sends an email notification to the email address +# specified in the "action_mail_acct" variable; +# "exec" - the system executes a custom command when disk space is running +# low; +# "suspend" - the system suspends recording audit events until more space is available; +# "single" - the audit daemon will put the computer system in single user mode; +# "halt" - the system is halted when disk space is critically low; +# CIS prescribes either 'email', 'exec', `single` or `halt`. rhel9cis_auditd_space_left_action: email +# This variable tells the system what action to take when the system has detected +# that it is low on disk space. +# The options for setting this variable are as follows: +# "ignore" - the system does nothing when presented with the aforementioned issue; +# "syslog" - a message is sent to the system log about disk space running low; +# "email" - the system sends an email notification to the email address +# specified in the "action_mail_acct" variable; +# "exec" - the system executes a custom command when disk space is running +# low; +# "suspend" - the system suspends recording audit events until more space is available; +# "single" - the audit daemon will put the computer system in single user mode; +# "halt" - the system is halted when disk space is critically low; +# CIS prescribes either `halt` or `single`. rhel9cis_auditd_admin_space_left_action: halt -# This value governs if the below extra-vars for auditd should be used by the role +# This value governs if the below extra-vars (found in the `rhel9cis_auditd_extra_conf`) +# for auditd should be used by the role. rhel9cis_auditd_extra_conf_usage: false # 6.3.3.x allow exceptions for UID in auditd config @@ -1317,18 +1444,27 @@ rhel9cis_auditd_uid_exclude: - 1999 # This can be used to configure other keys in auditd.conf -# Example: rhel9cis_auditd_extra_conf: + # This variable governs the threshold(MegaBytes) under which the audit daemon should perform a + # specific action to alert that the system is running low on disk space. Must be lower than + # the 'space_left' variable. admin_space_left: '10%' # Section 7 Vars -# 7.1.12 Ensure no files or directories without an owner and a group exist -rhel9cis_exclude_unowned_search_path: (! -path "/run/user/*" -a ! -path "/proc/*" -a ! -path "*/containerd/*" -a ! -path "*/kubelet/pods/*" -a ! -path "*/kubelet/plugins/*" -a ! -path "/sys/fs/cgroup/memory/*" -a ! -path "/var/*/private/*") +## Control 7.1.11 - Ensure no world writable files exist +# The following variable is a toggle for enabling/disabling the automated +# removal of world-writable permissions from all files. +# Possible values are `true` and `false`. +rhel9cis_no_world_write_adjust: true -# Control 7.1.12 +## Control 7.1.12 - Ensure no files or directories without an owner and a group exist +# This variable holds the part of the command that helps detect which files and +# directories do not have an owner and an affiliated group. +rhel9cis_exclude_unowned_search_path: (! -path "/run/user/*" -a ! -path "/proc/*" -a ! -path "*/containerd/*" -a ! -path "*/kubelet/pods/*" -a ! -path "*/kubelet/plugins/*" -a ! -path "/sys/fs/cgroup/memory/*" -a ! -path "/var/*/private/*") # The value of this variable specifies the owner that will be set for unowned files and directories. rhel9cis_unowned_owner: root +# The value of this variable specifies the group that will be set for ungrouped files and directories. rhel9cis_ungrouped_group: root # This variable is a toggle for enabling/disabling the automated # setting of an owner (specified in variable `rhel9cis_unowned_owner`) @@ -1336,17 +1472,28 @@ rhel9cis_ungrouped_group: root # Possible values are `true` and `false`. rhel9cis_ownership_adjust: true -## Control 7.1.13 +## Control 7.1.13 - Ensure SUID and SGID files are reviewed # This variable is a toggle for enabling/disabling the automated removal # of the SUID bit from all files on all mounts. # Possible values are `true` and `false`. rhel9cis_suid_sgid_adjust: false -## Control 7.1.11 - Ensure no world writable files exist -# Allow ansible to adjust world-writable files. False will just display world-writable files, True will remove world-writable. -rhel9cis_no_world_write_adjust: true +## Control 7.2.8 - Ensure local interactive user home directories are configured +# UID settings for interactive users +# 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 `rhel9cis_discover_int_uid` has +# been set to `true`. +min_int_uid: 1000 +# This variable sets the maximum number at which the search stops for UID +# Note that the value will be dynamically overwritten if variable `rhel9cis_discover_int_uid` has +# been set to `true`. +max_int_uid: 65533 -## Control 7.2.9 -# This allows ansible to alter the dot files as per rule if found -# When set to true this will align with benchmark - can impact a running system if not tested sufficiently +## Control 7.2.9 - Ensure local interactive user dot files access is configured +# This variable is a toggle foe enabling/disabling the automated modification of +# permissions on dot files. +# Possible values are `true` and `false` +# This setting can impact a running system if not tested sufficiently rhel9cis_dotperm_ansiblemanaged: false From a55675089457ad2c34820ac0c83888f1f6f8c933 Mon Sep 17 00:00:00 2001 From: "Tomuta, Diana Maria (T CST SCC-RO)" Date: Thu, 3 Jul 2025 13:03:08 +0300 Subject: [PATCH 070/139] Fixing issue https://code.siemens.com/infosec-pss-gov/security-crafter-baseline-automations/ansible-lockdown/rhel9-cis/-/issues/41. Signed-off-by: Diana-Maria Dumitru --- tasks/section_5/cis_5.4.2.x.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tasks/section_5/cis_5.4.2.x.yml b/tasks/section_5/cis_5.4.2.x.yml index 37a4e11..9a93947 100644 --- a/tasks/section_5/cis_5.4.2.x.yml +++ b/tasks/section_5/cis_5.4.2.x.yml @@ -135,6 +135,22 @@ ansible.builtin.set_fact: root_paths: "{{ discovered_root_paths.stdout }}" + - name: "5.4.2.5 | AUDIT | Ensure root PATH Integrity | Check for presence of non-dirs" + ansible.builtin.stat: + path: "{{ item }}" + loop: "{{ discovered_root_paths_split.stdout_lines }}" + register: paths_stat + + - name: "5.4.2.5 | AUDIT | Ensure root PATH Integrity | Create dirs for some paths that are not dirs" + ansible.builtin.file: + path: "{{ item.item }}" + state: directory + owner: root + group: root + mode: 'go-w' + loop: "{{ paths_stat.results }}" + when: not item.stat.exists + - name: "5.4.2.5 | AUDIT | Ensure root PATH Integrity | Check for empty dirs" when: discovered_root_paths is defined ansible.builtin.shell: 'echo {{ root_paths }} | grep -q "::" && echo "roots path contains a empty directory (::)"' From 778877f3f3f14317ab7df650634010941b6e5bb3 Mon Sep 17 00:00:00 2001 From: "Tomuta, Diana Maria (T CST SCC-RO)" Date: Fri, 4 Jul 2025 10:50:45 +0300 Subject: [PATCH 071/139] Small fixes. Signed-off-by: Diana-Maria Dumitru --- defaults/main.yml | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 71fe932..4f3bdb7 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,5 +1,4 @@ --- - # defaults file for rhel9-cis # WARNING: # These values may be overridden by other vars-setting options(e.g. like the below 'container_vars_file'), as explained here: @@ -13,7 +12,7 @@ os_check: true ## 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 -rhel9cis_disruption_high: false +rhel9cis_disruption_high: true ## Switching on/off specific baseline sections # These variables govern whether the tasks of a particular section are to be executed when running the role. @@ -68,10 +67,17 @@ change_requires_reboot: false ### Goss is required on the remote host ### ### vars/auditd.yml for other settings ### -# Allow audit to setup the requirements including installing git (if option chosen and downloading and adding goss binary to system) +## Audit setup +# Audits are carried out using Goss. This variable +# determines whether execution of the role prepares for auditing +# by installing the required binary. setup_audit: false -# enable audits to run - this runs the audit and get the latest content +## Enable audits to run - this runs the audit and get the latest content +# This variable governs whether the audit using the +# separately maintained audit role using Goss +# is carried out. +# This runs the audit and gets the latest content run_audit: false # Run heavy tests - some tests can have more impact on a system enabling these can have greater impact on a system audit_run_heavy_tests: true @@ -95,8 +101,16 @@ get_audit_binary_method: download ## e.g copy from ansible control node to remote host audit_bin_copy_location: /some/accessible/path -# how to get audit files onto host options +## How to retrieve the audit role +# The role for auditing is maintained separately. +# This variable specifies the method of how to get the audit role # options are git/copy/archive/get_url other e.g. if you wish to run from already downloaded conf +# onto the system. The options are as follows: +# - 'git': clone audit content from GitHub REPOSITORY, set up via `audit_file_git` var, and +# VERSION(e.g. branch, tag name), set up via `audit_git_version` var. +# - 'copy': copy from path as specified in variable `audit_conf_copy`. +# - 'archive': same as 'copy', only that the specified filepath needs to be unpacked. +# - 'get_url': Download from url as specified in variable `audit_files_url` audit_content: git # If using either archive, copy, get_url: @@ -311,7 +325,7 @@ rhel9cis_rule_3_3_11: true # Firewall utility rhel9cis_rule_4_1_1: true rhel9cis_rule_4_1_2: true -## Configure firewalld +# Configure firewalld rhel9cis_rule_4_2_1: true rhel9cis_rule_4_2_2: true # Configure nftables From 21fd466ec65f28f52be2fdfd17c0ab21aabf94b9 Mon Sep 17 00:00:00 2001 From: "Tomuta, Diana Maria (T CST SCC-RO)" Date: Fri, 4 Jul 2025 11:58:08 +0300 Subject: [PATCH 072/139] Small fixes part 2. Signed-off-by: Diana-Maria Dumitru --- defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults/main.yml b/defaults/main.yml index 4f3bdb7..ca37f6f 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1232,7 +1232,7 @@ rhel9cis_aide_cron: # This variable governs which logging service should be used, choosing between 'rsyslog' # or 'journald'(CIS recommendation) will trigger the execution of the associated subsection, as the-best # practices are written wholly independent of each other. -rhel9cis_syslog: journald +rhel9cis_syslog: rsyslog ## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy # Current variable configures the max amount of disk space the logs will use(thus, journal files From dfd5eb9a922b81f987e1666423b3ff236d7b6c75 Mon Sep 17 00:00:00 2001 From: "Tomuta, Diana Maria (T CST SCC-RO)" Date: Fri, 4 Jul 2025 13:44:46 +0300 Subject: [PATCH 073/139] Small fixes part 3. Signed-off-by: Diana-Maria Dumitru --- defaults/main.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index ca37f6f..933efb7 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -604,7 +604,6 @@ 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 # - 1.7.2 - Ensure local login warning banner is configured properly @@ -976,7 +975,6 @@ rhel9cis_authselect_pkg_update: false # NOTE the risks if system is using SSSD ## Controls 5.3.x - # This variable configures the name of the custom profile to be created and selected. # To be changed from default - cis_example_profile. This setting needs to be adjusted # in order to minimise risk. @@ -1110,7 +1108,7 @@ rhel9cis_force_user_mindays: false # This variable governs, how many days before a password expires, the user will be warned. # CIS requires a value of at least 7. rhel9cis_pass_warn_age: 7 -#The following variable allows the forcing of number of days before warning users of password expiry +# The following variable allows the forcing of number of days before warning users of password expiry # This can break current connecting user access rhel9cis_force_user_warnage: false From d25b472283950e2ff5b29aa4c1951323d574c0aa Mon Sep 17 00:00:00 2001 From: "Tomuta, Diana Maria (T CST SCC-RO)" Date: Fri, 4 Jul 2025 13:50:05 +0300 Subject: [PATCH 074/139] Fixing order of configs. Signed-off-by: Diana-Maria Dumitru --- templates/audit/99_auditd.rules.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/audit/99_auditd.rules.j2 b/templates/audit/99_auditd.rules.j2 index 6c852e3..4fa4516 100644 --- a/templates/audit/99_auditd.rules.j2 +++ b/templates/audit/99_auditd.rules.j2 @@ -56,9 +56,9 @@ -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/hostname -p wa -k system-locale -w /etc/NetworkManager -p wa -k system-locale {% endif %} {% if rhel9cis_rule_6_3_3_6 %} From 4329591c906d5301e2ecd5155309b820ea9d181a Mon Sep 17 00:00:00 2001 From: "Tomuta, Diana Maria (T CST SCC-RO)" Date: Tue, 8 Jul 2025 09:37:29 +0300 Subject: [PATCH 075/139] Fixing inconsistencies between rule ids in title, tags and when. Signed-off-by: Diana-Maria Dumitru --- tasks/section_1/cis_1.1.2.6.x.yml | 2 +- tasks/section_1/cis_1.1.2.7.x.yml | 2 +- tasks/section_3/cis_3.3.x.yml | 4 ++-- tasks/section_5/cis_5.4.2.x.yml | 2 +- tasks/section_6/cis_6.3.4.x.yml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tasks/section_1/cis_1.1.2.6.x.yml b/tasks/section_1/cis_1.1.2.6.x.yml index 765de3d..b27e4cc 100644 --- a/tasks/section_1/cis_1.1.2.6.x.yml +++ b/tasks/section_1/cis_1.1.2.6.x.yml @@ -1,6 +1,6 @@ --- -- name: "1/.1 | PATCH | Ensure /var/log is a separate partition" +- name: "1.1.2.6.1 | PATCH | Ensure /var/log is a separate partition" when: - rhel9cis_rule_1_1_2_6_1 - required_mount not in prelim_mount_names diff --git a/tasks/section_1/cis_1.1.2.7.x.yml b/tasks/section_1/cis_1.1.2.7.x.yml index 2dc5939..b4513dd 100644 --- a/tasks/section_1/cis_1.1.2.7.x.yml +++ b/tasks/section_1/cis_1.1.2.7.x.yml @@ -1,6 +1,6 @@ --- -- name: "1/.1 | PATCH | Ensure /var/log/audit is a separate partition" +- name: "1.1.2.7.1 | PATCH | Ensure /var/log/audit is a separate partition" when: - rhel9cis_rule_1_1_2_7_1 - required_mount not in prelim_mount_names diff --git a/tasks/section_3/cis_3.3.x.yml b/tasks/section_3/cis_3.3.x.yml index 123928e..0281f12 100644 --- a/tasks/section_3/cis_3.3.x.yml +++ b/tasks/section_3/cis_3.3.x.yml @@ -240,12 +240,12 @@ - rule_3.3.9 - NIST800-53R5_AU-3 block: - - name: "3.3.4 | PATCH | Ensure suspicious packets are logged | Set Fact" + - name: "3.3.9 | PATCH | Ensure suspicious packets are logged | Set Fact" ansible.builtin.set_fact: rhel9cis_sysctl_update: true rhel9cis_flush_ipv4_route: true - - name: "3.3.4 | PATCH | Ensure suspicious packets are logged" + - name: "3.3.9 | PATCH | Ensure suspicious packets are logged" ansible.builtin.debug: msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf" diff --git a/tasks/section_5/cis_5.4.2.x.yml b/tasks/section_5/cis_5.4.2.x.yml index 37a4e11..867e1af 100644 --- a/tasks/section_5/cis_5.4.2.x.yml +++ b/tasks/section_5/cis_5.4.2.x.yml @@ -61,7 +61,7 @@ - level1-server - level1-workstation - patch - - rule_5.4.2.2 + - rule_5.4.2.3 - user - system - NIST800-53R5_CM-1 diff --git a/tasks/section_6/cis_6.3.4.x.yml b/tasks/section_6/cis_6.3.4.x.yml index 74de70a..b044abc 100644 --- a/tasks/section_6/cis_6.3.4.x.yml +++ b/tasks/section_6/cis_6.3.4.x.yml @@ -27,9 +27,9 @@ - level2-workstation - patch - auditd - - rule_6.3.4.1 - rule_6.3.4.2 - rule_6.3.4.3 + - rule_6.3.4.4 - NIST800-53R5_AU-3 ansible.builtin.file: path: "{{ prelim_auditd_logfile.stdout }}" From b182abf2aad5e2a7df4d8a6bd449dc93cdbd631c Mon Sep 17 00:00:00 2001 From: "Tomuta, Diana Maria (T CST SCC-RO)" Date: Tue, 8 Jul 2025 16:38:12 +0300 Subject: [PATCH 076/139] Fixing inconsistencies for importing tasks from section 1. Signed-off-by: Diana-Maria Dumitru --- tasks/section_1/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_1/main.yml b/tasks/section_1/main.yml index 5d99f48..c540fab 100644 --- a/tasks/section_1/main.yml +++ b/tasks/section_1/main.yml @@ -41,7 +41,7 @@ file: cis_1.2.2.x.yml - name: "SECTION | 1.3.1 | Configure SELinux" - ansible.builtin.include_tasks: + ansible.builtin.import_tasks: file: cis_1.3.1.x.yml - name: "SECTION | 1.4 | Configure Bootloader" From 76a680bb5926de2cdff49319e3efeb5cae2fdc06 Mon Sep 17 00:00:00 2001 From: "Tomuta, Diana Maria (T CST SCC-RO)" Date: Wed, 9 Jul 2025 12:13:45 +0300 Subject: [PATCH 077/139] Fixing minor documentation issues. Signed-off-by: Diana-Maria Dumitru --- defaults/main.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 933efb7..1457d12 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -35,6 +35,7 @@ rhel9cis_level_2: true # Create managed not custom local_facts files create_benchmark_facts: true +# The path where the ansible facts file is created if audit facts are not present ansible_facts_path: /etc/ansible/facts.d ## Section 1.6 - Mandatory Access Control @@ -776,7 +777,7 @@ rhel9cis_ftp_client: false rhel9cis_openldap_clients_required: false ## Control - 2.2.3 - Ensure nis client is not installed # Set this variable to `true` to keep package `nis`(`ypbind`); otherwise, the package is uninstalled. -rhel9cis_ypbind_required: false # Same package as NIS server +rhel9cis_ypbind_required: false ## Control - 2.2.4 - Ensure telnet client is not installed # Set this variable to `true` to keep package `telnet`; otherwise, the package is uninstalled. rhel9cis_telnet_required: false @@ -827,7 +828,7 @@ rhel9cis_flush_ipv6_route: false # 1) either 'firewalld' # 2) or 'nftables' #### Some control allow for services to be removed or masked -#### The options are under each heading +#### The options are under each heading: #### absent = remove the package #### masked = leave package if installed and mask the service rhel9cis_firewall: firewalld @@ -1223,7 +1224,6 @@ rhel9cis_aide_cron: aide_weekday: '*' ## Preferred method of logging -## Whether rsyslog or journald preferred method for local logging ## Controls 6.2.1.x | Configure systemd-journald service ## Controls 6.2.2.x | Configured journald ## Controls 6.2.3.x | Configure rsyslog @@ -1327,7 +1327,7 @@ rhel9cis_remote_log_retrycount: 100 # of rsyslog forwarding must be enabled('rhel9cis_remote_log_server: true'). rhel9cis_remote_log_queuesize: 1000 -# Control 6.2.3.7 - Ensure rsyslog is not configured to receive logs from a remote client +## Control 6.2.3.7 - Ensure rsyslog is not configured to receive logs from a remote client # This variable expresses whether the system is used as a log server or not. If set to: # - 'false', current system will act as a log CLIENT, thus it should NOT receive data from other hosts. # - 'true', current system will act as a log SERVER, enabling centralised log management(by protecting log integrity @@ -1447,7 +1447,7 @@ rhel9cis_auditd_admin_space_left_action: halt # for auditd should be used by the role. rhel9cis_auditd_extra_conf_usage: false -# 6.3.3.x allow exceptions for UID in auditd config +## Controls 6.3.3.x allow exceptions for UID in auditd config ## Advanced option found in auditd post # This variable governs if defining user exceptions for auditd logging is acceptable. rhel9cis_allow_auditd_uid_user_exclusions: false @@ -1504,7 +1504,7 @@ min_int_uid: 1000 max_int_uid: 65533 ## Control 7.2.9 - Ensure local interactive user dot files access is configured -# This variable is a toggle foe enabling/disabling the automated modification of +# This variable is a toggle for enabling/disabling the automated modification of # permissions on dot files. # Possible values are `true` and `false` # This setting can impact a running system if not tested sufficiently From ad8e73c3ee02a395ff490c8e4982360561b2b62f Mon Sep 17 00:00:00 2001 From: "Tomuta, Diana Maria (T CST SCC-RO)" Date: Wed, 9 Jul 2025 13:28:33 +0300 Subject: [PATCH 078/139] Fixing minor documentation issues part 2. Signed-off-by: Diana-Maria Dumitru --- defaults/main.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 1457d12..3e5a0eb 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -92,9 +92,12 @@ fetch_audit_files: false audit_capture_files_dir: /some/location to copy to on control node ############################# -# How to retrieve audit binary -# Options are copy or download - detailed settings at the bottom of this file -# you will need to access to either github or the file already downloaded +## How to retrieve audit binary(Goss) +# Options are 'copy' or 'download' - detailed settings at the bottom of this file +# - if 'copy': +# - the filepath mentioned via the below 'audit_bin_copy_location' var will be used to access already downloaded Goss +# - if 'download': +# - the GitHub Goss-releases URL will be used for a fresh-download, via 'audit_bin_url' and 'audit_pkg_arch_name' vars get_audit_binary_method: download ## if get_audit_binary_method - copy the following needs to be updated for your environment From f90e896b0c736de908380248b58b35164149ff52 Mon Sep 17 00:00:00 2001 From: "Tomuta, Diana Maria (T CST SCC-RO)" Date: Wed, 9 Jul 2025 14:21:19 +0300 Subject: [PATCH 079/139] Fixing minor documentation issues part 3. Signed-off-by: Diana-Maria Dumitru --- defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults/main.yml b/defaults/main.yml index 3e5a0eb..d50aecf 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1416,7 +1416,7 @@ rhel9cis_auditd_disk_full_action: halt # when an error is detected on the partition that holds the audit log files. rhel9cis_auditd_disk_error_action: syslog -# Control 6.3.2.4 - Ensure system warns when audit logs are low on space +## Control 6.3.2.4 - Ensure system warns when audit logs are low on space # This variable tells the system what action to take when the system has detected # that it is starting to get low on disk space. # The options for setting this variable are as follows: From b62a414abb71466f4e50eb41a7d7415fd8e057fe Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:28:55 +0000 Subject: [PATCH 080/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/gitleaks/gitleaks: v8.27.2 → v8.28.0](https://github.com/gitleaks/gitleaks/compare/v8.27.2...v8.28.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a4d0a42..dec2081 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: - id: detect-secrets - repo: https://github.com/gitleaks/gitleaks - rev: v8.27.2 + rev: v8.28.0 hooks: - id: gitleaks From 876e261d1f311a2add28b0c50b265649f17ebb97 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 4 Aug 2025 09:53:09 +0100 Subject: [PATCH 081/139] fixed issues for permissions when using fetch thanks to @steve-hayes Signed-off-by: Mark Bolwell --- tasks/pre_remediation_audit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index 61959fa..250f987 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -70,7 +70,7 @@ mode: 'go-rwx' - name: Pre Audit | Run pre_remediation audit {{ benchmark }} # noqa name[template] - ansible.builtin.command: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ pre_audit_outfile }} -g \"{{ group_names }}\"" # noqa yaml[line-length] + ansible.builtin.shell: "umask 0022 && {{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ pre_audit_outfile }} -g \"{{ group_names }}\"" # noqa yaml[line-length] changed_when: true environment: AUDIT_BIN: "{{ audit_bin }}" From 4b62f0fc3518352b1d0d36758f7945bfa8fa05b9 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 4 Aug 2025 09:56:30 +0100 Subject: [PATCH 082/139] Updated post steps inline with pre steps for file permissions Signed-off-by: Mark Bolwell --- tasks/post_remediation_audit.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tasks/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index 68e7035..357a23f 100644 --- a/tasks/post_remediation_audit.yml +++ b/tasks/post_remediation_audit.yml @@ -1,22 +1,13 @@ --- - name: Post Audit | Run post_remediation {{ benchmark }} audit # noqa name[template] - ansible.builtin.command: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ post_audit_outfile }} -g \"{{ group_names }}\"" + ansible.builtin.shell: "umask 0022 && {{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ post_audit_outfile }} -g \"{{ group_names }}\"" # noqa yaml[line-length] changed_when: true environment: AUDIT_BIN: "{{ audit_bin }}" AUDIT_CONTENT_LOCATION: "{{ audit_conf_dest | default('/opt') }}" AUDIT_FILE: goss.yml -- name: Post Audit | ensure audit files readable by users - ansible.builtin.file: - path: "{{ item }}" - mode: '0644' - state: file - loop: - - "{{ post_audit_outfile }}" - - "{{ pre_audit_outfile }}" - - name: Post Audit | Capture audit data if json format when: audit_format == "json" block: From cfbbb3339a988f65512c180bfe6667f90ce13c53 Mon Sep 17 00:00:00 2001 From: Michael Hicks Date: Mon, 11 Aug 2025 15:12:17 -0700 Subject: [PATCH 083/139] renames 3 uses of ansible.builtin.systemd_service to ansible.builtin.systemd to maintain ansible 2.12+ compat. Fixes #379 Signed-off-by: Michael Hicks --- handlers/main.yml | 2 +- tasks/section_6/cis_6.1.x.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/handlers/main.yml b/handlers/main.yml index 1894300..1ef6ccf 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -263,7 +263,7 @@ listen: Restart auditd - name: Start auditd process - ansible.builtin.systemd_service: + ansible.builtin.systemd: name: auditd state: started listen: Restart auditd diff --git a/tasks/section_6/cis_6.1.x.yml b/tasks/section_6/cis_6.1.x.yml index 1db531b..a29118a 100644 --- a/tasks/section_6/cis_6.1.x.yml +++ b/tasks/section_6/cis_6.1.x.yml @@ -91,13 +91,13 @@ - name: "6.1.2 | PATCH | Ensure filesystem integrity is regularly checked | aide service" when: rhel9cis_aide_scan == "timer" - ansible.builtin.systemd_service: + ansible.builtin.systemd: name: aidecheck.service enabled: true - name: "6.1.2 | PATCH | Ensure filesystem integrity is regularly checked | aide service" when: rhel9cis_aide_scan == "timer" - ansible.builtin.systemd_service: + ansible.builtin.systemd: name: aidecheck.timer state: started enabled: true From 553f18e9926bb6e6ba7772e470375b44c709bdf5 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 15 Aug 2025 15:13:33 +0100 Subject: [PATCH 084/139] updated pre-commit-hooks version Signed-off-by: Mark Bolwell --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dec2081..aa27650 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ ci: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: # Safety - id: detect-aws-credentials From b21569c62dd7a15c269c9c928a2c61c4c5a81d9b Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 15 Aug 2025 16:00:36 +0100 Subject: [PATCH 085/139] added update for gdm and giu packages Signed-off-by: Mark Bolwell --- defaults/main.yml | 2 ++ tasks/section_1/main.yml | 1 + 2 files changed, 3 insertions(+) diff --git a/defaults/main.yml b/defaults/main.yml index d50aecf..98efbba 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -617,6 +617,8 @@ rhel9cis_warning_banner: Authorized users only. All activity may be monitored an # End Banner ## Control 1.8.x - Settings for GDM +# do not run Control 1.8.x if using a display manager different than gdm +rhel10cis_display_manager: "gdm" # This variable governs whether rules dealing with GUI specific packages(and/or their settings) should # be executed either to: # - secure GDM, if GUI is needed('rhel9cis_gui: true') diff --git a/tasks/section_1/main.yml b/tasks/section_1/main.yml index c540fab..29687b3 100644 --- a/tasks/section_1/main.yml +++ b/tasks/section_1/main.yml @@ -61,5 +61,6 @@ file: cis_1.7.x.yml - name: "SECTION | 1.8 | Gnome Display Manager" + when: rhel10cis_display_manager == 'gdm' ansible.builtin.import_tasks: file: cis_1.8.x.yml From fd2bfb7437215591945e4c0261f651f8e5eb04b0 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 15 Aug 2025 16:03:11 +0100 Subject: [PATCH 086/139] improved prelim tests for 5.2.4 Signed-off-by: Mark Bolwell --- tasks/main.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index 460acc8..191ea25 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -93,11 +93,14 @@ block: - name: "Check password set for {{ ansible_env.SUDO_USER }} | Assert local password set" # noqa name[template] ansible.builtin.assert: - that: - - prelim_ansible_user_password_set.stdout | length != 0 - - prelim_ansible_user_password_set.stdout != "!!" - fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_env.SUDO_USER }} has no password set - It can break access" - success_msg: "You have a password set for the {{ ansible_env.SUDO_USER }} user" + that: | + ( + ((prelim_ansible_user_password_set.stdout | length != 0) and (prelim_ansible_user_password_set.stdout != "!!" )) + or + (ansible_env.SUDO_USER in rhel10cis_sudoers_exclude_nopasswd_list) + ) + fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_env.SUDO_USER }} has no password set or or the user is not included in the exception list for rule 5.2.4 - It can break access" + success_msg: "You have a password set for the {{ ansible_env.SUDO_USER }} user or the user is included in the exception list for rule 5.2.4" - name: "Check account is not locked for {{ ansible_env.SUDO_USER }} | Assert local account not locked" # noqa name[template] ansible.builtin.assert: From cddad90a236347d6e20841488371363809bd2b99 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 15 Aug 2025 16:04:07 +0100 Subject: [PATCH 087/139] enabled different locale characters in password check 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 191ea25..83aff0c 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -134,7 +134,7 @@ - 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: LC_ALL=C 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 From 7428f269e74586716c11bb9404c240cd9cc39007 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 15 Aug 2025 16:09:51 +0100 Subject: [PATCH 088/139] changed rsyslog to insert before line134 Signed-off-by: Mark Bolwell --- tasks/section_6/cis_6.2.3.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_6/cis_6.2.3.x.yml b/tasks/section_6/cis_6.2.3.x.yml index 9d26acf..eaa3bd1 100644 --- a/tasks/section_6/cis_6.2.3.x.yml +++ b/tasks/section_6/cis_6.2.3.x.yml @@ -131,7 +131,7 @@ *.=warning;*.=err -/var/log/warn *.crit /var/log/warn *.*;mail.none;news.none /var/log/messages - insertafter: '#### RULES ####' + insertbefore: '# ### sample forwarding rule ###' notify: Restart rsyslog - name: "6.2.3.5 | PATCH | Ensure logging is configured | Local log settings" From f0fb7011226b5f25f34766bbe07f71eeae5279ea Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 15 Aug 2025 16:10:37 +0100 Subject: [PATCH 089/139] updated var naming on 5.4.2.5 Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.4.2.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/section_5/cis_5.4.2.x.yml b/tasks/section_5/cis_5.4.2.x.yml index b3dd7d9..b291cc2 100644 --- a/tasks/section_5/cis_5.4.2.x.yml +++ b/tasks/section_5/cis_5.4.2.x.yml @@ -139,7 +139,7 @@ ansible.builtin.stat: path: "{{ item }}" loop: "{{ discovered_root_paths_split.stdout_lines }}" - register: paths_stat + register: discovered_root_paths_stat - name: "5.4.2.5 | AUDIT | Ensure root PATH Integrity | Create dirs for some paths that are not dirs" ansible.builtin.file: @@ -148,7 +148,7 @@ owner: root group: root mode: 'go-w' - loop: "{{ paths_stat.results }}" + loop: "{{ discovered_root_paths_stat.results }}" when: not item.stat.exists - name: "5.4.2.5 | AUDIT | Ensure root PATH Integrity | Check for empty dirs" From f8d95213671abb8a0bfc39a6144380f1e22e8c26 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 15 Aug 2025 16:19:07 +0100 Subject: [PATCH 090/139] updated Signed-off-by: Mark Bolwell --- Changelog.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Changelog.md b/Changelog.md index b6db646..68ba2d4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,12 @@ # Changes to rhel9CIS +## 2.0.3 - Based on CIS v2.0.0 + +- addressed issue 371 thanks to @bgro and kodebach +- addressed issue 350 thanks to @chrispipo +- addressed issue 364 thanks to @polski-g +- pre-commit update + ## 2.0.2 - Based on CIS v2.0.0 - Update to audit_only to allow fetching results From 7af8f5fe2426aba27d477e40f22c1df8cf658b06 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Aug 2025 17:29:58 +0000 Subject: [PATCH 091/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/ansible-community/ansible-lint: v25.6.1 → v25.8.2](https://github.com/ansible-community/ansible-lint/compare/v25.6.1...v25.8.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index aa27650..4ae1ee6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,7 +46,7 @@ repos: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.6.1 + rev: v25.8.2 hooks: - id: ansible-lint name: Ansible-lint From 88507f95166a0be477f87df1c71df15aa48ac489 Mon Sep 17 00:00:00 2001 From: polski-g Date: Thu, 28 Aug 2025 13:15:29 -0400 Subject: [PATCH 092/139] 5.4.1.1: shell command should run in check_mode Signed-off-by: polski-g --- tasks/section_5/cis_5.4.1.x.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/section_5/cis_5.4.1.x.yml b/tasks/section_5/cis_5.4.1.x.yml index 7fcfb0b..58cd936 100644 --- a/tasks/section_5/cis_5.4.1.x.yml +++ b/tasks/section_5/cis_5.4.1.x.yml @@ -24,6 +24,7 @@ ansible.builtin.shell: "awk -F: '(/^[^:]+:[^!*]/ && ($5> {{ rhel9cis_pass_max_days }} || $5< {{ rhel9cis_pass_max_days }} || $5 == -1)){print $1}' /etc/shadow" changed_when: false failed_when: false + check_mode: false register: discovered_max_days - name: "5.4.1.1 | PATCH | Ensure password expiration is 365 days or less | Set existing users PASS_MAX_DAYS" From de7555aa1045fb30caeb292f34d74a9ad8e69920 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Tue, 2 Sep 2025 17:14:30 -0400 Subject: [PATCH 093/139] Update Changelog with fixes Signed-off-by: Frederick Witty --- Changelog.md | 2 +- tasks/prelim.yml | 20 +++++++------------- tasks/section_1/cis_1.6.x.yml | 5 +++-- tasks/section_4/cis_4.3.x.yml | 2 +- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/Changelog.md b/Changelog.md index 68ba2d4..af7476e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,7 +1,7 @@ # Changes to rhel9CIS ## 2.0.3 - Based on CIS v2.0.0 - +- update command to shell module on tasks - addressed issue 371 thanks to @bgro and kodebach - addressed issue 350 thanks to @chrispipo - addressed issue 364 thanks to @polski-g diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 715b0cb..bd69172 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -167,6 +167,7 @@ current_crypto_module: "{{ prelim_system_wide_crypto_policy.stdout.split(':')[1] }}" - name: "PRELIM | AUDIT | Set facts based on boot type" + tags: always block: - name: "PRELIM | AUDIT | Check whether machine is UEFI-based" ansible.builtin.stat: @@ -185,17 +186,14 @@ 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 - tags: - - always + when: rhel9cis_gui + tags: always ansible.builtin.package: name: dconf state: present @@ -204,8 +202,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 @@ -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: prelim_sshd_50_redhat_file @@ -361,7 +356,6 @@ prelim_max_int_uid: "{{ prelim_uid_max_id.stdout | default(max_int_uid) }}" - name: "PRELIM | AUDIT | Gather the package facts after prelim" - tags: - - always + tags: always ansible.builtin.package_facts: manager: auto diff --git a/tasks/section_1/cis_1.6.x.yml b/tasks/section_1/cis_1.6.x.yml index c418324..0530645 100644 --- a/tasks/section_1/cis_1.6.x.yml +++ b/tasks/section_1/cis_1.6.x.yml @@ -21,12 +21,14 @@ tags: - level1-server - level1-workstation + - sshd - automated - patch - rule_1.6.2 - NIST800-53R5_SC-8 - NIST800-53R5_IA-5 - - NIST800-53R5_AC-17- NIST800-53R5_SC-6 + - NIST800-53R5_AC-17 + - NIST800-53R5_SC-6 ansible.builtin.lineinfile: path: /etc/sysconfig/sshd regexp: ^CRYPTO_POLICY\s*= @@ -76,7 +78,6 @@ - rule_1.6.4 - NIST800-53R5_SC-6 block: - - name: "1.6.4 | PATCH | Ensure system wide crypto policy disables macs less than 128 bits | Add submodule exclusion" ansible.builtin.template: src: etc/crypto-policies/policies/modules/NO-WEAKMAC.pmod.j2 diff --git a/tasks/section_4/cis_4.3.x.yml b/tasks/section_4/cis_4.3.x.yml index 4e23998..4398df2 100644 --- a/tasks/section_4/cis_4.3.x.yml +++ b/tasks/section_4/cis_4.3.x.yml @@ -81,7 +81,7 @@ register: discovered_nftables_inconnectionrule - name: "4.3.2 | AUDIT | Ensure nftables established connections are configured | Gather outbound connection rules" - ansible.builtin.command: nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + ansible.builtin.shell: nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' changed_when: false failed_when: false register: discovered_nftables_outconnectionrule From 1c9c1b919c77e747bd1bfab5a414c849f10b3655 Mon Sep 17 00:00:00 2001 From: polski-g Date: Wed, 3 Sep 2025 09:55:00 -0400 Subject: [PATCH 094/139] 1.4.2: grep command should run in check_mode Signed-off-by: polski-g --- tasks/section_1/cis_1.4.x.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/section_1/cis_1.4.x.yml b/tasks/section_1/cis_1.4.x.yml index c6c3aac..5969dff 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -52,6 +52,7 @@ - name: "1.4.2 | AUDIT | Ensure permissions on bootloader config are configured | efi based system | capture current state" ansible.builtin.shell: grep "^[^#;]" /etc/fstab | grep '/boot/efi' | awk -F" " '{print $4}' changed_when: false + check_mode: false register: discovered_efi_fstab - name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured | efi based system | Build Options" From b0ec6c48208d026e59939c6b9750e033a6bc00d0 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Fri, 5 Sep 2025 16:24:11 -0400 Subject: [PATCH 095/139] Fix for #384, thank you @polski-g Signed-off-by: Frederick Witty --- Changelog.md | 1 + defaults/main.yml | 2 +- tasks/main.yml | 2 +- tasks/section_1/main.yml | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index af7476e..fb4a9f4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ # Changes to rhel9CIS ## 2.0.3 - Based on CIS v2.0.0 +- addressed issue #384 thank you @polski-g - update command to shell module on tasks - addressed issue 371 thanks to @bgro and kodebach - addressed issue 350 thanks to @chrispipo diff --git a/defaults/main.yml b/defaults/main.yml index 98efbba..344e195 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -618,7 +618,7 @@ rhel9cis_warning_banner: Authorized users only. All activity may be monitored an ## Control 1.8.x - Settings for GDM # do not run Control 1.8.x if using a display manager different than gdm -rhel10cis_display_manager: "gdm" +rhel9cis_display_manager: "gdm" # This variable governs whether rules dealing with GUI specific packages(and/or their settings) should # be executed either to: # - secure GDM, if GUI is needed('rhel9cis_gui: true') diff --git a/tasks/main.yml b/tasks/main.yml index 83aff0c..968debd 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -97,7 +97,7 @@ ( ((prelim_ansible_user_password_set.stdout | length != 0) and (prelim_ansible_user_password_set.stdout != "!!" )) or - (ansible_env.SUDO_USER in rhel10cis_sudoers_exclude_nopasswd_list) + (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 }} has no password set or or the user is not included in the exception list for rule 5.2.4 - It can break access" success_msg: "You have a password set for the {{ ansible_env.SUDO_USER }} user or the user is included in the exception list for rule 5.2.4" diff --git a/tasks/section_1/main.yml b/tasks/section_1/main.yml index 29687b3..fff557b 100644 --- a/tasks/section_1/main.yml +++ b/tasks/section_1/main.yml @@ -61,6 +61,6 @@ file: cis_1.7.x.yml - name: "SECTION | 1.8 | Gnome Display Manager" - when: rhel10cis_display_manager == 'gdm' + when: rhel9cis_display_manager == 'gdm' ansible.builtin.import_tasks: file: cis_1.8.x.yml From 413ccb96b7131dcc7c3427cf806758b7223b8038 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Fri, 5 Sep 2025 16:39:55 -0400 Subject: [PATCH 096/139] Update cryto policy based controls with improved logic Signed-off-by: Frederick Witty --- Changelog.md | 1 + defaults/main.yml | 1 + tasks/prelim.yml | 3 +-- tasks/section_1/cis_1.6.x.yml | 9 ++++++++- tasks/section_5/cis_5.1.x.yml | 3 +++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index fb4a9f4..252418c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ # Changes to rhel9CIS ## 2.0.3 - Based on CIS v2.0.0 +- improvment on crypto policy managed controls with var logic - addressed issue #384 thank you @polski-g - update command to shell module on tasks - addressed issue 371 thanks to @bgro and kodebach diff --git a/defaults/main.yml b/defaults/main.yml index 344e195..b829873 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -595,6 +595,7 @@ rhel9cis_set_boot_pass: true # -'FIPS': A level that conforms to the FIPS140-2 requirements rhel9cis_crypto_policy: 'DEFAULT' ## Controls 1.6.x and Controls 5.1.x +rhel9cis_crypto_policy_ansible_managed: true # 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, which currently are: diff --git a/tasks/prelim.yml b/tasks/prelim.yml index bd69172..1368993 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_crypto_policy_ansible_managed tags: - level1-server - level1-workstation diff --git a/tasks/section_1/cis_1.6.x.yml b/tasks/section_1/cis_1.6.x.yml index 0530645..6f3d6af 100644 --- a/tasks/section_1/cis_1.6.x.yml +++ b/tasks/section_1/cis_1.6.x.yml @@ -1,7 +1,9 @@ --- - name: "1.6.1 | AUDIT | Ensure system-wide crypto policy is not legacy" - when: rhel9cis_rule_1_6_1 + when: + - rhel9cis_rule_1_6_1 + - rhel9cis_crypto_policy_ansible_managed tags: - level1-server - level1-workstation @@ -39,6 +41,7 @@ when: - rhel9cis_rule_1_6_3 - "'NO-SHA1' not in rhel9cis_crypto_policy_module" + - rhel9cis_crypto_policy_ansible_managed tags: - level1-server - level1-workstation @@ -69,6 +72,7 @@ when: - rhel9cis_rule_1_6_4 - "'NO-WEAKMAC' not in rhel9cis_crypto_policy_module" + - rhel9cis_crypto_policy_ansible_managed tags: - level1-server - level1-workstation @@ -99,6 +103,7 @@ when: - rhel9cis_rule_1_6_5 - "'NO-SSHCBC' not in rhel9cis_crypto_policy_module" + - rhel9cis_crypto_policy_ansible_managed tags: - level1-server - level1-workstation @@ -129,6 +134,7 @@ when: - rhel9cis_rule_1_6_6 - "'NO-SSHWEAKCIPHERS' not in rhel9cis_crypto_policy_module" + - rhel9cis_crypto_policy_ansible_managed tags: - level1-server - level1-workstation @@ -159,6 +165,7 @@ when: - rhel9cis_rule_1_6_7 - "'NO-SSHETM' not in rhel9cis_crypto_policy_module" + - rhel9cis_crypto_policy_ansible_managed tags: - level1-server - level1-workstation diff --git a/tasks/section_5/cis_5.1.x.yml b/tasks/section_5/cis_5.1.x.yml index 3fd366c..ee384d3 100644 --- a/tasks/section_5/cis_5.1.x.yml +++ b/tasks/section_5/cis_5.1.x.yml @@ -80,6 +80,7 @@ when: - rhel9cis_rule_5_1_4 - "'NO-SSHWEAKCIPHERS' not in rhel9cis_crypto_policy_module" + - rhel9cis_crypto_policy_ansible_managed tags: - level1-server - level1-workstation @@ -108,6 +109,7 @@ when: - rhel9cis_rule_5_1_5 - "'NO-SHA1' not in rhel9cis_crypto_policy_module" + - rhel9cis_crypto_policy_ansible_managed tags: - level1-server - level1-workstation @@ -136,6 +138,7 @@ when: - rhel9cis_rule_5_1_6 - "'NO-SSHWEAKMACS' not in rhel9cis_crypto_policy_module" + - rhel9cis_crypto_policy_ansible_managed tags: - level1-server - level1-workstation From 2dfa9266a8ce9f0d08b210302c523e8b8058e0f8 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Mon, 8 Sep 2025 11:54:57 -0400 Subject: [PATCH 097/139] Update cryto policy var to standard Signed-off-by: Frederick Witty --- defaults/main.yml | 6 +++--- tasks/prelim.yml | 2 +- tasks/section_1/cis_1.6.x.yml | 12 ++++++------ tasks/section_5/cis_5.1.x.yml | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index b829873..c46ece3 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -586,7 +586,9 @@ rhel9cis_bootloader_password_hash: 'grub.pbkdf2.sha512.changethispassword' # pr # This variable governs whether a bootloader password should be set in '/boot/grub2/user.cfg' file. rhel9cis_set_boot_pass: true -## Controls 1.6.x +## Controls 1.6.x and Controls 5.1.x +# This variable governs if current Ansible role should manage system-wide crypto policy. +rhel9cis_crypto_policy_ansiblemanaged: true # This variable contains the value to be set as the system-wide crypto policy. Current rule enforces NOT USING # 'LEGACY' value(as it is less secure, it just ensures compatibility with legacy systems), therefore # possible values for this variable are, as explained by RedHat docs: @@ -594,8 +596,6 @@ rhel9cis_set_boot_pass: true # -'FUTURE': conservative security level that is believed to withstand any near-term future attacks # -'FIPS': A level that conforms to the FIPS140-2 requirements rhel9cis_crypto_policy: 'DEFAULT' -## Controls 1.6.x and Controls 5.1.x -rhel9cis_crypto_policy_ansible_managed: true # 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, which currently are: diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 1368993..7321267 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -136,7 +136,7 @@ register: prelim_systemd_coredump - name: "PRELIM | PATCH | Setup crypto-policy" - when: rhel9cis_crypto_policy_ansible_managed + when: rhel9cis_crypto_policy_ansiblemanaged tags: - level1-server - level1-workstation diff --git a/tasks/section_1/cis_1.6.x.yml b/tasks/section_1/cis_1.6.x.yml index 6f3d6af..8aace04 100644 --- a/tasks/section_1/cis_1.6.x.yml +++ b/tasks/section_1/cis_1.6.x.yml @@ -3,7 +3,7 @@ - name: "1.6.1 | AUDIT | Ensure system-wide crypto policy is not legacy" when: - rhel9cis_rule_1_6_1 - - rhel9cis_crypto_policy_ansible_managed + - rhel9cis_crypto_policy_ansiblemanaged tags: - level1-server - level1-workstation @@ -41,7 +41,7 @@ when: - rhel9cis_rule_1_6_3 - "'NO-SHA1' not in rhel9cis_crypto_policy_module" - - rhel9cis_crypto_policy_ansible_managed + - rhel9cis_crypto_policy_ansiblemanaged tags: - level1-server - level1-workstation @@ -72,7 +72,7 @@ when: - rhel9cis_rule_1_6_4 - "'NO-WEAKMAC' not in rhel9cis_crypto_policy_module" - - rhel9cis_crypto_policy_ansible_managed + - rhel9cis_crypto_policy_ansiblemanaged tags: - level1-server - level1-workstation @@ -103,7 +103,7 @@ when: - rhel9cis_rule_1_6_5 - "'NO-SSHCBC' not in rhel9cis_crypto_policy_module" - - rhel9cis_crypto_policy_ansible_managed + - rhel9cis_crypto_policy_ansiblemanaged tags: - level1-server - level1-workstation @@ -134,7 +134,7 @@ when: - rhel9cis_rule_1_6_6 - "'NO-SSHWEAKCIPHERS' not in rhel9cis_crypto_policy_module" - - rhel9cis_crypto_policy_ansible_managed + - rhel9cis_crypto_policy_ansiblemanaged tags: - level1-server - level1-workstation @@ -165,7 +165,7 @@ when: - rhel9cis_rule_1_6_7 - "'NO-SSHETM' not in rhel9cis_crypto_policy_module" - - rhel9cis_crypto_policy_ansible_managed + - rhel9cis_crypto_policy_ansiblemanaged tags: - level1-server - level1-workstation diff --git a/tasks/section_5/cis_5.1.x.yml b/tasks/section_5/cis_5.1.x.yml index ee384d3..42ca036 100644 --- a/tasks/section_5/cis_5.1.x.yml +++ b/tasks/section_5/cis_5.1.x.yml @@ -80,7 +80,7 @@ when: - rhel9cis_rule_5_1_4 - "'NO-SSHWEAKCIPHERS' not in rhel9cis_crypto_policy_module" - - rhel9cis_crypto_policy_ansible_managed + - rhel9cis_crypto_policy_ansiblemanaged tags: - level1-server - level1-workstation @@ -109,7 +109,7 @@ when: - rhel9cis_rule_5_1_5 - "'NO-SHA1' not in rhel9cis_crypto_policy_module" - - rhel9cis_crypto_policy_ansible_managed + - rhel9cis_crypto_policy_ansiblemanaged tags: - level1-server - level1-workstation @@ -138,7 +138,7 @@ when: - rhel9cis_rule_5_1_6 - "'NO-SSHWEAKMACS' not in rhel9cis_crypto_policy_module" - - rhel9cis_crypto_policy_ansible_managed + - rhel9cis_crypto_policy_ansiblemanaged tags: - level1-server - level1-workstation From 5794114b3e2207655b173a098c0b01bdc9a2474a Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Tue, 9 Sep 2025 15:12:01 -0400 Subject: [PATCH 098/139] Update prelim logic to address #382 Signed-off-by: Frederick Witty --- Changelog.md | 1 + tasks/main.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 252418c..9e27290 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ # Changes to rhel9CIS ## 2.0.3 - Based on CIS v2.0.0 +- addressed issue #382 to improve regex logic on 5.4.2.4 - improvment on crypto policy managed controls with var logic - addressed issue #384 thank you @polski-g - update command to shell module on tasks diff --git a/tasks/main.yml b/tasks/main.yml index 968debd..760ee1b 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -134,7 +134,7 @@ - rule_5.4.2.4 block: - name: "Ensure root password is set" - ansible.builtin.shell: LC_ALL=C passwd -S root | grep -E "(Password set, SHA512 crypt|Password locked)" + ansible.builtin.shell: LC_ALL=C passwd -S root | grep -E "(Password set|Password locked)" changed_when: false failed_when: prelim_root_passwd_set.rc not in [ 0, 1 ] register: prelim_root_passwd_set From e61cafb59be8b9c447fab098d9e3acb77de723dd Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Tue, 9 Sep 2025 15:59:30 -0400 Subject: [PATCH 099/139] addressed issue #387, thank you @fragglexarmy Signed-off-by: Frederick Witty --- Changelog.md | 1 + tasks/section_5/cis_5.4.1.x.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 9e27290..099c93d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ # Changes to rhel9CIS ## 2.0.3 - Based on CIS v2.0.0 +- addressed issue #387, thank you @fragglexarmy - addressed issue #382 to improve regex logic on 5.4.2.4 - improvment on crypto policy managed controls with var logic - addressed issue #384 thank you @polski-g diff --git a/tasks/section_5/cis_5.4.1.x.yml b/tasks/section_5/cis_5.4.1.x.yml index 7fcfb0b..3ea1c99 100644 --- a/tasks/section_5/cis_5.4.1.x.yml +++ b/tasks/section_5/cis_5.4.1.x.yml @@ -64,7 +64,7 @@ - rhel9cis_force_user_mindays ansible.builtin.user: name: "{{ item }}" - password_expire_max: "{{ rhel9cis_pass_min_days }}" + password_expire_min: "{{ rhel9cis_pass_min_days }}" loop: "{{ discovered_min_days.stdout_lines }}" - name: "5.4.1.3 | PATCH | Ensure password expiration warning days is configured" From d92ec8c5640319995ea3f33e3409f8c9d0230d75 Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Tue, 9 Sep 2025 16:31:14 -0400 Subject: [PATCH 100/139] typo fix Signed-off-by: Frederick Witty --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 099c93d..ec3d9aa 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,7 +3,7 @@ ## 2.0.3 - Based on CIS v2.0.0 - addressed issue #387, thank you @fragglexarmy - addressed issue #382 to improve regex logic on 5.4.2.4 -- improvment on crypto policy managed controls with var logic +- improvement on crypto policy managed controls with var logic - addressed issue #384 thank you @polski-g - update command to shell module on tasks - addressed issue 371 thanks to @bgro and kodebach From 392c3f90161f23b61a9eba5f4166073318a5f21e Mon Sep 17 00:00:00 2001 From: polski-g Date: Tue, 2 Sep 2025 12:15:45 -0400 Subject: [PATCH 101/139] Support section 5 modularization corrected trailing whitespace Signed-off-by: polski-g --- defaults/main.yml | 6 ++++ tasks/section_5/main.yml | 65 +++++++++++++++++++++++----------------- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 98efbba..ed3cf59 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -18,11 +18,17 @@ rhel9cis_disruption_high: true # These variables govern whether the tasks of a particular section are to be executed when running the role. # E.g: If you want to execute the tasks of Section 1 you should set the "_section1" variable to true. # If you do not want the tasks from that section to get executed you simply set the variable to "false". +# Some sections support sub-section modularization. The super-section and sub-section must both be true +# for the sub-section to execute. rhel9cis_section1: true rhel9cis_section2: true rhel9cis_section3: true rhel9cis_section4: true rhel9cis_section5: true +rhel9cis_section5_1: true +rhel9cis_section5_2: true +rhel9cis_section5_3: true +rhel9cis_section5_4: true rhel9cis_section6: true rhel9cis_section7: true diff --git a/tasks/section_5/main.yml b/tasks/section_5/main.yml index ae908ac..c4dacff 100644 --- a/tasks/section_5/main.yml +++ b/tasks/section_5/main.yml @@ -5,45 +5,56 @@ - name: "SECTION | 5.1 | Configure SSH Server" when: - "'openssh-server' in ansible_facts.packages" + - rhel9cis_section5_1 ansible.builtin.import_tasks: file: cis_5.1.x.yml - name: "SECTION | 5.2 | Configure privilege escalation" + when: + - - rhel9cis_section5_2 ansible.builtin.import_tasks: file: cis_5.2.x.yml -- name: "SECTION | 5.3.1.x | Configure PAM software packages" - ansible.builtin.import_tasks: - file: cis_5.3.1.x.yml +- name: "SECTION | 5.3" + when: + - rhel9cis_section5_3 + block: + - name: "SECTION | 5.3.1.x | Configure PAM software packages" + ansible.builtin.import_tasks: + file: cis_5.3.1.x.yml -- name: "SECTION | 5.3.2.x | Configure authselect" - ansible.builtin.import_tasks: - file: cis_5.3.2.x.yml + - name: "SECTION | 5.3.2.x | Configure authselect" + ansible.builtin.import_tasks: + file: cis_5.3.2.x.yml -- name: "SECTION | 5.3.3.1.x | Configure pam_faillock module" - ansible.builtin.import_tasks: - file: cis_5.3.3.1.x.yml + - name: "SECTION | 5.3.3.1.x | Configure pam_faillock module" + ansible.builtin.import_tasks: + file: cis_5.3.3.1.x.yml -- name: "SECTION | 5.3.3.2.x | Configure pam_pwquality module" - ansible.builtin.import_tasks: - file: cis_5.3.3.2.x.yml + - name: "SECTION | 5.3.3.2.x | Configure pam_pwquality module" + ansible.builtin.import_tasks: + file: cis_5.3.3.2.x.yml -- name: "SECTION | 5.3.3.3.x | Configure pam_pwhistory module" - ansible.builtin.import_tasks: - file: cis_5.3.3.3.x.yml + - name: "SECTION | 5.3.3.3.x | Configure pam_pwhistory module" + ansible.builtin.import_tasks: + file: cis_5.3.3.3.x.yml -- name: "SECTION | 5.3.3.4.x | Configure pam_unix module" - ansible.builtin.import_tasks: - file: cis_5.3.3.4.x.yml + - name: "SECTION | 5.3.3.4.x | Configure pam_unix module" + ansible.builtin.import_tasks: + file: cis_5.3.3.4.x.yml -- name: "SECTION | 5.4.1.x | Configure shadow password suite parameters" - ansible.builtin.import_tasks: - file: cis_5.4.1.x.yml +- name: "SECTION | 5.4" + when: + - rhel9cis_section5_4 + block: + - name: "SECTION | 5.4.1.x | Configure shadow password suite parameters" + ansible.builtin.import_tasks: + file: cis_5.4.1.x.yml -- name: "SECTION | 5.4.2.x | Configure root and system accounts and environment" - ansible.builtin.import_tasks: - file: cis_5.4.2.x.yml + - name: "SECTION | 5.4.2.x | Configure root and system accounts and environment" + ansible.builtin.import_tasks: + file: cis_5.4.2.x.yml -- name: "SECTION | 5.4.3.x | Configure user default environment" - ansible.builtin.import_tasks: - file: cis_5.4.3.x.yml + - name: "SECTION | 5.4.3.x | Configure user default environment" + ansible.builtin.import_tasks: + file: cis_5.4.3.x.yml From 2557470054c9d784bcda461299ee9f542865b7a8 Mon Sep 17 00:00:00 2001 From: polski-g Date: Thu, 28 Aug 2025 13:55:41 -0400 Subject: [PATCH 102/139] 5.3.2.2: fix regex failing to match whitespace Fixed yamllint (colons) issues Signed-off-by: polski-g --- tasks/section_5/cis_5.3.2.x.yml | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/tasks/section_5/cis_5.3.2.x.yml b/tasks/section_5/cis_5.3.2.x.yml index 5917019..6e1919c 100644 --- a/tasks/section_5/cis_5.3.2.x.yml +++ b/tasks/section_5/cis_5.3.2.x.yml @@ -91,9 +91,15 @@ insertafter: "{{ item.after | default(omit) }}" line: "{{ item.line }}" loop: - - { regexp: auth\s*required\s*pam_faillock.so preauth, after: auth\s*required\s*pam_env.so, line: "auth required pam_faillock.so preauth silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" } - - { regexp: auth\s*required\s*pam_faillock.so authfail, before: auth\s*required\s*pam_deny.so, line: "auth required pam_faillock.so authfail silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" } - - { regexp: account\s*required\s*pam_faillock.so, before: account\s*required\s*pam_unix.so, line: "account required pam_faillock.so" } + - regexp: "auth\\s+required\\s+pam_faillock.so\\s+preauth" + after: "auth\\s+required\\s+pam_env.so" # yamllint disable-line rule:colons + line: "auth required pam_faillock.so preauth silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" # yamllint disable-line rule:colons + - regexp: "auth\\s+required\\s+pam_faillock.so\\s+authfail" + before: "auth\\s+required\\s+pam_deny.so" + line: "auth required pam_faillock.so authfail silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" # yamllint disable-line rule:colons + - regexp: "account\\s+required\\s+pam_faillock.so" + before: "account\\s+required\\s+pam_unix.so" + line: "account required pam_faillock.so" # yamllint disable-line rule:colons - name: "5.3.2.2 | AUDIT | Ensure pam_faillock module is enabled | Add lines password-auth" when: not rhel9cis_allow_authselect_updates @@ -104,9 +110,15 @@ insertafter: "{{ item.after | default(omit) }}" line: "{{ item.line }}" loop: - - { regexp: auth\s*required\s*pam_faillock.so preauth, after: auth\s*required\s*pam_env.so, line: "auth required pam_faillock.so preauth silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" } - - { regexp: auth\s*required\s*pam_faillock.so authfail, before: auth\s*required\s*pam_deny.so, line: "auth required pam_faillock.so authfail silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" } - - { regexp: account\s*required\s*pam_faillock.so, before: account\s*required\s*pam_unix.so, line: "account required pam_faillock.so" } + - regexp: "auth\\s+required\\s+pam_faillock.so\\s+preauth" + after: "auth\\s+required\\s+pam_env.so" # yamllint disable-line rule:colons + line: "auth required pam_faillock.so preauth silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" # yamllint disable-line rule:colons + - regexp: "auth\\s+required\\s+pam_faillock.so\\s+authfail" + before: "auth\\s+required\\s+pam_deny.so" + line: "auth required pam_faillock.so authfail silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" # yamllint disable-line rule:colons + - regexp: "account\\s+required\\s+pam_faillock.so" + before: "account\\s+required\\s+pam_unix.so" + line: "account required pam_faillock.so" # yamllint disable-line rule:colons - name: "5.3.2.3 | PATCH | Ensure pam_pwquality module is enabled" when: From 03d42ba8ced44b8fe8e3f23b2d449753826c62b2 Mon Sep 17 00:00:00 2001 From: Danny Beuker Date: Mon, 22 Sep 2025 09:57:55 +0200 Subject: [PATCH 103/139] Suggestion for the missing assert parameter Signed-off-by: Danny Beuker --- tasks/pre_remediation_audit.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index 250f987..cf8d8c7 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -57,6 +57,7 @@ - name: Pre Audit Setup | If audit ensure goss is available when: not prelim_goss_available.stat.exists ansible.builtin.assert: + that: prelim_goss_available['stat']['exists'] == true msg: "Audit has been selected: unable to find goss binary at {{ audit_bin }}" - name: Pre Audit Setup | Copy ansible default vars values to test audit From 2c0b5134b15331ff375963f23749229ee15e16bb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Sep 2025 17:39:44 +0000 Subject: [PATCH 104/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/ansible-community/ansible-lint: v25.8.2 → v25.9.0](https://github.com/ansible-community/ansible-lint/compare/v25.8.2...v25.9.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4ae1ee6..7fd561a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,7 +46,7 @@ repos: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.8.2 + rev: v25.9.0 hooks: - id: ansible-lint name: Ansible-lint From d63f58972deb487e5119405d74b536aa58ab0e97 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 1 Oct 2025 10:32:24 +0100 Subject: [PATCH 105/139] fixed typo Signed-off-by: Mark Bolwell --- tasks/section_5/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_5/main.yml b/tasks/section_5/main.yml index c4dacff..09a2fdd 100644 --- a/tasks/section_5/main.yml +++ b/tasks/section_5/main.yml @@ -11,7 +11,7 @@ - name: "SECTION | 5.2 | Configure privilege escalation" when: - - - rhel9cis_section5_2 + - rhel9cis_section5_2 ansible.builtin.import_tasks: file: cis_5.2.x.yml From d2b371432eb6959cf2fb62def22434e5d2c06263 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 1 Oct 2025 10:32:52 +0100 Subject: [PATCH 106/139] issue #393 addressed thanks to @fragglexarmy Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.4.1.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_5/cis_5.4.1.x.yml b/tasks/section_5/cis_5.4.1.x.yml index ea6eb11..badca42 100644 --- a/tasks/section_5/cis_5.4.1.x.yml +++ b/tasks/section_5/cis_5.4.1.x.yml @@ -94,7 +94,7 @@ - discovered_warn_days.stdout_lines | length > 0 - item in prelim_interactive_users | map(attribute='username') | list - rhel9cis_force_user_warnage - ansible.builtin.command: "chage --warndays {{ rhel9cis_pass['warn_age'] }} {{ item }}" + ansible.builtin.command: "chage --warndays {{ rhel9cis_pass_warn_age }} {{ item }}" changed_when: true loop: "{{ discovered_warn_days.stdout_lines }}" From ed5942f4941c2e6331a9ae5f0444ba609e9e397e Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 1 Oct 2025 10:37:12 +0100 Subject: [PATCH 107/139] workflows updated Signed-off-by: Mark Bolwell --- .../workflows/devel_pipeline_validation.yml | 242 +++++++++--------- .../workflows/main_pipeline_validation.yml | 223 ++++++++-------- 2 files changed, 229 insertions(+), 236 deletions(-) diff --git a/.github/workflows/devel_pipeline_validation.yml b/.github/workflows/devel_pipeline_validation.yml index 10750a2..deac4d7 100644 --- a/.github/workflows/devel_pipeline_validation.yml +++ b/.github/workflows/devel_pipeline_validation.yml @@ -4,16 +4,16 @@ on: # yamllint disable-line rule:truthy pull_request_target: - types: [opened, reopened, synchronize] - branches: - - devel - - benchmark* - paths: - - '**.yml' - - '**.sh' - - '**.j2' - - '**.ps1' - - '**.cfg' + types: [opened, reopened, synchronize] + branches: + - devel + - benchmark* + paths: + - '**.yml' + - '**.sh' + - '**.j2' + - '**.ps1' + - '**.cfg' # Allow manual running of workflow workflow_dispatch: @@ -27,133 +27,131 @@ # that can run sequentially or in parallel jobs: # This will create messages for first time contributers and direct them to the Discord server - welcome: - runs-on: ubuntu-latest + welcome: + runs-on: ubuntu-latest - steps: - - uses: actions/first-interaction@main - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - pr-message: |- - Congrats on opening your first pull request and thank you for taking the time to help improve Ansible-Lockdown! - Please join in the conversation happening on the [Discord Server](https://www.lockdownenterprise.com/discord) as well. + steps: + - uses: actions/first-interaction@main + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + issue_message: |- + Congrats on opening your first issue and thank you for taking the time to help improve Ansible-Lockdown! + Please join in the conversation happening on the [Discord Server](https://www.lockdownenterprise.com/discord) as well. + pr_message: |- + Congrats on opening your first pull request and thank you for taking the time to help improve Ansible-Lockdown! + Please join in the conversation happening on the [Discord Server](https://www.lockdownenterprise.com/discord) as well. - # This workflow contains a single job that tests the playbook - playbook-test: - # The type of runner that the job will run on - runs-on: self-hosted - env: - ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} - # Imported as a variable by terraform - TF_VAR_repository: ${{ github.event.repository.name }} - AWS_REGION: "us-east-1" - ANSIBLE_VERSION: ${{ vars.ANSIBLE_RUNNER_VERSION }} - defaults: - run: - shell: bash - working-directory: .github/workflows/github_linux_IaC - # working-directory: .github/workflows + # This workflow contains a single job that tests the playbook + playbook-test: + # The type of runner that the job will run on + runs-on: self-hosted + env: + ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} + # Imported as a variable by terraform + TF_VAR_repository: ${{ github.event.repository.name }} + AWS_REGION: "us-east-1" + ANSIBLE_VERSION: ${{ vars.ANSIBLE_RUNNER_VERSION }} + defaults: + run: + shell: bash + working-directory: .github/workflows/github_linux_IaC + # working-directory: .github/workflows - steps: + steps: - - name: Git clone the lockdown repository to test - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} + - name: Git clone the lockdown repository to test + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} - - name: If a variable for IAC_BRANCH is set use that branch - working-directory: .github/workflows - run: | - if [ ${{ vars.IAC_BRANCH }} != '' ]; then - echo "IAC_BRANCH=${{ vars.IAC_BRANCH }}" >> $GITHUB_ENV - echo "Pipeline using the following IAC branch ${{ vars.IAC_BRANCH }}" - else - echo IAC_BRANCH=main >> $GITHUB_ENV - fi + - name: If a variable for IAC_BRANCH is set use that branch + working-directory: .github/workflows + run: | + if [ ${{ vars.IAC_BRANCH }} != '' ]; then + echo "IAC_BRANCH=${{ vars.IAC_BRANCH }}" >> $GITHUB_ENV + echo "Pipeline using the following IAC branch ${{ vars.IAC_BRANCH }}" + else + echo IAC_BRANCH=main >> $GITHUB_ENV + fi - # Pull in terraform code for linux servers - - name: Clone GitHub IaC plan - uses: actions/checkout@v4 - with: - repository: ansible-lockdown/github_linux_IaC - path: .github/workflows/github_linux_IaC - ref: ${{ env.IAC_BRANCH }} + # Pull in terraform code for linux servers + - name: Clone GitHub IaC plan + uses: actions/checkout@v4 + with: + repository: ansible-lockdown/github_linux_IaC + path: .github/workflows/github_linux_IaC + ref: ${{ env.IAC_BRANCH }} - # Uses dedicated restricted role and policy to enable this only for this task - # No credentials are part of github for AWS auth - - name: configure aws credentials - uses: aws-actions/configure-aws-credentials@main - with: - role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} - role-session-name: ${{ secrets.AWS_ROLE_SESSION }} - aws-region: ${{ env.AWS_REGION }} + # Uses dedicated restricted role and policy to enable this only for this task + # No credentials are part of github for AWS auth + - name: configure aws credentials + uses: aws-actions/configure-aws-credentials@main + with: + role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} + role-session-name: ${{ secrets.AWS_ROLE_SESSION }} + aws-region: ${{ env.AWS_REGION }} - - name: DEBUG - Show IaC files - if: env.ENABLE_DEBUG == 'true' - run: | - echo "OSVAR = $OSVAR" - echo "benchmark_type = $benchmark_type" - echo "PRIVSUBNET_ID = $AWS_PRIVSUBNET_ID" - echo "VPC_ID" = $AWS_VPC_SECGRP_ID" - pwd - ls - env: - # Imported from GitHub variables this is used to load the relevant OS.tfvars file - OSVAR: ${{ vars.OSVAR }} - benchmark_type: ${{ vars.BENCHMARK_TYPE }} - PRIVSUBNET_ID: ${{ secrets.AWS_PRIVSUBNET_ID }} - VPC_ID: ${{ secrets.AWS_VPC_SECGRP_ID }} + - name: DEBUG - Show IaC files + if: env.ENABLE_DEBUG == 'true' + run: | + echo "OSVAR = $OSVAR" + echo "benchmark_type = $benchmark_type" + pwd + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Tofu init - id: init - run: tofu init - env: - # Imported from GitHub variables this is used to load the relevant OS.tfvars file - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + - name: Tofu init + id: init + run: tofu init + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Tofu validate - id: validate - run: tofu validate - env: - # Imported from GitHub variables this is used to load the relevant OS.tfvars file - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + - name: Tofu validate + id: validate + run: tofu validate + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Tofu apply - id: apply - env: - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} - TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} - run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false + - name: Tofu apply + id: apply + env: + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} + TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} + run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false ## Debug Section - - name: DEBUG - Show Ansible hostfile - if: env.ENABLE_DEBUG == 'true' - run: cat hosts.yml + - name: DEBUG - Show Ansible hostfile + if: env.ENABLE_DEBUG == 'true' + run: cat hosts.yml - # Aws deployments taking a while to come up insert sleep or playbook fails + # Aws deployments taking a while to come up insert sleep or playbook fails - - name: Sleep to allow system to come up - run: sleep ${{ vars.BUILD_SLEEPTIME }} + - name: Sleep to allow system to come up + run: sleep ${{ vars.BUILD_SLEEPTIME }} - # Run the Ansible playbook - - name: Run_Ansible_Playbook - env: - ANSIBLE_HOST_KEY_CHECKING: "false" - ANSIBLE_DEPRECATION_WARNINGS: "false" - run: | - /opt/ansible_${{ env.ANSIBLE_VERSION }}_venv/bin/ansible-playbook -i hosts.yml --private-key ~/.ssh/le_runner ../../../site.yml + # Run the Ansible playbook + - name: Run_Ansible_Playbook + env: + ANSIBLE_HOST_KEY_CHECKING: "false" + ANSIBLE_DEPRECATION_WARNINGS: "false" + run: | + /opt/ansible_${{ env.ANSIBLE_VERSION }}_venv/bin/ansible-playbook -i hosts.yml --private-key ~/.ssh/le_runner ../../../site.yml - # Remove test system - User secrets to keep if necessary + # Remove test system - User secrets to keep if necessary - - name: Tofu Destroy - if: always() && env.ENABLE_DEBUG == 'false' - env: - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} - TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} - run: tofu destroy -var-file "${OSVAR}.tfvars" --auto-approve -input=false + - name: Tofu Destroy + if: always() && env.ENABLE_DEBUG == 'false' + env: + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} + TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} + run: tofu destroy -var-file "${OSVAR}.tfvars" --auto-approve -input=false diff --git a/.github/workflows/main_pipeline_validation.yml b/.github/workflows/main_pipeline_validation.yml index 6792a00..6c1d2ea 100644 --- a/.github/workflows/main_pipeline_validation.yml +++ b/.github/workflows/main_pipeline_validation.yml @@ -4,16 +4,16 @@ on: # yamllint disable-line rule:truthy pull_request_target: - types: [opened, reopened, synchronize] - branches: - - main - - latest - paths: - - '**.yml' - - '**.sh' - - '**.j2' - - '**.ps1' - - '**.cfg' + types: [opened, reopened, synchronize] + branches: + - main + - latest + paths: + - '**.yml' + - '**.sh' + - '**.j2' + - '**.ps1' + - '**.cfg' # Allow permissions for AWS auth permissions: @@ -24,123 +24,118 @@ # A workflow run is made up of one or more jobs # that can run sequentially or in parallel jobs: + # This workflow contains a single job that tests the playbook + playbook-test: + # The type of runner that the job will run on + runs-on: self-hosted + env: + ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} + # Imported as a variable by terraform + TF_VAR_repository: ${{ github.event.repository.name }} + AWS_REGION : "us-east-1" + ANSIBLE_VERSION: ${{ vars.ANSIBLE_RUNNER_VERSION }} + defaults: + run: + shell: bash + working-directory: .github/workflows/github_linux_IaC + # working-directory: .github/workflows - # This workflow contains a single job that tests the playbook - playbook-test: - # The type of runner that the job will run on - runs-on: self-hosted - env: - ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} - # Imported as a variable by terraform - TF_VAR_repository: ${{ github.event.repository.name }} - AWS_REGION : "us-east-1" - ANSIBLE_VERSION: ${{ vars.ANSIBLE_RUNNER_VERSION }} - defaults: - run: - shell: bash - working-directory: .github/workflows/github_linux_IaC - # working-directory: .github/workflows + steps: - steps: + - name: Git clone the lockdown repository to test + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} - - name: Git clone the lockdown repository to test - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} + - name: If a variable for IAC_BRANCH is set use that branch + working-directory: .github/workflows + run: | + if [ ${{ vars.IAC_BRANCH }} != '' ]; then + echo "IAC_BRANCH=${{ vars.IAC_BRANCH }}" >> $GITHUB_ENV + echo "Pipeline using the following IAC branch ${{ vars.IAC_BRANCH }}" + else + echo IAC_BRANCH=main >> $GITHUB_ENV + fi - - name: If a variable for IAC_BRANCH is set use that branch - working-directory: .github/workflows - run: | - if [ ${{ vars.IAC_BRANCH }} != '' ]; then - echo "IAC_BRANCH=${{ vars.IAC_BRANCH }}" >> $GITHUB_ENV - echo "Pipeline using the following IAC branch ${{ vars.IAC_BRANCH }}" - else - echo IAC_BRANCH=main >> $GITHUB_ENV - fi + # Pull in terraform code for linux servers + - name: Clone GitHub IaC plan + uses: actions/checkout@v4 + with: + repository: ansible-lockdown/github_linux_IaC + path: .github/workflows/github_linux_IaC + ref: ${{ env.IAC_BRANCH }} - # Pull in terraform code for linux servers - - name: Clone GitHub IaC plan - uses: actions/checkout@v4 - with: - repository: ansible-lockdown/github_linux_IaC - path: .github/workflows/github_linux_IaC - ref: ${{ env.IAC_BRANCH }} + # Uses dedicated restricted role and policy to enable this only for this task + # No credentials are part of github for AWS auth + - name: configure aws credentials + uses: aws-actions/configure-aws-credentials@main + with: + role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} + role-session-name: ${{ secrets.AWS_ROLE_SESSION }} + aws-region: ${{ env.AWS_REGION }} - # Uses dedicated restricted role and policy to enable this only for this task - # No credentials are part of github for AWS auth - - name: configure aws credentials - uses: aws-actions/configure-aws-credentials@main - with: - role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} - role-session-name: ${{ secrets.AWS_ROLE_SESSION }} - aws-region: ${{ env.AWS_REGION }} + - name: DEBUG - Show IaC files + if: env.ENABLE_DEBUG == 'true' + run: | + echo "OSVAR = $OSVAR" + echo "benchmark_type = $benchmark_type" + pwd + ls + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: DEBUG - Show IaC files - if: env.ENABLE_DEBUG == 'true' - run: | - echo "OSVAR = $OSVAR" - echo "benchmark_type = $benchmark_type" - echo "PRIVSUBNET_ID = $AWS_PRIVSUBNET_ID" - echo "VPC_ID" = $AWS_VPC_SECGRP_ID" - pwd - ls - env: - # Imported from GitHub variables this is used to load the relevant OS.tfvars file - OSVAR: ${{ vars.OSVAR }} - benchmark_type: ${{ vars.BENCHMARK_TYPE }} - PRIVSUBNET_ID: ${{ secrets.AWS_PRIVSUBNET_ID }} - VPC_ID: ${{ secrets.AWS_VPC_SECGRP_ID }} + - name: Tofu init + id: init + run: tofu init + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Tofu init - id: init - run: tofu init - env: - # Imported from GitHub variables this is used to load the relevant OS.tfvars file - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + - name: Tofu validate + id: validate + run: tofu validate + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Tofu validate - id: validate - run: tofu validate - env: - # Imported from GitHub variables this is used to load the relevant OS.tfvars file - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - - name: Tofu apply - id: apply - env: - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} - TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} - run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false + - name: Tofu apply + id: apply + env: + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} + TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} + run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false ## Debug Section - - name: DEBUG - Show Ansible hostfile - if: env.ENABLE_DEBUG == 'true' - run: cat hosts.yml + - name: DEBUG - Show Ansible hostfile + if: env.ENABLE_DEBUG == 'true' + run: cat hosts.yml - # Aws deployments taking a while to come up insert sleep or playbook fails + # Aws deployments taking a while to come up insert sleep or playbook fails - - name: Sleep to allow system to come up - run: sleep ${{ vars.BUILD_SLEEPTIME }} + - name: Sleep to allow system to come up + run: sleep ${{ vars.BUILD_SLEEPTIME }} - # Run the Ansible playbook - - name: Run_Ansible_Playbook - env: - ANSIBLE_HOST_KEY_CHECKING: "false" - ANSIBLE_DEPRECATION_WARNINGS: "false" - run: | - /opt/ansible_${{ env.ANSIBLE_VERSION }}_venv/bin/ansible-playbook -i hosts.yml --private-key ~/.ssh/le_runner ../../../site.yml + # Run the Ansible playbook + - name: Run_Ansible_Playbook + env: + ANSIBLE_HOST_KEY_CHECKING: "false" + ANSIBLE_DEPRECATION_WARNINGS: "false" + run: | + /opt/ansible_${{ env.ANSIBLE_VERSION }}_venv/bin/ansible-playbook -i hosts.yml --private-key ~/.ssh/le_runner ../../../site.yml - # Remove test system - User secrets to keep if necessary + # Remove test system - User secrets to keep if necessary - - name: Tofu Destroy - if: always() && env.ENABLE_DEBUG == 'false' - env: - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} - TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} - run: tofu destroy -var-file "${OSVAR}.tfvars" --auto-approve -input=false + - name: Tofu Destroy + if: always() && env.ENABLE_DEBUG == 'false' + env: + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} + TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} + run: tofu destroy -var-file "${OSVAR}.tfvars" --auto-approve -input=false From 81eadd4a6f81d58d3f2c7e4434ece27c842516b9 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 1 Oct 2025 12:59:44 +0100 Subject: [PATCH 108/139] max-concurrent audit option added Signed-off-by: Mark Bolwell --- defaults/main.yml | 2 ++ tasks/post_remediation_audit.yml | 2 +- tasks/pre_remediation_audit.yml | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index d7719ba..ed14e51 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -88,6 +88,8 @@ setup_audit: false run_audit: false # Run heavy tests - some tests can have more impact on a system enabling these can have greater impact on a system audit_run_heavy_tests: true +# Ability to limit the number of concurrent processes used by goss (default 50) +audit_max_concurrent: 50 ## Only run Audit do not remediate audit_only: false diff --git a/tasks/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index 357a23f..5e9419c 100644 --- a/tasks/post_remediation_audit.yml +++ b/tasks/post_remediation_audit.yml @@ -1,7 +1,7 @@ --- - name: Post Audit | Run post_remediation {{ benchmark }} audit # noqa name[template] - ansible.builtin.shell: "umask 0022 && {{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ post_audit_outfile }} -g \"{{ group_names }}\"" # noqa yaml[line-length] + ansible.builtin.shell: "umask 0022 && {{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -m {{ audit_max_concurrent }} -o {{ post_audit_outfile }} -g \"{{ group_names }}\"" # noqa yaml[line-length] changed_when: true environment: AUDIT_BIN: "{{ audit_bin }}" diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index cf8d8c7..dd9efb4 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 @@ -71,7 +72,7 @@ mode: 'go-rwx' - name: Pre Audit | Run pre_remediation audit {{ benchmark }} # noqa name[template] - ansible.builtin.shell: "umask 0022 && {{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ pre_audit_outfile }} -g \"{{ group_names }}\"" # noqa yaml[line-length] + ansible.builtin.shell: "umask 0022 && {{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -m {{ audit_max_concurrent }} -o {{ pre_audit_outfile }} -g \"{{ group_names }}\"" # noqa yaml[line-length] changed_when: true environment: AUDIT_BIN: "{{ audit_bin }}" From 6f167140d1a3b1c1c713793ec17850f83a0c7c68 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 1 Oct 2025 13:00:14 +0100 Subject: [PATCH 109/139] updated Signed-off-by: Mark Bolwell --- Changelog.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Changelog.md b/Changelog.md index ec3d9aa..85eab9c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,15 @@ # Changes to rhel9CIS + +## 2.0.4 - Based on CIS v2.0.0 + +- addressed issue #393 thank you to @fragglexarmy +- addressed issue #394 thank you to @dbeuker +- addressed issues #390 and #391 thanks to @polski-g +- Added max-concurrent options for audit +- work flow updates +- audit logic improvements + ## 2.0.3 - Based on CIS v2.0.0 - addressed issue #387, thank you @fragglexarmy - addressed issue #382 to improve regex logic on 5.4.2.4 From 319c7a8fbbf3e159002c0fde14ca926ab5425e69 Mon Sep 17 00:00:00 2001 From: polski-g Date: Thu, 8 May 2025 10:59:55 -0400 Subject: [PATCH 110/139] ensure check mode runs all non-destructive tasks Signed-off-by: polski-g --- tasks/prelim.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 7321267..7c31c25 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -114,6 +114,7 @@ ansible.builtin.shell: rpm -qi redhat-release | grep Signature # noqa command-instead-of-module changed_when: false failed_when: false + check_mode: false register: prelim_os_gpg_package_valid - name: "PRELIM | PATCH | Force keys to be imported" # noqa command-instead-of-module @@ -207,6 +208,7 @@ ansible.builtin.command: find /sys/class/net/*/ -type d -name wireless register: discover_wireless_adapters changed_when: false + check_mode: false failed_when: discover_wireless_adapters.rc not in [ 0, 1 ] - name: "PRELIM | PATCH | Install Network-Manager | if wireless adapter present" From 7aa911b3541617cd71677c1ebcdcf5a0eba1a8ce Mon Sep 17 00:00:00 2001 From: Thomas Rumbaut Date: Thu, 2 Oct 2025 10:06:44 +0200 Subject: [PATCH 111/139] Update cis_3.2.x.yml (add dccp to blacklist instead of cramfs Signed-off-by: Thomas Rumbaut --- tasks/section_3/cis_3.2.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/section_3/cis_3.2.x.yml b/tasks/section_3/cis_3.2.x.yml index a49d907..415d966 100644 --- a/tasks/section_3/cis_3.2.x.yml +++ b/tasks/section_3/cis_3.2.x.yml @@ -25,8 +25,8 @@ - name: "3.2.1 | PATCH | Ensure dccp kernel module is not available | blacklist" ansible.builtin.lineinfile: path: /etc/modprobe.d/blacklist.conf - regexp: "^(#)?blacklist cramfs(\\s|$)" - line: "blacklist cramfs" + regexp: "^(#)?blacklist dccp(\\s|$)" + line: "blacklist dccp" create: true mode: 'u-x,go-rwx' From eb2fc50dc7bb89d416deb81223bd06ac6cf8b5e3 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 2 Oct 2025 13:47:01 +0100 Subject: [PATCH 112/139] updated to latest version Signed-off-by: Mark Bolwell --- README.md | 194 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 117 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index 098c50a..5c75173 100644 --- a/README.md +++ b/README.md @@ -6,59 +6,93 @@ --- +## Public Repository 📣 + ![Org Stars](https://img.shields.io/github/stars/ansible-lockdown?label=Org%20Stars&style=social) ![Stars](https://img.shields.io/github/stars/ansible-lockdown/RHEL9-CIS?label=Repo%20Stars&style=social) ![Forks](https://img.shields.io/github/forks/ansible-lockdown/RHEL9-CIS?style=social) -![followers](https://img.shields.io/github/followers/ansible-lockdown?style=social) +![Followers](https://img.shields.io/github/followers/ansible-lockdown?style=social) [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/AnsibleLockdown.svg?style=social&label=Follow%20%40AnsibleLockdown)](https://twitter.com/AnsibleLockdown) - -![Ansible Galaxy Quality](https://img.shields.io/ansible/quality/61781?label=Quality&&logo=ansible) ![Discord Badge](https://img.shields.io/discord/925818806838919229?logo=discord) +![License](https://img.shields.io/github/license/ansible-lockdown/RHEL9-CIS?label=License) + +## Lint & Pre-Commit Tools 🔧 + +[![Pre-Commit.ci](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/RHEL9-CIS/pre-commit-ci.json)](https://results.pre-commit.ci/latest/github/ansible-lockdown/RHEL9-CIS/devel) +![YamlLint](https://img.shields.io/badge/yamllint-Present-brightgreen?style=flat&logo=yaml&logoColor=white) +![Ansible-Lint](https://img.shields.io/badge/ansible--lint-Present-brightgreen?style=flat&logo=ansible&logoColor=white) + +## Community Release Information 📂 + ![Release Branch](https://img.shields.io/badge/Release%20Branch-Main-brightgreen) -![Release Tag](https://img.shields.io/github/v/release/ansible-lockdown/RHEL9-CIS) -![Release Date](https://img.shields.io/github/release-date/ansible-lockdown/RHEL9-CIS) +![Release Tag](https://img.shields.io/github/v/tag/ansible-lockdown/RHEL9-CIS?label=Release%20Tag&&color=success) +![Main Release Date](https://img.shields.io/github/release-date/ansible-lockdown/RHEL9-CIS?label=Release%20Date) +![Benchmark Version Main](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/RHEL9-CIS/benchmark-version-main.json) +![Benchmark Version Devel](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/RHEL9-CIS/benchmark-version-devel.json) [![Main Pipeline Status](https://github.com/ansible-lockdown/RHEL9-CIS/actions/workflows/main_pipeline_validation.yml/badge.svg?)](https://github.com/ansible-lockdown/RHEL9-CIS/actions/workflows/main_pipeline_validation.yml) [![Devel Pipeline Status](https://github.com/ansible-lockdown/RHEL9-CIS/actions/workflows/devel_pipeline_validation.yml/badge.svg?)](https://github.com/ansible-lockdown/RHEL9-CIS/actions/workflows/devel_pipeline_validation.yml) + + ![Devel Commits](https://img.shields.io/github/commit-activity/m/ansible-lockdown/RHEL9-CIS/devel?color=dark%20green&label=Devel%20Branch%20Commits) - -![Issues Open](https://img.shields.io/github/issues-raw/ansible-lockdown/RHEL9-CIS?label=Open%20Issues) -![Issues Closed](https://img.shields.io/github/issues-closed-raw/ansible-lockdown/RHEL9-CIS?label=Closed%20Issues&&color=success) +![Open Issues](https://img.shields.io/github/issues-raw/ansible-lockdown/RHEL9-CIS?label=Open%20Issues) +![Closed Issues](https://img.shields.io/github/issues-closed-raw/ansible-lockdown/RHEL9-CIS?label=Closed%20Issues&&color=success) ![Pull Requests](https://img.shields.io/github/issues-pr/ansible-lockdown/RHEL9-CIS?label=Pull%20Requests) -[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit) - -![License](https://img.shields.io/github/license/ansible-lockdown/RHEL9-CIS?label=License) --- -### Community +## Subscriber Release Information 🔐 -Join us on our [Discord Server](https://www.lockdownenterprise.com/discord) to ask questions, discuss features, or just chat with other Ansible-Lockdown users. +![Private Release Branch](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/Private-RHEL9-CIS/release-branch.json) +![Private Benchmark Version](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/Private-RHEL9-CIS/benchmark-version.json) + +[![Private Remediate Pipeline](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/Private-RHEL9-CIS/remediate.json)](https://github.com/ansible-lockdown/Private-RHEL9-CIS/actions/workflows/main_pipeline_validation.yml) +[![Private GPO Pipeline](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/Private-RHEL9-CIS/gpo.json)](https://github.com/ansible-lockdown/Private-RHEL9-CIS/actions/workflows/main_pipeline_validation_gpo.yml) + +![Private Pull Requests](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/Private-RHEL9-CIS/prs.json) +![Private Closed Issues](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/Private-RHEL9-CIS/issues-closed.json) --- -## Caution(s) +## Looking for support? 🤝 + +[Lockdown Enterprise](https://www.lockdownenterprise.com#GH_AL_WINDOWS_2022_cis) + +[Ansible support](https://www.mindpointgroup.com/cybersecurity-products/ansible-counselor#GH_AL_WINDOWS_2022_cis) + +### Community 💬 + +On our [Discord Server](https://www.lockdownenterprise.com/discord) 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 RHEL9-CIS-Audit role or a compliance scanner should be used for compliance checking over check mode. +- Check Mode is not guaranteed! 🚫 The role will complete in check mode without errors, but it is not supported and should be used with caution. - 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 +- To use release version please point to main branch and relevant release for the cis benchmark you wish to work with. - Did we mention testing?? --- +## 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](./ChangeLog.md) + +--- + ## Matching a security Level for CIS It is possible to to only run level 1 or level 2 controls for CIS. @@ -71,14 +105,34 @@ This is managed using tags: The control found in defaults main also need to reflect this as this control the testing that takes place if you are using the audit component. -## Coming from a previous release +--- +## Requirements ✅ -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. +**General:** -Further details can be seen in the [Changelog](./Changelog.md) +- Basic knowledge of Ansible, below are some links to the Ansible documentation to help get started if you are unfamiliar with Ansible -## Auditing (new) + - [Main Ansible documentation page](https://docs.ansible.com) + - [Ansible Getting Started](https://docs.ansible.com/ansible/latest/user_guide/intro_getting_started.html) + - [Tower User Guide](https://docs.ansible.com/ansible-tower/latest/html/userguide/index.html) + - [Ansible Community Info](https://docs.ansible.com/ansible/latest/community/index.html) +- 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 Family OS 9 + +- 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.12+ +- python-def +- libselinux-python + +--- + +## Auditing 🔍 This can be turned on or off within the defaults/main.yml file with the variable 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. @@ -109,7 +163,7 @@ PLAY RECAP ********************************************************************* default : ok=270 changed=23 unreachable=0 failed=0 skipped=140 rescued=0 ignored=0 ``` -## Documentation +## Documentation 📖 - [Read The Docs](https://ansible-lockdown.readthedocs.io/en/latest/) - [Getting Started](https://www.lockdownenterprise.com/docs/getting-started-with-lockdown#GH_AL_RH9_cis) @@ -117,38 +171,32 @@ default : ok=270 changed=23 unreachable=0 failed=0 s - [Per-Host Configuration](https://www.lockdownenterprise.com/docs/per-host-lockdown-enterprise-configuration#GH_AL_RH9_cis) - [Getting the Most Out of the Role](https://www.lockdownenterprise.com/docs/get-the-most-out-of-lockdown-enterprise#GH_AL_RH9_cis) -## Requirements - -**General:** - -- Basic knowledge of Ansible, below are some links to the Ansible documentation to help get started if you are unfamiliar with Ansible - - - [Main Ansible documentation page](https://docs.ansible.com) - - [Ansible Getting Started](https://docs.ansible.com/ansible/latest/user_guide/intro_getting_started.html) - - [Tower User Guide](https://docs.ansible.com/ansible-tower/latest/html/userguide/index.html) - - [Ansible Community Info](https://docs.ansible.com/ansible/latest/community/index.html) -- 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 9 - Other versions are not supported. - -- 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.12+ -- python-def -- 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 +## 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. +There are many tags available for added control precision. Each control has its own set of tags noting what level, what OS element it relates to, whether it's a patch or audit, and the rule number. Additionally, NIST references follow a specific conversion format for consistency and clarity. +### Conversion Format for NIST References: + + 1. Standard Prefix: + + - All references are prefixed with "NIST". + + 2. Standard Types: + + - "800-53" references are formatted as NIST800-53. + - "800-53r5" references are formatted as NIST800-53R5 (with 'R' capitalized). + - "800-171" references are formatted as NIST800-171. + + 3. Details: + + - Section and subsection numbers use periods (.) for numeric separators. + - Parenthetical elements are separated by underscores (_), e.g., IA-5(1)(d) becomes IA-5_1_d. + - Subsection letters (e.g., "b") are appended with an underscore. 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. ```sh @@ -162,33 +210,34 @@ Below is an example of the tag section from a control within this role. Using th - rule_2.2.4 ``` -## Community Contribution + +## 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. +- Your work is done in your own individual branch. Make sure to Signed-off-by 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 +- Pull Requests into devel will confirm your commits have a GPG signature, Signed-off-by, 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 +## Pipeline Testing 🔄 + +uses: + +- ansible-core 2.16 +- 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 +- self-hosted runners using OpenTofu + ## Known Issues Almalinux BaseOS, EPEL and many cloud providers repositories, do not allow gpgcheck(rule_1.2.1.2) or repo_gpgcheck (rule_1.2.1.3) this will cause issues during the playbook unless or a workaround is found. -## Pipeline Testing -uses: +## Local Testing 💻 -- 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 +### example ```bash molecule test -s default @@ -198,24 +247,15 @@ molecule verify -s localhost local testing uses: -- ansible 2.13.3 +- ansible-core - 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](https://pre-commit.com) can be tested and can be run from within the directory - -```sh -pre-commit run -``` - -## Credits and Thanks - -Based on an original concept by Sam Doran +## Credits and Thanks 🙏 Massive thanks to the fantastic community and all its members. From 64e7aab306b81d5de857cb414ba040432bdabfde Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 2 Oct 2025 13:48:29 +0100 Subject: [PATCH 113/139] updated Signed-off-by: Mark Bolwell --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 85eab9c..4d9dc7c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ - addressed issue #393 thank you to @fragglexarmy - addressed issue #394 thank you to @dbeuker - addressed issues #390 and #391 thanks to @polski-g +- addressed issue #398 thanks to trumbaut - Added max-concurrent options for audit - work flow updates - audit logic improvements From 4c91e7477fa1f7194f80de9cd00ec765d4690a93 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 2 Oct 2025 13:59:03 +0100 Subject: [PATCH 114/139] fixed typos Signed-off-by: Mark Bolwell --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5c75173..65a8fca 100644 --- a/README.md +++ b/README.md @@ -58,9 +58,9 @@ ## Looking for support? 🤝 -[Lockdown Enterprise](https://www.lockdownenterprise.com#GH_AL_WINDOWS_2022_cis) +[Lockdown Enterprise](https://www.lockdownenterprise.com#GH_AL_RHEL9-CIS) -[Ansible support](https://www.mindpointgroup.com/cybersecurity-products/ansible-counselor#GH_AL_WINDOWS_2022_cis) +[Ansible support](https://www.mindpointgroup.com/cybersecurity-products/ansible-counselor#GH_AL_RHEL9-CIS) ### Community 💬 @@ -95,7 +95,7 @@ Further details can be seen in the [Changelog](./ChangeLog.md) ## Matching a security Level for CIS -It is possible to to only run level 1 or level 2 controls for CIS. +It is possible to only run level 1 or level 2 controls for CIS. This is managed using tags: - level1-server From 9df94973d72687e31855446045deee5417adbf48 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 3 Oct 2025 07:56:30 +0100 Subject: [PATCH 115/139] added badge workflows Signed-off-by: Mark Bolwell --- .../benchmark_tracking_controller.yml | 38 +++++++++++++++++++ .github/workflows/export_badges_private.yml | 27 +++++++++++++ .github/workflows/export_badges_public.yml | 19 ++++++++++ 3 files changed, 84 insertions(+) create mode 100644 .github/workflows/benchmark_tracking_controller.yml create mode 100644 .github/workflows/export_badges_private.yml create mode 100644 .github/workflows/export_badges_public.yml diff --git a/.github/workflows/benchmark_tracking_controller.yml b/.github/workflows/benchmark_tracking_controller.yml new file mode 100644 index 0000000..0d9f515 --- /dev/null +++ b/.github/workflows/benchmark_tracking_controller.yml @@ -0,0 +1,38 @@ +--- + +# GitHub schedules all cron jobs in UTC. +# This expression will run the job every day at 9 AM Eastern Time during Daylight Saving Time (mid-March to early November). +# This expression will run the job every day at 8 AM Eastern Time during Standard Time (early November to mid-March). + +name: Central Benchmark Orchestrator + +on: + push: + branches: + - latest + schedule: + - cron: '0 6 * * *' # Runs daily at 9 AM ET + workflow_dispatch: + +jobs: + call-benchmark-tracker: + if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref_name == 'latest') + name: Start Benchmark Tracker + uses: ansible-lockdown/github_linux_IaC/.github/workflows/benchmark_track.yml@self_hosted + with: + repo_name: ${{ github.repository }} + secrets: + TEAMS_WEBHOOK_URL: ${{ secrets.TEAMS_WEBHOOK_URL }} + BADGE_PUSH_TOKEN: ${{ secrets.BADGE_PUSH_TOKEN }} + DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} + + call-monitor-promotions: + if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + name: Monitor Promotions and Auto-Promote + uses: ansible-lockdown/github_linux_IaC/.github/workflows/benchmark_promote.yml@self_hosted + with: + repo_name: ${{ github.repository }} + secrets: + TEAMS_WEBHOOK_URL: ${{ secrets.TEAMS_WEBHOOK_URL }} + BADGE_PUSH_TOKEN: ${{ secrets.BADGE_PUSH_TOKEN }} + DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} diff --git a/.github/workflows/export_badges_private.yml b/.github/workflows/export_badges_private.yml new file mode 100644 index 0000000..d316cbf --- /dev/null +++ b/.github/workflows/export_badges_private.yml @@ -0,0 +1,27 @@ +--- + +name: Export Private Repo Badges + +# Use different minute offsets with the same hourly pattern: +# Repo Group Suggested Cron Expression Explanation +# Group A 0 */6 * * * Starts at top of hour +# Group B 10 */6 * * * Starts at 10 after +# And So On + +on: + push: + branches: + - latest + schedule: + - cron: '0 */6 * * *' + workflow_dispatch: + +jobs: + export-badges: + if: github.event_name == 'workflow_dispatch' || (github.event_name == 'schedule' && startsWith(github.repository, 'ansible-lockdown/Private-')) || (github.event_name == 'push' && github.ref_name == 'latest') + uses: ansible-lockdown/github_linux_IaC/.github/workflows/export_badges_private.yml@self_hosted + with: + # Full org/repo path passed for GitHub API calls (e.g., ansible-lockdown/Private-Windows-2016-CIS) + repo_name: ${{ github.repository }} + secrets: + BADGE_PUSH_TOKEN: ${{ secrets.BADGE_PUSH_TOKEN }} diff --git a/.github/workflows/export_badges_public.yml b/.github/workflows/export_badges_public.yml new file mode 100644 index 0000000..fa4b27f --- /dev/null +++ b/.github/workflows/export_badges_public.yml @@ -0,0 +1,19 @@ +--- + +name: Export Public Repo Badges + +on: + push: + branches: + - main + - devel + workflow_dispatch: + +jobs: + export-badges: + if: github.repository_visibility == 'public' && (github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && (github.ref_name == 'devel' || github.ref_name == 'main'))) + uses: ansible-lockdown/github_linux_IaC/.github/workflows/export_badges_public.yml@self_hosted + with: + repo_name: ${{ github.repository }} + secrets: + BADGE_PUSH_TOKEN: ${{ secrets.BADGE_PUSH_TOKEN }} From 6500e39f4265eb7e7f2ebd414c0d4def366585d9 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 3 Oct 2025 08:19:07 +0100 Subject: [PATCH 116/139] Added fix for #399 thanks to @trumbaut Signed-off-by: Mark Bolwell --- Changelog.md | 2 +- tasks/section_5/cis_5.1.x.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index 4d9dc7c..d4b1b78 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,7 +6,7 @@ - addressed issue #393 thank you to @fragglexarmy - addressed issue #394 thank you to @dbeuker - addressed issues #390 and #391 thanks to @polski-g -- addressed issue #398 thanks to trumbaut +- addressed issue #398 & #399 thanks to trumbaut - Added max-concurrent options for audit - work flow updates - audit logic improvements diff --git a/tasks/section_5/cis_5.1.x.yml b/tasks/section_5/cis_5.1.x.yml index 42ca036..dc450ea 100644 --- a/tasks/section_5/cis_5.1.x.yml +++ b/tasks/section_5/cis_5.1.x.yml @@ -41,8 +41,8 @@ ansible.builtin.file: path: "{{ item.path }}" owner: root - group: root - mode: 'u-x,go-rwx' + group: "{{ 'ssh_keys' if (item.gr_name == 'ssh_keys') else 'root' }}" + mode: "{{ 'u-x,g-wx,o-rwx' if (item.gr_name == 'ssh_keys') else 'u-x,go-rwx' }}" loop: "{{ discovered_ssh_private_host_key.files }}" loop_control: label: "{{ item.path }}" From de4b2cfa5cf80371436abb74f40bad59a68479c0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 17:51:08 +0000 Subject: [PATCH 117/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/ansible-community/ansible-lint: v25.9.0 → v25.9.1](https://github.com/ansible-community/ansible-lint/compare/v25.9.0...v25.9.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7fd561a..e633b2a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,7 +46,7 @@ repos: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.9.0 + rev: v25.9.1 hooks: - id: ansible-lint name: Ansible-lint From 51668530a951cea132383eb884a2f4150e23425d Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Thu, 9 Oct 2025 14:10:29 -0400 Subject: [PATCH 118/139] update workflow benchmark_tracking_controller Signed-off-by: Frederick Witty --- .../benchmark_tracking_controller.yml | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/.github/workflows/benchmark_tracking_controller.yml b/.github/workflows/benchmark_tracking_controller.yml index 0d9f515..039ec0d 100644 --- a/.github/workflows/benchmark_tracking_controller.yml +++ b/.github/workflows/benchmark_tracking_controller.yml @@ -1,8 +1,22 @@ --- # GitHub schedules all cron jobs in UTC. -# This expression will run the job every day at 9 AM Eastern Time during Daylight Saving Time (mid-March to early November). -# This expression will run the job every day at 8 AM Eastern Time during Standard Time (early November to mid-March). +# ────────────────────────────────────────────────────────────────────────────── +# Schedule: +# - '0 13 * * *' runs at 13:00 UTC every day. +# - This corresponds to: +# • 9:00 AM Eastern **during Daylight Saving Time** (mid-Mar → early-Nov) +# • 8:00 AM Eastern **during Standard Time** (early-Nov → mid-Mar) +# +# Job routing: +# - call-benchmark-tracker: +# • Runs on manual dispatch, and on pushes to the 'latest' branch. +# - call-monitor-promotions: +# • Runs on schedule or manual dispatch **only in repos named ansible-lockdown/Private-***. +# • Skips automatically in public repos (e.g., Windows-2022-CIS) to avoid false failures. +# +# Defense-in-depth: +# - The called promotion workflow may still keep its own guard to ensure only Private-* repos execute it. name: Central Benchmark Orchestrator @@ -11,11 +25,12 @@ on: branches: - latest schedule: - - cron: '0 6 * * *' # Runs daily at 9 AM ET + - cron: '0 13 * * *' # 13:00 UTC → 9 AM ET (DST) / 8 AM ET (Standard Time) workflow_dispatch: jobs: call-benchmark-tracker: + # Run on manual dispatch OR when 'latest' branch receives a push if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref_name == 'latest') name: Start Benchmark Tracker uses: ansible-lockdown/github_linux_IaC/.github/workflows/benchmark_track.yml@self_hosted @@ -27,7 +42,8 @@ jobs: DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} call-monitor-promotions: - if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + # Run on schedule or manual dispatch, but only for Private-* repos + if: (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && startsWith(github.repository, 'ansible-lockdown/Private-') name: Monitor Promotions and Auto-Promote uses: ansible-lockdown/github_linux_IaC/.github/workflows/benchmark_promote.yml@self_hosted with: From 451dce8aa79ac8e9b89584e2390d18d6cddcbeb1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 17:38:43 +0000 Subject: [PATCH 119/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/ansible-community/ansible-lint: v25.9.1 → v25.9.2](https://github.com/ansible-community/ansible-lint/compare/v25.9.1...v25.9.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e633b2a..0091b2a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,7 +46,7 @@ repos: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.9.1 + rev: v25.9.2 hooks: - id: ansible-lint name: Ansible-lint From 278813694bf95e426743dc728fcb6661fa91ac80 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 16 Oct 2025 15:23:56 +0100 Subject: [PATCH 120/139] Updated permissions Signed-off-by: Mark Bolwell --- .github/workflows/devel_pipeline_validation.yml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/devel_pipeline_validation.yml b/.github/workflows/devel_pipeline_validation.yml index deac4d7..8fd728a 100644 --- a/.github/workflows/devel_pipeline_validation.yml +++ b/.github/workflows/devel_pipeline_validation.yml @@ -17,12 +17,6 @@ # Allow manual running of workflow workflow_dispatch: - # Allow permissions for AWS auth - permissions: - id-token: write - contents: read - pull-requests: read - # A workflow run is made up of one or more jobs # that can run sequentially or in parallel jobs: @@ -30,6 +24,10 @@ welcome: runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: - uses: actions/first-interaction@main with: @@ -45,6 +43,13 @@ playbook-test: # The type of runner that the job will run on runs-on: self-hosted + + # Allow permissions for AWS auth + permissions: + id-token: write + contents: read + pull-requests: read + env: ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} # Imported as a variable by terraform From afcfda9ef06d8e40b0b6f3de8f02217e604f2d3c Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 16 Oct 2025 15:24:49 +0100 Subject: [PATCH 121/139] compliant with 2.19 Signed-off-by: Mark Bolwell --- templates/audit/99_auditd.rules.j2 | 98 +++++------------------------- 1 file changed, 14 insertions(+), 84 deletions(-) diff --git a/templates/audit/99_auditd.rules.j2 b/templates/audit/99_auditd.rules.j2 index 4fa4516..c3c2b6c 100644 --- a/templates/audit/99_auditd.rules.j2 +++ b/templates/audit/99_auditd.rules.j2 @@ -10,12 +10,7 @@ {% endif %} {% if rhel9cis_rule_6_3_3_2 %} {% set syscalls = ["execve"] %} -{% set arch_syscalls = [] %} -{%- for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append(syscall) }} -{% endif %} -{% endfor -%} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b64 -C euid!=uid -F auid!=unset -S {{ arch_syscalls|join(',') }} -k user_emulation -a always,exit -F arch=b32 -C euid!=uid -F auid!=unset -S {{ arch_syscalls|join(',') }} -k user_emulation {% endif %} @@ -24,33 +19,18 @@ {% endif %} {% if rhel9cis_rule_6_3_3_4 %} {% set syscalls = ["adjtimex","settimeofday"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append(syscall) }} -{% endif %} -{% endfor %} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -k time-change -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -k time-change {% set syscalls = ["clock_settime"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append(syscall) }} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F a0=0x0 -k time-change -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F a0=0x0 -k time-change -{% endif %} -{% endfor %} -w /etc/localtime -p wa -k time-change {% endif %} {% if rhel9cis_rule_6_3_3_5 %} {% set syscalls = ["sethostname","setdomainname"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append(syscall) }} -{% endif %} -{% endfor %} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -k system-locale -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -k system-locale -w /etc/issue -p wa -k system-locale @@ -68,12 +48,7 @@ {% endif %} {% if rhel9cis_rule_6_3_3_7 %} {% set syscalls = ["creat","open","openat","truncate","ftruncate"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append(syscall) }} -{% endif %} -{% endfor %} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F exit=-EACCES -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F exit=-EPERM -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F exit=-EACCES -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access @@ -91,62 +66,27 @@ {% endif %} {% if rhel9cis_rule_6_3_3_9 %} {% set syscalls = ["chmod","fchmod","fchmodat"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append(syscall) }} -{% endif %} -{% endfor %} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod {% set syscalls = ["chown","fchown","lchown","fchownat"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append(syscall) }} -{% endif %} -{% endfor %} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod {% set syscalls = ["setxattr","lsetxattr","fsetxattr","removexattr","lremovexattr","fremovexattr"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append(syscall) }} -{% endif %} -{% endfor %} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod {% set syscalls = ["chmod","fchmod","fchmodat"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append(syscall) }} -{% endif %} -{% endfor %} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod {% set syscalls = ["chown","fchown","lchown","fchownat"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append(syscall) }} -{% endif %} -{% endfor %} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod {% set syscalls = ["setxattr","lsetxattr","fsetxattr","removexattr","lremovexattr","fremovexattr"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append(syscall) }} -{% endif %} -{% endfor %} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod {% endif %} {% if rhel9cis_rule_6_3_3_10 %} {% set syscalls = ["mount"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append(syscall) }} -{% endif %} -{% endfor %} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k mounts -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k mounts {% endif %} @@ -161,12 +101,7 @@ {% endif %} {% if rhel9cis_rule_6_3_3_13 %} {% set syscalls = ["unlink","unlinkat","rename","renameat"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append( syscall) }} -{% endif %} -{% endfor %} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k delete -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k delete {% endif %} @@ -189,12 +124,7 @@ {% if rhel9cis_rule_6_3_3_19 %} -a always,exit -F path=/usr/bin/kmod -F perm=x -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k kernel_modules {% set syscalls = ["init_module","finit_module","delete_module","create_module","query_module"] %} -{% set arch_syscalls = [] %} -{% for syscall in syscalls %} -{% if syscall in supported_syscalls %} -{{ arch_syscalls.append( syscall) }} -{% endif %} -{% endfor %} +{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k kernel_modules {% endif %} {% if rhel9cis_rule_6_3_3_20 %} From f8cdf84e95a45525444100041fd00629960ab657 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 16 Oct 2025 15:26:07 +0100 Subject: [PATCH 122/139] Added benchmark_version variable Signed-off-by: Mark Bolwell --- templates/ansible_vars_goss.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/ansible_vars_goss.yml.j2 b/templates/ansible_vars_goss.yml.j2 index 7cb906b..cbaa125 100644 --- a/templates/ansible_vars_goss.yml.j2 +++ b/templates/ansible_vars_goss.yml.j2 @@ -37,7 +37,7 @@ rhel9cis_legacy_boot: {{ rhel9cis_legacy_boot }} ## Benchmark name used by auditing control role # The audit variable found at the base ## metadata for Audit benchmark -benchmark_version: 'v2.0.0' +benchmark_version: {{ benchmark_version }} benchmark: RHEL9-CIS From ea17b0adc23e272801ef31a67592bee5042b8899 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 16 Oct 2025 15:26:42 +0100 Subject: [PATCH 123/139] removed legacy option Signed-off-by: Mark Bolwell --- defaults/main.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index ed14e51..fbe81eb 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -94,8 +94,6 @@ audit_max_concurrent: 50 ## Only run Audit do not remediate audit_only: false ### As part of audit_only ### -# This will enable files to be copied back to control node in audit_only mode -fetch_audit_files: false # Path to copy the files to will create dir structure in audit_only mode audit_capture_files_dir: /some/location to copy to on control node ############################# From 5354111505c088b47fb53689363fbd4b8e451345 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 16 Oct 2025 15:27:27 +0100 Subject: [PATCH 124/139] improved audit logic Signed-off-by: Mark Bolwell --- tasks/pre_remediation_audit.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index dd9efb4..410473e 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -85,6 +85,7 @@ - name: Pre Audit | Capture audit data if json format ansible.builtin.shell: grep -E '\"summary-line.*Count:.*Failed' "{{ pre_audit_outfile }}" | cut -d'"' -f4 changed_when: false + failed_when: pre_audit_summary.stderr | length > 0 register: pre_audit_summary - name: Pre Audit | Set Fact for audit summary @@ -97,6 +98,7 @@ - name: Pre Audit | Capture audit data if documentation format ansible.builtin.shell: tail -2 "{{ pre_audit_outfile }}" | tac | tr '\n' ' ' changed_when: false + failed_when: pre_audit_summary.stderr | length > 0 register: pre_audit_summary - name: Pre Audit | Set Fact for audit summary From 8ec8ebc8167ef99946ab4d7a7950c8b0b82fca9c Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 16 Oct 2025 15:29:26 +0100 Subject: [PATCH 125/139] updated Signed-off-by: Mark Bolwell --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index d4b1b78..737f860 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,7 @@ - Added max-concurrent options for audit - work flow updates - audit logic improvements +- auditd template 2.19 compatible ## 2.0.3 - Based on CIS v2.0.0 - addressed issue #387, thank you @fragglexarmy From e1dd9fd283b7b92cc74846a0feb6dbbb01ef5fbc Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Thu, 16 Oct 2025 15:12:19 -0400 Subject: [PATCH 126/139] Add workflow to auto add new issues to project Signed-off-by: Frederick Witty --- .../workflows/add_repo_issue_to_gh_project.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/add_repo_issue_to_gh_project.yml diff --git a/.github/workflows/add_repo_issue_to_gh_project.yml b/.github/workflows/add_repo_issue_to_gh_project.yml new file mode 100644 index 0000000..4a056eb --- /dev/null +++ b/.github/workflows/add_repo_issue_to_gh_project.yml @@ -0,0 +1,17 @@ +--- + +name: Add Repo Issue to ALD GH project +on: + issues: + types: + - opened + - reopened + - transferred +jobs: + add-to-project: + runs-on: ubuntu-latest + steps: + - uses: actions/add-to-project@main + with: + project-url: https://github.com/orgs/ansible-lockdown/projects/1 + github-token: ${{ secrets.GITHUB_TOKEN }} From 4c41656a3b642c3ba620b4df5eaafd7f3f382f7b Mon Sep 17 00:00:00 2001 From: Frederick Witty Date: Thu, 23 Oct 2025 08:28:06 -0400 Subject: [PATCH 127/139] .github standardization Signed-off-by: Frederick Witty --- .../add_repo_issue_to_gh_project.yml | 2 +- .github/workflows/update_galaxy.yml | 19 ------------------- 2 files changed, 1 insertion(+), 20 deletions(-) delete mode 100644 .github/workflows/update_galaxy.yml diff --git a/.github/workflows/add_repo_issue_to_gh_project.yml b/.github/workflows/add_repo_issue_to_gh_project.yml index 4a056eb..80d7344 100644 --- a/.github/workflows/add_repo_issue_to_gh_project.yml +++ b/.github/workflows/add_repo_issue_to_gh_project.yml @@ -14,4 +14,4 @@ jobs: - uses: actions/add-to-project@main with: project-url: https://github.com/orgs/ansible-lockdown/projects/1 - github-token: ${{ secrets.GITHUB_TOKEN }} + github-token: ${{ secrets.ALD_GH_PROJECT }} diff --git a/.github/workflows/update_galaxy.yml b/.github/workflows/update_galaxy.yml deleted file mode 100644 index b6ee6a1..0000000 --- a/.github/workflows/update_galaxy.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- - - name: update galaxy - - on: - push: - branches: - - main - jobs: - update_role: - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Action Ansible Galaxy Release ${{ github.ref_name }} - uses: ansible-actions/ansible-galaxy-action@main - with: - galaxy_api_key: ${{ secrets.GALAXY_API_KEY }} From 0ec943073cad7d805b08cdbc11bf8c925e2611ae Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 17:45:49 +0000 Subject: [PATCH 128/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/gitleaks/gitleaks: v8.28.0 → v8.29.0](https://github.com/gitleaks/gitleaks/compare/v8.28.0...v8.29.0) - [github.com/ansible-community/ansible-lint: v25.9.2 → v25.11.0](https://github.com/ansible-community/ansible-lint/compare/v25.9.2...v25.11.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0091b2a..4aa6519 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,12 +41,12 @@ repos: - id: detect-secrets - repo: https://github.com/gitleaks/gitleaks - rev: v8.28.0 + rev: v8.29.0 hooks: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.9.2 + rev: v25.11.0 hooks: - id: ansible-lint name: Ansible-lint From 539ac4f5cc6b1646ed18343d6915dbef60c894d8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 17:42:03 +0000 Subject: [PATCH 129/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/gitleaks/gitleaks: v8.29.0 → v8.29.1](https://github.com/gitleaks/gitleaks/compare/v8.29.0...v8.29.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4aa6519..9d80577 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: - id: detect-secrets - repo: https://github.com/gitleaks/gitleaks - rev: v8.29.0 + rev: v8.29.1 hooks: - id: gitleaks From 72602c63fade97c61e2845f3beae665d98580f1e Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 25 Nov 2025 09:28:00 +0000 Subject: [PATCH 130/139] add fix provided by @kpi-nourman via discord community Signed-off-by: Mark Bolwell --- templates/etc/dconf/db/gdm.d/01-banner-message.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/etc/dconf/db/gdm.d/01-banner-message.j2 b/templates/etc/dconf/db/gdm.d/01-banner-message.j2 index 901e9e0..ec42bfc 100644 --- a/templates/etc/dconf/db/gdm.d/01-banner-message.j2 +++ b/templates/etc/dconf/db/gdm.d/01-banner-message.j2 @@ -4,4 +4,4 @@ [org/gnome/login-screen] banner-message-enable=true -banner-message-text="{{ rhel9cis_warning_banner }}" +banner-message-text="{{ rhel9cis_warning_banner | trim | replace("\n", "\\n") }}" From 52452b1e3c71d6fbb427edbc477234174420df16 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 28 Nov 2025 14:51:43 +0000 Subject: [PATCH 131/139] issues 413 addressed thansk to @bbaassssiiee Signed-off-by: Mark Bolwell --- Changelog.md | 4 +++- tasks/main.yml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 737f860..ac9c3b6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,5 @@ # Changes to rhel9CIS - ## 2.0.4 - Based on CIS v2.0.0 - addressed issue #393 thank you to @fragglexarmy @@ -11,6 +10,9 @@ - work flow updates - audit logic improvements - auditd template 2.19 compatible +- pre-commit updates +- #410 thanks to @kpi-nourman +- #413 thanks to @bbaassssiiee ## 2.0.3 - Based on CIS v2.0.0 - addressed issue #387, thank you @fragglexarmy diff --git a/tasks/main.yml b/tasks/main.yml index 760ee1b..6f97141 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -134,7 +134,7 @@ - rule_5.4.2.4 block: - name: "Ensure root password is set" - ansible.builtin.shell: LC_ALL=C passwd -S root | grep -E "(Password set|Password locked)" + ansible.builtin.shell: LC_ALL=C passwd -S root | grep -E "(\*LOCK\*|Password set|Password locked)" changed_when: false failed_when: prelim_root_passwd_set.rc not in [ 0, 1 ] register: prelim_root_passwd_set From 571711f11e0d8a988fee79a2f24eaf918768add4 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 1 Dec 2025 10:23:25 +0000 Subject: [PATCH 132/139] updated with correct fix thanks to @bbaassssiiee 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 6f97141..4d1887d 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -134,7 +134,7 @@ - rule_5.4.2.4 block: - name: "Ensure root password is set" - ansible.builtin.shell: LC_ALL=C passwd -S root | grep -E "(\*LOCK\*|Password set|Password locked)" + ansible.builtin.shell: LC_ALL=C passwd -S root | grep -E "(Alternate authentication|Password set|Password locked)" changed_when: false failed_when: prelim_root_passwd_set.rc not in [ 0, 1 ] register: prelim_root_passwd_set From 322404a6921f2709b4066e3745c7dc5d181314e3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 17:41:29 +0000 Subject: [PATCH 133/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/gitleaks/gitleaks: v8.29.1 → v8.30.0](https://github.com/gitleaks/gitleaks/compare/v8.29.1...v8.30.0) - [github.com/ansible-community/ansible-lint: v25.11.0 → v25.12.1](https://github.com/ansible-community/ansible-lint/compare/v25.11.0...v25.12.1) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9d80577..255180a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,12 +41,12 @@ repos: - id: detect-secrets - repo: https://github.com/gitleaks/gitleaks - rev: v8.29.1 + rev: v8.30.0 hooks: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.11.0 + rev: v25.12.1 hooks: - id: ansible-lint name: Ansible-lint From 62989d258b5af00fd190299d002b95635e9b8284 Mon Sep 17 00:00:00 2001 From: George Nalen Date: Fri, 19 Dec 2025 16:31:37 -0500 Subject: [PATCH 134/139] added fix to issue #416 Signed-off-by: George Nalen --- templates/etc/sysctl.d/60-disable_ipv6.conf.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/templates/etc/sysctl.d/60-disable_ipv6.conf.j2 b/templates/etc/sysctl.d/60-disable_ipv6.conf.j2 index bdded40..b4b5318 100644 --- a/templates/etc/sysctl.d/60-disable_ipv6.conf.j2 +++ b/templates/etc/sysctl.d/60-disable_ipv6.conf.j2 @@ -4,4 +4,7 @@ {% if rhel9cis_rule_3_1_1 and not rhel9cis_ipv6_required %} net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 +{% for interface in ansible_interfaces %} +net.ipv6.conf.{{ interface }}.disable_ipv6 = 1 +{% endfor %} {% endif %} From 96474159ab282aad770e038870fad2d5cfacec69 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 17:33:38 +0000 Subject: [PATCH 135/139] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/ansible-community/ansible-lint: v25.12.1 → v25.12.2](https://github.com/ansible-community/ansible-lint/compare/v25.12.1...v25.12.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 255180a..dbc1d7e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,7 +46,7 @@ repos: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.12.1 + rev: v25.12.2 hooks: - id: ansible-lint name: Ansible-lint From beb3bfdc94ea94903bb82a3cba0d89d84c7ce60f Mon Sep 17 00:00:00 2001 From: George Nalen Date: Mon, 22 Dec 2025 16:35:08 -0500 Subject: [PATCH 136/139] added option for sysctl or kernel for disabling IPv6 Signed-off-by: George Nalen --- defaults/main.yml | 2 ++ tasks/section_3/cis_3.1.x.yml | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index fbe81eb..2ad3eb2 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -802,6 +802,8 @@ rhel9cis_tftp_client: false ## Control 3.1.1 - Ensure IPv6 status is identified # This variable governs whether ipv6 is enabled or disabled. rhel9cis_ipv6_required: true +# rhel9cis_ipv6_disable defines the method of disabling IPv6, sysctl vs kernel +rhel9cis_ipv6_disable: "sysctl" ## Control 3.1.2 - Ensure wireless interfaces are disabled # if wireless adapter found allow network manager to be installed diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index a20c0e9..6cd73f3 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -16,14 +16,29 @@ - rule_3.1.1 - NIST800-53R5_CM-7 block: - - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | refresh" + - name: "3.1.1 | AUDIT | Ensure IPv6 status is identified | Set vars for sysctl template" + when: "'sysctl' in rhel9cis_ipv6_disable_method" ansible.builtin.set_fact: rhel9cis_sysctl_update: true rhel9cis_flush_ipv6_route: true - - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | disable" + - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | disable via sysctl template" + when: "'sysctl' in rhel9cis_ipv6_disable_method" ansible.builtin.debug: msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-disable_ipv6.conf" + + - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | Find IPv6 status" + when: "'kernel' in rhel9cis_ipv6_disable_method" + ansible.builtin.command: grubby --info=ALL + changed_when: false + failed_when: false + register: discovered_rhel9cis_3_1_1_ipv6_status + + - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | Disable IPV6 via Kernel" + when: + - "'kernel' in rhel9cis_ipv6_disable_method" + - "'ipv6.disable=1' not in discovered_rhel9cis_3_1_1_ipv6_status.stdout" + ansible.builtin.shell: grubby --update-kernel=ALL --args="ipv6.disable=1" - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled" when: From 2b7c8293b83667c853b44df0bd2bf38217695401 Mon Sep 17 00:00:00 2001 From: George Nalen Date: Mon, 22 Dec 2025 16:56:24 -0500 Subject: [PATCH 137/139] fixed linting issue Signed-off-by: George Nalen --- tasks/section_3/cis_3.1.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index 6cd73f3..0c9c374 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -26,7 +26,7 @@ when: "'sysctl' in rhel9cis_ipv6_disable_method" ansible.builtin.debug: msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-disable_ipv6.conf" - + - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | Find IPv6 status" when: "'kernel' in rhel9cis_ipv6_disable_method" ansible.builtin.command: grubby --info=ALL From d9927f005bc09bd172c94d51096cfe2a68e386af Mon Sep 17 00:00:00 2001 From: George Nalen Date: Tue, 23 Dec 2025 08:42:28 -0500 Subject: [PATCH 138/139] fixed typo in disable method var Signed-off-by: George Nalen --- defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults/main.yml b/defaults/main.yml index 2ad3eb2..f620a72 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -803,7 +803,7 @@ rhel9cis_tftp_client: false # This variable governs whether ipv6 is enabled or disabled. rhel9cis_ipv6_required: true # rhel9cis_ipv6_disable defines the method of disabling IPv6, sysctl vs kernel -rhel9cis_ipv6_disable: "sysctl" +rhel9cis_ipv6_disable_method: "sysctl" ## Control 3.1.2 - Ensure wireless interfaces are disabled # if wireless adapter found allow network manager to be installed From 29a48f7f4cc0c794760a0f1b4a8da2c92ac7d35d Mon Sep 17 00:00:00 2001 From: George Nalen Date: Tue, 23 Dec 2025 09:04:42 -0500 Subject: [PATCH 139/139] updated name info for tasks related to 3.1.1 Signed-off-by: George Nalen --- tasks/section_3/cis_3.1.x.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index 0c9c374..ff9ec46 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -16,18 +16,18 @@ - rule_3.1.1 - NIST800-53R5_CM-7 block: - - name: "3.1.1 | AUDIT | Ensure IPv6 status is identified | Set vars for sysctl template" + - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | Set vars for sysctl template" when: "'sysctl' in rhel9cis_ipv6_disable_method" ansible.builtin.set_fact: rhel9cis_sysctl_update: true rhel9cis_flush_ipv6_route: true - - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | disable via sysctl template" + - name: "3.1.1 | AUDIT | Ensure IPv6 status is identified | Message out implementation info" when: "'sysctl' in rhel9cis_ipv6_disable_method" ansible.builtin.debug: msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-disable_ipv6.conf" - - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | Find IPv6 status" + - name: "3.1.1 | AUDIT | Ensure IPv6 status is identified | Find IPv6 status" when: "'kernel' in rhel9cis_ipv6_disable_method" ansible.builtin.command: grubby --info=ALL changed_when: false