From ecc2e66795349db655a22e5aef84f1f089af6bb2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 17:55:03 +0000 Subject: [PATCH 01/42] [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.21.2 → v8.22.0](https://github.com/gitleaks/gitleaks/compare/v8.21.2...v8.22.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 9ebfee3..7fe39ad 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.21.2 + rev: v8.22.0 hooks: - id: gitleaks From 58d6389d8544999c72bc67c6a3bd2904b8d002cc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 17:34:45 +0000 Subject: [PATCH 02/42] [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.22.0 → v8.22.1](https://github.com/gitleaks/gitleaks/compare/v8.22.0...v8.22.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 7fe39ad..4561cf6 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.22.0 + rev: v8.22.1 hooks: - id: gitleaks From 88a497b1955d61b1e57771a07b44190639261ebd Mon Sep 17 00:00:00 2001 From: Christopher Papke Date: Tue, 7 Jan 2025 12:57:02 -0800 Subject: [PATCH 03/42] Use shell for grep with shell expansions Signed-off-by: Christopher Papke --- tasks/section_5/cis_5.3.2.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_5/cis_5.3.2.x.yml b/tasks/section_5/cis_5.3.2.x.yml index eddf5ee..91e7186 100644 --- a/tasks/section_5/cis_5.3.2.x.yml +++ b/tasks/section_5/cis_5.3.2.x.yml @@ -141,7 +141,7 @@ - rule_5.3.2.5 block: - name: "5.3.2.5 | AUDIT | Ensure pam_unix module is enabled" - ansible.builtin.command: grep -P -- '\b(pam_unix\.so)\b' /etc/authselect/"$(head -1 /etc/authselect/authselect.conf)"/{system,password}-auth + ansible.builtin.shell: grep -P -- '\b(pam_unix\.so)\b' /etc/authselect/"$(head -1 /etc/authselect/authselect.conf)"/{system,password}-auth changed_when: false failed_when: discovered_discovered_authselect_pam_unix.rc not in [ 0, 1 ] register: discovered_discovered_authselect_pam_unix From cc8e32fb2da05191c10fc935eb96c6f9716fa09c Mon Sep 17 00:00:00 2001 From: Christopher Papke Date: Tue, 7 Jan 2025 13:01:24 -0800 Subject: [PATCH 04/42] remove extra discovered_ prefix from variable Signed-off-by: Christopher Papke --- tasks/section_5/cis_5.3.2.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/section_5/cis_5.3.2.x.yml b/tasks/section_5/cis_5.3.2.x.yml index eddf5ee..143b3c0 100644 --- a/tasks/section_5/cis_5.3.2.x.yml +++ b/tasks/section_5/cis_5.3.2.x.yml @@ -143,8 +143,8 @@ - name: "5.3.2.5 | AUDIT | Ensure pam_unix module is enabled" ansible.builtin.command: grep -P -- '\b(pam_unix\.so)\b' /etc/authselect/"$(head -1 /etc/authselect/authselect.conf)"/{system,password}-auth changed_when: false - failed_when: discovered_discovered_authselect_pam_unix.rc not in [ 0, 1 ] - register: discovered_discovered_authselect_pam_unix + failed_when: discovered_authselect_pam_unix.rc not in [ 0, 1 ] + register: discovered_authselect_pam_unix - name: "5.3.2.5 | PATCH | Ensure pam_unix module is enabled | system-auth" when: "'system-auth:password' not in discovered_authselect_pam_unix.stdout" From 424e5f78eb9230b816c3f357b9b49fc50e0f8f04 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 13 Jan 2025 11:55:27 +0000 Subject: [PATCH 05/42] Added fix for 5.3.2.2 Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.3.2.x.yml | 62 ++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/tasks/section_5/cis_5.3.2.x.yml b/tasks/section_5/cis_5.3.2.x.yml index d80e39a..ef84113 100644 --- a/tasks/section_5/cis_5.3.2.x.yml +++ b/tasks/section_5/cis_5.3.2.x.yml @@ -45,7 +45,6 @@ when: - rhel9cis_rule_5_3_2_2 - rhel9cis_disruption_high - - rhel9cis_allow_authselect_updates tags: - level1-server - level1-workstation @@ -58,19 +57,58 @@ - NIST800-53R5_IA-5 - authselect - rule_5.3.2.2 - notify: Authselect update block: - - name: "5.3.2.2 | AUDIT | Ensure pam_faillock module is enabled | Get current config" - ansible.builtin.shell: | - authselect current | grep faillock - changed_when: false - failed_when: discovered_authselect_current_faillock.rc not in [ 0, 1 ] - register: discovered_authselect_current_faillock + - name: "5.3.2.2 | AUDIT | Ensure pam_faillock module is enabled | Get current config authselect" + block: + - name: "5.3.2.2 | AUDIT | Ensure pam_faillock module is enabled | Get current config authselect" + when: rhel9cis_allow_authselect_updates + ansible.builtin.shell: authselect current | grep faillock + changed_when: false + failed_when: discovered_authselect_current_faillock.rc not in [ 0, 1 ] + register: discovered_authselect_current_faillock - - name: "5.3.2.2 | AUDIT | Ensure pam_faillock module is enabled | Add feature if missing" # noqa syntax-check[specific]" - when: discovered_authselect_current_faillock.rc != 0 - ansible.builtin.command: "/usr/bin/authselect select custom/{{ rhel9cis_authselect_custom_profile_name }}{% if rhel9cis_rule_5_3_2_2 %} with-faillock{% endif %}{% if rhel9cis_rule_5_3_2_3 %} with-pwquality{% endif %}{% if rhel9cis_rule_5_3_2_4 %} with-pwhistory{% endif %}{% if rhel9cis_rule_5_3_3_4_1 %} without-nullok{% endif %}" - changed_when: true + - name: "5.3.2.2 | PATCH | Ensure pam_faillock module is enabled | Add feature if missing authselect" # noqa syntax-check[specific]" + when: + - rhel9cis_allow_authselect_updates + - discovered_authselect_current_faillock.rc != 0 + ansible.builtin.command: "/usr/bin/authselect select custom/{{ rhel9cis_authselect_custom_profile_name }}{% if rhel9cis_rule_5_3_2_2 %} with-faillock{% endif %}{% if rhel9cis_rule_5_3_2_3 %} with-pwquality{% endif %}{% if rhel9cis_rule_5_3_2_4 %} with-pwhistory{% endif %}{% if rhel9cis_rule_5_3_3_4_1 %} without-nullok{% endif %}" + changed_when: true + notify: Authselect update + + - name: "5.3.2.2 | PATCH | Ensure pam_faillock module is enabled | Get current config not authselect" + block: + - name: "5.3.2.2 | AUDIT | Ensure pam_faillock module is enabled | not authselect" + when: not rhel9cis_allow_authselect_updates + ansible.builtin.command: grep -E "(auth|account)\s*required\s*pam_faillock.so" /etc/pam.d/{system,password}-auth + changed_when: false + failed_when: false + register: discovered_faillock_not_authselect + + - name: "5.3.2.2 | PATCH | Ensure pam_faillock module is enabled | Add lines system-auth" + when: not rhel9cis_allow_authselect_updates + ansible.builtin.lineinfile: + path: "/etc/pam.d/system-auth" + regexp: "{{ item.regexp }}" + insertbefore: "{{ item.before | default(omit) }}" + 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 } + + - name: "5.3.2.2 | AUDIT | Ensure pam_faillock module is enabled | Add lines password-auth" + when: not rhel9cis_allow_authselect_updates + ansible.builtin.lineinfile: + path: "/etc/pam.d/password-auth" + regexp: "{{ item.regexp }}" + insertbefore: "{{ item.before | default(omit) }}" + 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 } - name: "5.3.2.3 | PATCH | Ensure pam_pwquality module is enabled" when: From c0ce0533387039e8f8d599b0ef98723e407daba9 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 13 Jan 2025 11:55:41 +0000 Subject: [PATCH 06/42] added origin #272 5.3.3.3.3 Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.3.3.3.x.yml | 52 +++++-------------------------- 1 file changed, 8 insertions(+), 44 deletions(-) diff --git a/tasks/section_5/cis_5.3.3.3.x.yml b/tasks/section_5/cis_5.3.3.3.x.yml index ca5a5dc..8fe6036 100644 --- a/tasks/section_5/cis_5.3.3.3.x.yml +++ b/tasks/section_5/cis_5.3.3.3.x.yml @@ -54,43 +54,10 @@ - patch - rule_5.3.3.3.2 - pam - block: - - name: "5.3.3.3.2 | AUDIT | Ensure password history is enforced for the root user | Check existing files" - ansible.builtin.shell: grep -Psi -- '^\h*password\h+[^#\n\r]+\h+pam_pwhistory\.so\h+([^#\n\r]+\h+)?enforce_for_root\b' /etc/pam.d/{system,password}-auth - register: discovered_pwhistory_enforce_for_root - changed_when: false - failed_when: discovered_pwhistory_enforce_for_root.rc not in [0, 1] - - - name: "5.3.3.3.2 | PATCH| Ensure password history is enforced for the root user | Ensure enforce_for_root is set pwhistory file" - ansible.builtin.lineinfile: - path: "/etc/security/pwhistory.conf" - regexp: ^\s*(?#)enforce_for_root - line: enforce_for_root - - - name: "5.3.3.3.2 | PATCH | Ensure password history is enforced for the root user | Ensure enforce_for_root is set" - when: - - not rhel9cis_allow_authselect_updates - - discovered_pwhistory_enforce_for_root.stdout | length == 0 - - rhel9cis_disruption_high - ansible.builtin.lineinfile: - path: "/{{ rhel9cis_pam_confd_dir }}{{ rhel9cis_pam_pwhistory_file }}" - regexp: ^(password\h+[^#\n\r]+\h+pam_pwhistory\.so\h+)(.*)(enforce_for_root) - line: '\1\2\3 enforce_for_root' - backrefs: true - - - name: "5.3.3.3.2 | PATCH | Ensure password history is enforced for the root user | Ensure enforce_for_root is set" - when: - - rhel9cis_allow_authselect_updates - - discovered_pwhistory_enforce_for_root.stdout | length == 0 - - rhel9cis_disruption_high - ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" - regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwhistory\.so)(.*)\senforce_for_root(.*$) - replace: \1\2enforce_for_root\3 - loop: - - password - - system - notify: Authselect update + ansible.builtin.lineinfile: + path: "/etc/security/pwhistory.conf" + regexp: ^\s*(?#)enforce_for_root + line: enforce_for_root - name: "5.3.3.3.3 | PATCH | Ensure pam_pwhistory includes use_authtok" when: rhel9cis_rule_5_3_3_3_3 @@ -107,22 +74,19 @@ changed_when: false failed_when: discovered_pwhistory_use_authtok.rc not in [0, 1] - - name: "5.3.3.3.3 | PATCH | Ensure pam_pwhistory includes use_authtok | Update pwhistory for use_authtok" - ansible.builtin.lineinfile: - path: "/etc/security/pwhistory.conf" - regexp: ^\s*(?#)use_authtok - line: use_authtok - - name: "5.3.3.3.3 | PATCH | Ensure pam_pwhistory includes use_authtok | Ensure use_authtok is set" when: - not rhel9cis_allow_authselect_updates - discovered_pwhistory_use_authtok.stdout | length == 0 - rhel9cis_disruption_high ansible.builtin.lineinfile: - path: "/{{ rhel9cis_pam_confd_dir }}{{ rhel9cis_pam_pwhistory_file }}" + path: "{{ item }}" regexp: ^(password\h+[^#\n\r]+\h+pam_pwhistory\.so\h+)(.*)(use_authtok) line: '\1\2 use_authtok' backrefs: true + loop: + - /etc/pam.d/password-auth + - /etc/pam.d/system-auth - name: "PATCH | Ensure pam_pwhistory includes use_authtok | add authtok to pam files AuthSelect" when: From 60d4e73bb0c67ab2873ebf50d27fc1ef813b3e1b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:49:55 +0000 Subject: [PATCH 07/42] [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.22.1 → v8.23.0](https://github.com/gitleaks/gitleaks/compare/v8.22.1...v8.23.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 4561cf6..4671271 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.22.1 + rev: v8.23.0 hooks: - id: gitleaks From 6f1fce2fc42044a9514baf7b5452a53eb92c5809 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 17:45:13 +0000 Subject: [PATCH 08/42] [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.23.0 → v8.23.1](https://github.com/gitleaks/gitleaks/compare/v8.23.0...v8.23.1) - [github.com/ansible-community/ansible-lint: v24.12.2 → v25.1.0](https://github.com/ansible-community/ansible-lint/compare/v24.12.2...v25.1.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 4671271..c80dacd 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.23.0 + rev: v8.23.1 hooks: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v24.12.2 + rev: v25.1.0 hooks: - id: ansible-lint name: Ansible-lint From fb73b18596f3d5ad19ee11800e0931bc6defd132 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 22 Jan 2025 08:53:02 +0000 Subject: [PATCH 09/42] Add new pwquality dicovery & title update Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 6602d28..5695843 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -177,14 +177,14 @@ ansible.builtin.set_fact: grub2_path: /etc/grub2-efi.cfg -- name: "PRELIM | Discover Gnome Desktop Environment" +- name: "PRELIM | AUDIT | Discover Gnome Desktop Environment" tags: - always ansible.builtin.stat: path: /usr/share/gnome/gnome-version.xml register: prelim_gnome_present -- name: "PRELIM | Install dconf if gui installed" +- name: "PRELIM | PATCH | Install dconf if gui installed" when: - rhel9cis_gui tags: @@ -243,6 +243,15 @@ mode: 'go-rwx' state: touch +- name: "PRELIM | AUDIT | Capture pam secuirty related files" + tags: always + ansible.builtin.find: + paths: + - /etc/security/pwquality.conf.d/ + - /etc/pam.d/ + patterns: '*-auth,*.conf' + register: prelim_pam_pwquality_confs + - name: "PRELIM | AUDIT | Gather UID 0 accounts other than root" when: rhel9cis_rule_5_4_2_1 tags: @@ -326,7 +335,7 @@ changed_when: false register: prelim_uid_max_id - - name: "PRELIM | AUDIT | set_facts for interactive uid/gid" + - 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 }}" From 5e176d4dc9bf4ce22c4d532cdbc18501b9433e45 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 22 Jan 2025 08:53:27 +0000 Subject: [PATCH 10/42] Use new prelim task for controls based on #273 Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.3.3.2.x.yml | 42 +++++++++++++------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/tasks/section_5/cis_5.3.3.2.x.yml b/tasks/section_5/cis_5.3.3.2.x.yml index 920ed88..702503d 100644 --- a/tasks/section_5/cis_5.3.3.2.x.yml +++ b/tasks/section_5/cis_5.3.3.2.x.yml @@ -18,10 +18,9 @@ path: "{{ item }}" regexp: 'difok\s*=\s*\d+\b' replace: '' - with_fileglob: - - '/etc/security/pwquality.conf' - - '/etc/security/pwquality.conf.d/*.conf' - - /etc/pam.d/*-auth + loop: + - /etc/security/pwquality.conf + - "{{ prelim_pam_pwquality_confs.files | default ([]) }}" - name: "5.3.3.2.1 | PATCH | Ensure password number of changed characters is configured | Ensure difok file exists" ansible.builtin.template: @@ -74,10 +73,9 @@ path: "{{ item }}" regexp: 'minlen\s*=\s*\d+\b' replace: '' - with_fileglob: - - '/etc/security/pwquality.conf' - - '/etc/security/pwquality.conf.d/*.conf' - - '/etc/pam.d/*-auth' + loop: + - /etc/security/pwquality.conf + - "{{ prelim_pam_pwquality_confs.files | default ([]) }}" - name: "5.3.3.2.2 | PATCH | Ensure minimum password length is configured | Ensure minlen file exists" ansible.builtin.template: @@ -130,10 +128,9 @@ path: "{{ item }}" regexp: '(minclass|[dulo]credit)\s*=\s*(-\d|\d+)\b' replace: '' - with_fileglob: - - '/etc/security/pwquality.conf' - - '/etc/security/pwquality.conf.d/*.conf' - - '/etc/pam.d/*-auth' + loop: + - /etc/security/pwquality.conf + - "{{ prelim_pam_pwquality_confs.files | default ([]) }}" - name: "5.3.3.2.3 | PATCH | Ensure password complexity is configured | Ensure complexity file exists" ansible.builtin.template: @@ -184,10 +181,9 @@ path: "{{ item }}" regexp: 'maxrepeat\s*=\s*\d+\b' replace: '' - with_fileglob: - - '/etc/security/pwquality.conf' - - '/etc/security/pwquality.conf.d/*.conf' - - '/etc/pam.d/*-auth' + loop: + - /etc/security/pwquality.conf + - "{{ prelim_pam_pwquality_confs.files | default ([]) }}" - name: "5.3.3.2.4 | PATCH | Ensure password same consecutive characters is configured | Ensure maxrepeat file exists" ansible.builtin.template: @@ -240,10 +236,9 @@ path: "{{ item }}" regexp: 'maxsequence\s*=\s*\d+\b' replace: '' - with_fileglob: - - '/etc/security/pwquality.conf' - - '/etc/security/pwquality.conf.d/*.conf' - - '/etc/pam.d/*-auth' + loop: + - /etc/security/pwquality.conf + - "{{ prelim_pam_pwquality_confs.files | default ([]) }}" - name: "5.3.3.2.5 | PATCH | Ensure password maximum sequential characters is configured | Ensure maxsequence file exists" ansible.builtin.template: @@ -295,10 +290,9 @@ path: "{{ item }}" regexp: 'dictcheck\s*=\s*\d+\b' replace: '' - with_fileglob: - - '/etc/security/pwquality.conf' - - '/etc/security/pwquality.conf.d/*.conf' - - '/etc/pam.d/*-auth' + loop: + - /etc/security/pwquality.conf + - "{{ prelim_pam_pwquality_confs.files | default ([]) }}" - name: "5.3.3.2.6 | PATCH | Ensure password dictionary check is enabled | Ensure dictcheck file exists" ansible.builtin.template: From 7d49c0d27c69419189b8b31f930b10ba1aa7d53f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 22 Jan 2025 14:23:31 +0000 Subject: [PATCH 11/42] added fix for #280 thanks to @msachikanta Signed-off-by: Mark Bolwell --- templates/etc/systemd/system/tmp.mount.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/etc/systemd/system/tmp.mount.j2 b/templates/etc/systemd/system/tmp.mount.j2 index 3f689ee..7f64547 100644 --- a/templates/etc/systemd/system/tmp.mount.j2 +++ b/templates/etc/systemd/system/tmp.mount.j2 @@ -23,7 +23,7 @@ After=swap.target What=tmpfs Where=/tmp Type=tmpfs -Options=mode=1777,strictatime,{% if rhel9cis_rule_1_1_2_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_2_4 %}nosuid,{% endif %}{% if rhel9cis_rule_1_1_2_3 %}noexec{% endif %} +Options=mode=1777,strictatime,{% if rhel9cis_rule_1_1_2_1_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_2_1_3 %}nosuid,{% endif %}{% if rhel9cis_rule_1_1_2_1_4 %}noexec{% endif %} # Make 'systemctl enable tmp.mount' work: [Install] From 9f3d8becf03de14eed78d59f13a6d09d8de2e910 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 22 Jan 2025 16:56:51 +0000 Subject: [PATCH 12/42] Improve logic for 5.3.3.2.x controls Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 5 ++-- tasks/section_5/cis_5.3.3.2.x.yml | 48 +++++++++++++++++++------------ 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 5695843..1ec355b 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -243,13 +243,12 @@ mode: 'go-rwx' state: touch -- name: "PRELIM | AUDIT | Capture pam secuirty related files" +- name: "PRELIM | AUDIT | Capture pam security related files" tags: always ansible.builtin.find: paths: - /etc/security/pwquality.conf.d/ - - /etc/pam.d/ - patterns: '*-auth,*.conf' + patterns: '*.conf' register: prelim_pam_pwquality_confs - name: "PRELIM | AUDIT | Gather UID 0 accounts other than root" diff --git a/tasks/section_5/cis_5.3.3.2.x.yml b/tasks/section_5/cis_5.3.3.2.x.yml index 702503d..e8e1530 100644 --- a/tasks/section_5/cis_5.3.3.2.x.yml +++ b/tasks/section_5/cis_5.3.3.2.x.yml @@ -14,13 +14,15 @@ when: - item != rhel9cis_passwd_difok_file - rhel9cis_disruption_high - ansible.builtin.replace: + ansible.builtin.lineinfile: path: "{{ item }}" regexp: 'difok\s*=\s*\d+\b' - replace: '' + state: absent loop: - /etc/security/pwquality.conf - - "{{ prelim_pam_pwquality_confs.files | default ([]) }}" + - /etc/pam.d/system-auth + - /etc/pam.d/password-auth + - "{{ prelim_pam_pwquality_confs.files | default([]) }}" - name: "5.3.3.2.1 | PATCH | Ensure password number of changed characters is configured | Ensure difok file exists" ansible.builtin.template: @@ -69,13 +71,15 @@ when: - item != rhel9cis_passwd_minlen_file - rhel9cis_disruption_high - ansible.builtin.replace: + ansible.builtin.lineinfile: path: "{{ item }}" regexp: 'minlen\s*=\s*\d+\b' - replace: '' + state: absent loop: - /etc/security/pwquality.conf - - "{{ prelim_pam_pwquality_confs.files | default ([]) }}" + - /etc/pam.d/system-auth + - /etc/pam.d/password-auth + - "{{ prelim_pam_pwquality_confs.files | default([]) }}" - name: "5.3.3.2.2 | PATCH | Ensure minimum password length is configured | Ensure minlen file exists" ansible.builtin.template: @@ -124,13 +128,15 @@ when: - item != rhel9cis_passwd_complex_file - rhel9cis_disruption_high - ansible.builtin.replace: + ansible.builtin.lineinfile: path: "{{ item }}" regexp: '(minclass|[dulo]credit)\s*=\s*(-\d|\d+)\b' - replace: '' + state: absent loop: - /etc/security/pwquality.conf - - "{{ prelim_pam_pwquality_confs.files | default ([]) }}" + - /etc/pam.d/system-auth + - /etc/pam.d/password-auth + - "{{ prelim_pam_pwquality_confs.files | default([]) }}" - name: "5.3.3.2.3 | PATCH | Ensure password complexity is configured | Ensure complexity file exists" ansible.builtin.template: @@ -177,13 +183,15 @@ block: - name: "5.3.3.2.4 | PATCH | Ensure password same consecutive characters is configured | Remove maxrepeat settings from conf files except expected file" when: item != rhel9cis_passwd_maxrepeat_file - ansible.builtin.replace: + ansible.builtin.lineinfile: path: "{{ item }}" regexp: 'maxrepeat\s*=\s*\d+\b' - replace: '' + state: absent loop: - /etc/security/pwquality.conf - - "{{ prelim_pam_pwquality_confs.files | default ([]) }}" + - /etc/pam.d/system-auth + - /etc/pam.d/password-auth + - "{{ prelim_pam_pwquality_confs.files | default([]) }}" - name: "5.3.3.2.4 | PATCH | Ensure password same consecutive characters is configured | Ensure maxrepeat file exists" ansible.builtin.template: @@ -232,13 +240,15 @@ when: - item != rhel9cis_passwd_maxsequence_file - rhel9cis_disruption_high - ansible.builtin.replace: + ansible.builtin.lineinfile: path: "{{ item }}" regexp: 'maxsequence\s*=\s*\d+\b' - replace: '' + state: absent loop: - /etc/security/pwquality.conf - - "{{ prelim_pam_pwquality_confs.files | default ([]) }}" + - /etc/pam.d/system-auth + - /etc/pam.d/password-auth + - "{{ prelim_pam_pwquality_confs.files | default([]) }}" - name: "5.3.3.2.5 | PATCH | Ensure password maximum sequential characters is configured | Ensure maxsequence file exists" ansible.builtin.template: @@ -286,13 +296,15 @@ - name: "5.3.3.2.6 | PATCH | Ensure password dictionary check is enabled | Remove dictcheck settings from conf files except expected file" when: - item != rhel9cis_passwd_dictcheck_file - ansible.builtin.replace: + ansible.builtin.lineinfile: path: "{{ item }}" regexp: 'dictcheck\s*=\s*\d+\b' - replace: '' + state: absent loop: - /etc/security/pwquality.conf - - "{{ prelim_pam_pwquality_confs.files | default ([]) }}" + - /etc/pam.d/system-auth + - /etc/pam.d/password-auth + - "{{ prelim_pam_pwquality_confs.files | default([]) }}" - name: "5.3.3.2.6 | PATCH | Ensure password dictionary check is enabled | Ensure dictcheck file exists" ansible.builtin.template: From ee9258a74b37a449187cf96aa155e5c512db6d3e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 17:53:00 +0000 Subject: [PATCH 13/42] [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.23.1 → v8.23.2](https://github.com/gitleaks/gitleaks/compare/v8.23.1...v8.23.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 c80dacd..a802c69 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.23.1 + rev: v8.23.2 hooks: - id: gitleaks From d1a6f6d2b854de835b9cf5adcfa0a9fc6696f4ee Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 29 Jan 2025 10:27:20 +0000 Subject: [PATCH 14/42] Updated arm discovery Signed-off-by: Mark Bolwell --- tasks/LE_audit_setup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/LE_audit_setup.yml b/tasks/LE_audit_setup.yml index c1fd66e..d784dc1 100644 --- a/tasks/LE_audit_setup.yml +++ b/tasks/LE_audit_setup.yml @@ -7,7 +7,7 @@ audit_pkg_arch_name: AMD64 - name: Pre Audit Setup | Set audit package name | ARM64 - when: ansible_facts.machine == "arm64" + when: (ansible_facts.machine == "arm64" or ansible_facts.machine == "aarch64") ansible.builtin.set_fact: audit_pkg_arch_name: ARM64 @@ -24,7 +24,7 @@ - name: Pre Audit Setup | Copy audit binary when: get_audit_binary_method == 'copy' ansible.builtin.copy: - src: "{{ audit_bin_copy_location }}" + src: "{{ audit_bin_copy_location }}/goss-linux-{{ audit_pkg_arch_name }}" dest: "{{ audit_bin }}" owner: root group: root From c178cba7bc68031f460303fe836e74d89e36827c Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 29 Jan 2025 13:53:58 +0000 Subject: [PATCH 15/42] Updated comments Signed-off-by: Mark Bolwell --- vars/main.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/vars/main.yml b/vars/main.yml index 93439ad..c1d0fb3 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -24,9 +24,11 @@ warn_count: 0 gpg_key_package: "{{ ansible_facts.distribution | lower }}-gpg-keys" -## Control 6.3.3.x - Audit template -# This variable governs if the auditd logic should be executed(if value is true). -# NOTE: The current default value is likely to be overriden(via 'set_fact') by other further tasks(in sub-section 'Auditd rules'). +## Controls 6.3.3.x - Audit template +# This variable is set to true by tasks 6.3.3.1 to 6.3.3.20. As a result, the +# audit settings are overwritten with the role's template. In order to exclude +# specific rules, you must set the variable of form `ubtu24cis_rule_6_3_3_x` above +# to `false`. update_audit_template: false # Defaults From ed1a209635b724b76e96143351559252e5c9cb1f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 29 Jan 2025 13:54:13 +0000 Subject: [PATCH 16/42] Updated audit rules for arch Signed-off-by: Mark Bolwell --- tasks/auditd.yml | 19 +++- templates/audit/99_auditd.rules.j2 | 135 ++++++++++++++++++++++++----- 2 files changed, 129 insertions(+), 25 deletions(-) diff --git a/tasks/auditd.yml b/tasks/auditd.yml index 7022e2c..7b86b94 100644 --- a/tasks/auditd.yml +++ b/tasks/auditd.yml @@ -1,17 +1,30 @@ --- -- name: POST | AUDITD | Apply auditd template will for section 4.1.3 - only required rules will be added | stat file +# Since auditd rules are dependent on syscalls and syscall tables are architecture specific, +# we need to update the auditd rules depending on the architecture of the system. +# This task passed the syscalls table to the auditd template and updates the auditd rules + +- name: "POST | AUDITD | Set supported_syscalls variable" + ansible.builtin.shell: ausyscall --dump | awk '{print $2}' + changed_when: false + failed_when: discovered_auditd_syscalls.rc not in [ 0, 1 ] + register: discovered_auditd_syscalls + +- name: POST | AUDITD | Apply auditd template will for section 6.3.3 - only required rules will be added | stat file ansible.builtin.stat: path: /etc/audit/rules.d/99_auditd.rules register: discovered_auditd_rules_file -- name: POST | AUDITD | Apply auditd template will for section 4.1.3 - only required rules will be added | setup file +- name: POST | Apply auditd template for section 6.3.3.x + when: update_audit_template + vars: + supported_syscalls: "{{ discovered_auditd_syscalls.stdout_lines }}" ansible.builtin.template: src: audit/99_auditd.rules.j2 dest: /etc/audit/rules.d/99_auditd.rules owner: root group: root - mode: '0640' + mode: 'u-x,go-wx' diff: "{{ discovered_auditd_rules_file.stat.exists }}" # Only run diff if not a new file register: discovered_auditd_rules_template_updated notify: diff --git a/templates/audit/99_auditd.rules.j2 b/templates/audit/99_auditd.rules.j2 index e977e4e..cb12736 100644 --- a/templates/audit/99_auditd.rules.j2 +++ b/templates/audit/99_auditd.rules.j2 @@ -9,20 +9,40 @@ -w /etc/sudoers.d -p wa -k scope {% endif %} {% if rhel9cis_rule_6_3_3_2 %} --a always,exit -F arch=b64 -C euid!=uid -F auid!=unset -S execve -k user_emulation --a always,exit -F arch=b32 -C euid!=uid -F auid!=unset -S execve -k user_emulation +{% set syscalls = ["execve"] %} +{% set arch_syscalls = [] %} +{% for syscall in syscalls %} +{% if syscall in supported_syscalls %} +{{ arch_syscalls.append( syscall) }} +{% endif %} +{% endfor %} +-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 %} {% if rhel9cis_rule_6_3_3_3 %} -w {{ rhel9cis_sudolog_location }} -p wa -k sudo_log_file {% endif %} {% if rhel9cis_rule_6_3_3_4 %} --a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time-change --a always,exit -F arch=b32 -S adjtimex,settimeofday,clock_settime -k time-change +{% set arch_syscalls = [] %} +{% for syscall in syscalls %} +{% if syscall in supported_syscalls %} +{{ arch_syscalls.append( syscall) }} +{% endif %} +{% endfor %} +-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 -w /etc/localtime -p wa -k time-change {% endif %} {% if rhel9cis_rule_6_3_3_5 %} --a always,exit -F arch=b64 -S sethostname,setdomainname -F key=system-locale --a always,exit -F arch=b32 -S sethostname,setdomainname -F key=system-locale +{% set syscalls = ["sethostname","setdomainname"] %} +{% set arch_syscalls = [] %} +{% for syscall in syscalls %} +{% if syscall in supported_syscalls %} +{{ arch_syscalls.append( syscall) }} +{% endif %} +{% endfor %} +-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 -w /etc/issue.net -p wa -k system-locale -w /etc/hosts -p wa -k system-locale @@ -35,10 +55,17 @@ {% endfor %} {% endif %} {% if rhel9cis_rule_6_3_3_7 %} --a always,exit -F arch=b64 -S creat,open,openat,truncate,ftruncate -F exit=-EACCES -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access --a always,exit -F arch=b64 -S creat,open,openat,truncate,ftruncate -F exit=-EPERM -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access --a always,exit -F arch=b32 -S creat,open,openat,truncate,ftruncate -F exit=-EACCES -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access --a always,exit -F arch=b32 -S creat,open,openat,truncate,ftruncate -F exit=-EPERM -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access +{% 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 %} +-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 +-a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F exit=-EPERM -F auid=>{{ prelim_min_int_uid }} -F auid!=unset -k access {% endif %} {% if rhel9cis_rule_6_3_3_8 %} -w /etc/group -p wa -k identity @@ -51,16 +78,66 @@ -w /etc/pam.d -p wa -k identity {% endif %} {% if rhel9cis_rule_6_3_3_9 %} --a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>={{ prelim_min_int_uid }} -F auid!=unset -F key=perm_mod --a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>={{ prelim_min_int_uid }} -F auid!=unset -F key=perm_mod --a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>={{ prelim_min_int_uid }} -F auid!=unset -F key=perm_mod --a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F auid>={{ prelim_min_int_uid }} -F auid!=unset -F key=perm_mod --a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>={{ prelim_min_int_uid }} -F auid!=unset -F key=perm_mod --a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>={{ prelim_min_int_uid }} -F auid!=unset -F key=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 %} +-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 %} +-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 %} +-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 %} +-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 %} +-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 %} +-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 %} --a always,exit -F arch=b32 -S mount -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k mounts --a always,exit -F arch=b64 -S mount -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k mounts +{% set syscalls = ["mount"] %} +{% set arch_syscalls = [] %} +{% for syscall in syscalls %} +{% if syscall in supported_syscalls %} +{{ arch_syscalls.append( syscall) }} +{% endif %} +{% endfor %} +-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 %} {% endif %} {% if rhel9cis_rule_6_3_3_11 %} -w /var/run/utmp -p wa -k session @@ -72,8 +149,15 @@ -w /var/run/faillock -p wa -k logins {% endif %} {% if rhel9cis_rule_6_3_3_13 %} --a always,exit -F arch=b64 -S rename,unlink,unlinkat,renameat -F auid>={{ prelim_min_int_uid }} -F auid!=unset -F key=delete --a always,exit -F arch=b32 -S rename,unlink,unlinkat,renameat -F auid>={{ prelim_min_int_uid }} -F auid!=unset -F key=delete +{% set syscalls = ["unlink","unlinkat","rename","renameat"] %} +{% set arch_syscalls = [] %} +{% for syscall in syscalls %} +{% if syscall in supported_syscalls %} +{{ arch_syscalls.append( syscall) }} +{% endif %} +{% endfor %} +-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 %} {% if rhel9cis_rule_6_3_3_14 %} -w /etc/selinux -p wa -k MAC-policy @@ -92,8 +176,15 @@ -a always,exit -F path=/usr/sbin/usermod -F perm=x -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k usermod {% endif %} {% if rhel9cis_rule_6_3_3_19 %} --a always,exit -F arch=b64 -S init_module,finit_module,delete_module,create_module,query_module -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k kernel_modules --a always,exit -F path=/usr/bin/kmod -F perm=x -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k kernel_modules +-a always,exit -F path=/usr/bin/kmod -F perm=x -F auid=>{{ prelim_min_int_uid }} -F auid!=-1 -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 %} +-a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid=>{{ prelim_min_int_uid }} -F auid!=-1 -k kernel_modules {% endif %} {% if rhel9cis_rule_6_3_3_20 %} -e 2 From 91699576985e103d8c03d94d4a0b58038da010b8 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 29 Jan 2025 14:22:24 +0000 Subject: [PATCH 17/42] Updated template Signed-off-by: Mark Bolwell --- templates/audit/99_auditd.rules.j2 | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/audit/99_auditd.rules.j2 b/templates/audit/99_auditd.rules.j2 index cb12736..c162bc0 100644 --- a/templates/audit/99_auditd.rules.j2 +++ b/templates/audit/99_auditd.rules.j2 @@ -138,7 +138,6 @@ -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 %} -{% endif %} {% if rhel9cis_rule_6_3_3_11 %} -w /var/run/utmp -p wa -k session -w /var/log/wtmp -p wa -k session From b9a4503558a966af2fde6d517cca7a2f500aede5 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 30 Jan 2025 10:19:42 +0000 Subject: [PATCH 18/42] Updated and tested rules Signed-off-by: Mark Bolwell --- templates/audit/99_auditd.rules.j2 | 58 +++++++++++++++--------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/templates/audit/99_auditd.rules.j2 b/templates/audit/99_auditd.rules.j2 index c162bc0..b9e632c 100644 --- a/templates/audit/99_auditd.rules.j2 +++ b/templates/audit/99_auditd.rules.j2 @@ -11,11 +11,11 @@ {% if rhel9cis_rule_6_3_3_2 %} {% set syscalls = ["execve"] %} {% set arch_syscalls = [] %} -{% for syscall in syscalls %} +{%- for syscall in syscalls %} {% if syscall in supported_syscalls %} -{{ arch_syscalls.append( syscall) }} +{{ arch_syscalls.append(syscall) }} {% endif %} -{% endfor %} +{% endfor -%} -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 %} @@ -26,7 +26,7 @@ {% set arch_syscalls = [] %} {% for syscall in syscalls %} {% if syscall in supported_syscalls %} -{{ arch_syscalls.append( syscall) }} +{{ arch_syscalls.append(syscall) }} {% endif %} {% endfor %} -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -k time-change @@ -38,7 +38,7 @@ {% set arch_syscalls = [] %} {% for syscall in syscalls %} {% if syscall in supported_syscalls %} -{{ arch_syscalls.append( syscall) }} +{{ arch_syscalls.append(syscall) }} {% endif %} {% endfor %} -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -k system-locale @@ -59,13 +59,13 @@ {% set arch_syscalls = [] %} {% for syscall in syscalls %} {% if syscall in supported_syscalls %} -{{ arch_syscalls.append( syscall) }} +{{ arch_syscalls.append(syscall) }} {% endif %} {% endfor %} --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 --a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F exit=-EPERM -F auid=>{{ prelim_min_int_uid }} -F auid!=unset -k access +-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 +-a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F exit=-EPERM -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access {% endif %} {% if rhel9cis_rule_6_3_3_8 %} -w /etc/group -p wa -k identity @@ -82,61 +82,61 @@ {% set arch_syscalls = [] %} {% for syscall in syscalls %} {% if syscall in supported_syscalls %} -{{ arch_syscalls.append( syscall) }} +{{ arch_syscalls.append(syscall) }} {% endif %} {% endfor %} --a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid=>{{ prelim_min_int_uid }} -F auid!=unset -k perm_mod +-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) }} +{{ arch_syscalls.append(syscall) }} {% endif %} {% endfor %} --a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid=>{{ prelim_min_int_uid }} -F auid!=unset -k perm_mod +-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) }} +{{ arch_syscalls.append(syscall) }} {% endif %} {% endfor %} --a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid=>{{ prelim_min_int_uid }} -F auid!=unset -k perm_mod +-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) }} +{{ arch_syscalls.append(syscall) }} {% endif %} {% endfor %} --a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid=>{{ prelim_min_int_uid }} -F auid!=unset -k perm_mod +-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) }} +{{ arch_syscalls.append(syscall) }} {% endif %} {% endfor %} --a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid=>{{ prelim_min_int_uid }} -F auid!=unset -k perm_mod +-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) }} +{{ arch_syscalls.append(syscall) }} {% endif %} {% endfor %} --a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid=>{{ prelim_min_int_uid }} -F auid!=unset -k perm_mod +-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) }} +{{ arch_syscalls.append(syscall) }} {% endif %} {% endfor %} --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 +-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 %} {% if rhel9cis_rule_6_3_3_11 %} -w /var/run/utmp -p wa -k session @@ -155,8 +155,8 @@ {{ arch_syscalls.append( syscall) }} {% endif %} {% endfor %} --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 +-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 %} {% if rhel9cis_rule_6_3_3_14 %} -w /etc/selinux -p wa -k MAC-policy @@ -175,7 +175,7 @@ -a always,exit -F path=/usr/sbin/usermod -F perm=x -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k usermod {% endif %} {% 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!=-1 -k kernel_modules +-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 %} @@ -183,7 +183,7 @@ {{ arch_syscalls.append( syscall) }} {% endif %} {% endfor %} --a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid=>{{ prelim_min_int_uid }} -F auid!=-1 -k kernel_modules +-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 %} -e 2 From fecfb7e79384aaf4caeaf3c4a7cc078e30bad690 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 30 Jan 2025 12:40:52 +0000 Subject: [PATCH 19/42] addressed issue #282 Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.3.3.3.x.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasks/section_5/cis_5.3.3.3.x.yml b/tasks/section_5/cis_5.3.3.3.x.yml index 8fe6036..9daf71a 100644 --- a/tasks/section_5/cis_5.3.3.3.x.yml +++ b/tasks/section_5/cis_5.3.3.3.x.yml @@ -69,7 +69,7 @@ - pam block: - name: "5.3.3.3.3 | AUDIT | Ensure pam_pwhistory includes use_authtok | Check existing files" - ansible.builtin.shell: grep -Psi -- '^\h*password\h+[^#\n\r]+\h+pam_pwhistory\.so\h+([^#\n\r]+\h+)?use_authtok\b' /etc/pam.d/{system,password}-auth + ansible.builtin.shell: grep -Psic -- '^\h*password\h+[^#\n\r]+\h+pam_pwhistory\.so\h+([^#\n\r]+\h+)?use_authtok\b' /etc/pam.d/{system,password}-auth register: discovered_pwhistory_use_authtok changed_when: false failed_when: discovered_pwhistory_use_authtok.rc not in [0, 1] @@ -81,9 +81,9 @@ - rhel9cis_disruption_high ansible.builtin.lineinfile: path: "{{ item }}" - regexp: ^(password\h+[^#\n\r]+\h+pam_pwhistory\.so\h+)(.*)(use_authtok) - line: '\1\2 use_authtok' - backrefs: true + regexp: ^password\s*pam_pwhistory\.so\s*.*\s(!?use_authtok) + line: password required pam_pwhistory.so use_authtok + insertbefore: ^password.*pam_deny.so loop: - /etc/pam.d/password-auth - /etc/pam.d/system-auth From e121cb4992c1bae9f7fffef8113cb51fe100539c Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 30 Jan 2025 15:34:30 +0000 Subject: [PATCH 20/42] Fix quoting Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.3.2.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/section_5/cis_5.3.2.x.yml b/tasks/section_5/cis_5.3.2.x.yml index ef84113..eadb9b5 100644 --- a/tasks/section_5/cis_5.3.2.x.yml +++ b/tasks/section_5/cis_5.3.2.x.yml @@ -95,7 +95,7 @@ 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: account\s*required\s*pam_faillock.so, before: account\s*required\s*pam_unix.so, line: "account required pam_faillock.so" } - name: "5.3.2.2 | AUDIT | Ensure pam_faillock module is enabled | Add lines password-auth" when: not rhel9cis_allow_authselect_updates @@ -108,7 +108,7 @@ 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: account\s*required\s*pam_faillock.so, before: account\s*required\s*pam_unix.so, line: "account required pam_faillock.so" } - name: "5.3.2.3 | PATCH | Ensure pam_pwquality module is enabled" when: From 761f8517c42f7ad3a23ba9106e23b95c25402b87 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 30 Jan 2025 15:34:42 +0000 Subject: [PATCH 21/42] fix spacing Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.3.3.1.x.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 19e1c44..1730521 100644 --- a/tasks/section_5/cis_5.3.3.1.x.yml +++ b/tasks/section_5/cis_5.3.3.1.x.yml @@ -24,7 +24,7 @@ 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+(.*$) - replace: \1\2\3 + replace: \1 \2\3 loop: - password - system @@ -126,4 +126,3 @@ loop: - password - system - notify: Authselect update From f9478c0e39a0e01898d424839caebf9e188632f6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 18:04:46 +0000 Subject: [PATCH 22/42] [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.23.2 → v8.23.3](https://github.com/gitleaks/gitleaks/compare/v8.23.2...v8.23.3) - [github.com/ansible-community/ansible-lint: v25.1.0 → v25.1.1](https://github.com/ansible-community/ansible-lint/compare/v25.1.0...v25.1.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 a802c69..e4e845e 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.23.2 + rev: v8.23.3 hooks: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.1.0 + rev: v25.1.1 hooks: - id: ansible-lint name: Ansible-lint From 49807a096b9f64016577da6997761005f24b7703 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Fri, 7 Feb 2025 12:20:45 +0000 Subject: [PATCH 23/42] updated logic on 7.2.9 Signed-off-by: Mark Bolwell --- tasks/section_7/cis_7.2.x.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tasks/section_7/cis_7.2.x.yml b/tasks/section_7/cis_7.2.x.yml index 2a33f33..cc1825c 100644 --- a/tasks/section_7/cis_7.2.x.yml +++ b/tasks/section_7/cis_7.2.x.yml @@ -287,15 +287,15 @@ 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 "\.*" -perm /g+w,o+w + ansible.builtin.shell: find /home/ -name "\.*" changed_when: false - failed_when: discovered_homedir_dot_files.rc not in [ 0, 1 ] + failed_when: discovered_homedir_hidden_files.rc not in [ 0, 1 ] check_mode: false - register: discovered_homedir_dot_files + register: discovered_homedir_hidden_files - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Warning on files found" when: - - discovered_homedir_dot_files.stdout | length > 0 + - discovered_homedir_hidden_files.stdout | length > 0 - rhel9cis_dotperm_ansiblemanaged ansible.builtin.debug: msg: @@ -303,16 +303,18 @@ - name: "7.2.9 | PATCH | Ensure local interactive user dot files access is configured | Set warning count" when: - - discovered_homedir_dot_files.stdout | length > 0 + - discovered_homedir_hidden_files.stdout | length > 0 - 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" when: - - discovered_homedir_dot_files.stdout | length > 0 + - discovered_homedir_hidden_files.stdout | length > 0 - rhel9cis_dotperm_ansiblemanaged ansible.builtin.file: path: '{{ item }}' mode: 'go-w' - with_items: "{{ discovered_homedir_dot_files.stdout_lines }}" + 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 }}" + with_items: "{{ discovered_homedir_hidden_files.stdout_lines }}" From 5e722198656c2053f7a192624abbb83184adecc7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 17:53:49 +0000 Subject: [PATCH 24/42] [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.1.1 → v25.1.2](https://github.com/ansible-community/ansible-lint/compare/v25.1.1...v25.1.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 e4e845e..401d32e 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.1.1 + rev: v25.1.2 hooks: - id: ansible-lint name: Ansible-lint From 2078657ceb9994de5142b7a6761edbb5a7733351 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 20 Feb 2025 10:22:11 +0000 Subject: [PATCH 25/42] added fix for #293 thanks to @machikanta Signed-off-by: Mark Bolwell --- defaults/main.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/defaults/main.yml b/defaults/main.yml index 3f6202b..1735ce8 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1303,3 +1303,9 @@ 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.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 +rhel9cis_dotperm_ansiblemanaged: false From d6a560b2c8df1ce22fb111dac7186e92b76d51b7 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 20 Feb 2025 11:54:14 +0000 Subject: [PATCH 26/42] rsyslog_#294 thanks to @alopezgcp Signed-off-by: Mark Bolwell --- defaults/main.yml | 134 +++++++++++++--------- tasks/section_6/cis_6.2.3.x.yml | 4 +- tasks/section_6/main.yml | 1 + templates/etc/logrotate.d/rsyslog.conf.j2 | 11 -- templates/etc/logrotate.d/rsyslog_log.j2 | 26 +++++ 5 files changed, 107 insertions(+), 69 deletions(-) delete mode 100644 templates/etc/logrotate.d/rsyslog.conf.j2 create mode 100644 templates/etc/logrotate.d/rsyslog_log.j2 diff --git a/defaults/main.yml b/defaults/main.yml index 1735ce8..546e0e7 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1100,14 +1100,68 @@ rhel9cis_aide_cron: # ## Preferred method of logging ## Whether rsyslog or journald preferred method for local logging -## Control 6.2.3 | Configure rsyslog -## Control 6.2.1 | Configure journald -# This variable governs which logging service should be used, choosing between 'rsyslog'(CIS recommendation) -# or 'journald'(only one is implemented) will trigger the execution of the associated subsection, as the-best +## 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. rhel9cis_syslog: journald -## Control 6.2.2.x & 6.2.3.x - Ensure rsyslog is not configured to receive logs from a remote client +## 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 +# will not grow without bounds) +# The variables below related to journald, please set these to your site specific values +# These variable specifies how much disk space the journal may use up at most +# Specify values in bytes or use K, M, G, T, P, E as units for the specified sizes. +# See https://www.freedesktop.org/software/systemd/man/journald.conf.html for more information. +rhel9cis_journald_systemmaxuse: 10M +## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy +# Current variable configures the amount of disk space to keep free for other uses. +rhel9cis_journald_systemkeepfree: 100G +## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy +# This variable configures how much disk space the journal may use up at most. +# Similar with 'rhel9cis_journald_systemmaxuse', but related to runtime space. +rhel9cis_journald_runtimemaxuse: 10M +## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy +# This variable configures the actual amount of disk space to keep free +# Similar with 'rhel9cis_journald_systemkeepfree', but related to runtime space. +rhel9cis_journald_runtimekeepfree: 100G +## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy +# Current variable governs the settings for log retention(how long the log files will be kept). +# Thus, it specifies the maximum time to store entries in a single journal +# file before rotating to the next one. Set to 0 to turn off this feature. +# The given values is interpreted as seconds, unless suffixed with the units +# `year`, `month`, `week`, `day`, `h` or `m` to override the default time unit of seconds. +# Values are Xm, Xh, Xday, Xweek, Xmonth, Xyear, for example 2week is two weeks +# 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 +# '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. +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. +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. +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 @@ -1155,57 +1209,25 @@ rhel9cis_remote_log_retrycount: 100 # of rsyslog forwarding must be enabled('rhel9cis_remote_log_server: true'). rhel9cis_remote_log_queuesize: 1000 -## Control 6.2.2.1.2 - Ensure systemd-journal-remote 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. -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. -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. -rhel9cis_journal_trustedcertificatefile: "/etc/ssl/ca/trusted.pem" -# ATTENTION: Uncomment the keyword below when values are set! - -## 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 -# will not grow without bounds) -# The variables below related to journald, please set these to your site specific values -# These variable specifies how much disk space the journal may use up at most -# Specify values in bytes or use K, M, G, T, P, E as units for the specified sizes. -# See https://www.freedesktop.org/software/systemd/man/journald.conf.html for more information. -rhel9cis_journald_systemmaxuse: 10M -## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy -# Current variable configures the amount of disk space to keep free for other uses. -rhel9cis_journald_systemkeepfree: 100G -## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy -# This variable configures how much disk space the journal may use up at most. -# Similar with 'rhel9cis_journald_systemmaxuse', but related to runtime space. -rhel9cis_journald_runtimemaxuse: 10M -## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy -# This variable configures the actual amount of disk space to keep free -# Similar with 'rhel9cis_journald_systemkeepfree', but related to runtime space. -rhel9cis_journald_runtimekeepfree: 100G -## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy -# Current variable governs the settings for log retention(how long the log files will be kept). -# Thus, it specifies the maximum time to store entries in a single journal -# file before rotating to the next one. Set to 0 to turn off this feature. -# The given values is interpreted as seconds, unless suffixed with the units -# `year`, `month`, `week`, `day`, `h` or `m` to override the default time unit of seconds. -# Values are Xm, Xh, Xday, Xweek, Xmonth, Xyear, for example 2week is two weeks -# ATTENTION: Uncomment the keyword below when values are set! -rhel9cis_journald_maxfilesec: 1month +## 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 +rhel9cis_rsyslog_logrotate_rotated_when: weekly +# This 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 +rhel9cis_rsyslog_logrotate_compress: true +rhel9cis_rsyslog_logrotate_missingok: true +rhel9cis_rsyslog_logrotate_notifempty: true +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 # This variable represents the audit backlog limit, i.e., the maximum number of audit records that the diff --git a/tasks/section_6/cis_6.2.3.x.yml b/tasks/section_6/cis_6.2.3.x.yml index 9333697..9d26acf 100644 --- a/tasks/section_6/cis_6.2.3.x.yml +++ b/tasks/section_6/cis_6.2.3.x.yml @@ -256,8 +256,8 @@ - name: "6.2.3.8 | PATCH | Ensure logrotate is configured | set rsyslog conf" ansible.builtin.template: - src: etc/logrotate.d/rsyslog.conf.j2 - dest: /etc/logrotate.d/rsyslog.conf + src: etc/logrotate.d/rsyslog_log.j2 + dest: /etc/logrotate.d/rsyslog_log owner: root group: root mode: 'g-wx,o-rwx' diff --git a/tasks/section_6/main.yml b/tasks/section_6/main.yml index a1909dc..dda7ee5 100644 --- a/tasks/section_6/main.yml +++ b/tasks/section_6/main.yml @@ -5,6 +5,7 @@ file: cis_6.1.x.yml - name: "SECTION | 6.2.1 | Configure systemd-journald service" + when: rhel9cis_syslog == 'journald' ansible.builtin.import_tasks: file: cis_6.2.1.x.yml diff --git a/templates/etc/logrotate.d/rsyslog.conf.j2 b/templates/etc/logrotate.d/rsyslog.conf.j2 deleted file mode 100644 index 2423b24..0000000 --- a/templates/etc/logrotate.d/rsyslog.conf.j2 +++ /dev/null @@ -1,11 +0,0 @@ -/var/log/rsyslog/*.log { - {{ rhel9cis_rsyslog_logrotate_rotated }} - rotate {{ rhel9cis_rsyslog_logrotate_keep }} - {% if rhel9cis_rsyslog_logrotate_compress %}compress{% else %}nocompress{% endif %} - {% if rhel9cis_rsyslog_logrotate_missingok %}missingok{% else %}missingok{% endif %} - {% if rhel9cis_rsyslog_logrotate_notifempty %}notifempty{% else %}ifempty{% endif %} - {% if rhel9cis_rsyslog_logrotate_create %}create {{ rhel9cis_rsyslog_logrotate_create_opts }}{% endif %} - postrotate - /usr/bin/systemctl reload rsyslog.service >/dev/null || true - endscript -} diff --git a/templates/etc/logrotate.d/rsyslog_log.j2 b/templates/etc/logrotate.d/rsyslog_log.j2 new file mode 100644 index 0000000..8acb53e --- /dev/null +++ b/templates/etc/logrotate.d/rsyslog_log.j2 @@ -0,0 +1,26 @@ +/var/log/rsyslog/*.log { + {{ rhel9cis_rsyslog_logrotate_rotated_when }} + rotate {{ rhel9cis_rsyslog_logrotate_rotatation_keep }} +{% if rhel9cis_rsyslog_logrotate_compress %} + compress +{% else %} + nocompress +{% endif %} +{% if rhel9cis_rsyslog_logrotate_missingok %} + missingok +{% else %} + nomissingok +{% endif %} +{% if rhel9cis_rsyslog_logrotate_notifempty %} + notifempty +{% else %} + ifempty +{% endif %} +{% if rhel9cis_rsyslog_logrotate_create %} + create{% if rhel9cis_rsyslog_logrotate_create_opts is defined %} {{ rhel9cis_rsyslog_logrotate_create_opts }}{% endif %} +{% endif %} + + postrotate + /usr/bin/systemctl reload rsyslog.service >/dev/null || true + endscript +} From 3441894ab4392a3619e68c6beb35cdce9bc69a81 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 20 Feb 2025 11:55:59 +0000 Subject: [PATCH 27/42] Lint update Signed-off-by: Mark Bolwell --- defaults/main.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 546e0e7..f5c38b1 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1211,7 +1211,7 @@ rhel9cis_remote_log_queuesize: 1000 ## 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 +# Please refer to logrotate options to match your site requirements # This sets when to rotate rhel9cis_rsyslog_logrotate_rotated_when: weekly # This sets how many rotations of the file to keep @@ -1227,7 +1227,7 @@ rhel9cis_rsyslog_logrotate_notifempty: true 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: +# rhel9cis_rsyslog_logrotate_create_opts: ## Control 6.3.2.1 - Ensure audit_backlog_limit is sufficient # This variable represents the audit backlog limit, i.e., the maximum number of audit records that the @@ -1326,7 +1326,6 @@ rhel9cis_suid_sgid_adjust: false # 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.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 From eb77cdd36763e65a9dabf3c08238f4684b3fbe66 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 20 Feb 2025 11:56:30 +0000 Subject: [PATCH 28/42] Added precommit exclusion Signed-off-by: Mark Bolwell --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index f67408e..de8046f 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ benchparse/ # GitHub Action/Workflow files .github/ + +# Precommit exclusions +.ansible/ From f9c7ff5949c6b476bc8cf7df6ee5fddd0fc57a6d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 17:24:15 +0000 Subject: [PATCH 29/42] [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.23.3 → v8.24.0](https://github.com/gitleaks/gitleaks/compare/v8.23.3...v8.24.0) - [github.com/ansible-community/ansible-lint: v25.1.2 → v25.1.3](https://github.com/ansible-community/ansible-lint/compare/v25.1.2...v25.1.3) --- .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 401d32e..4791982 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.23.3 + rev: v8.24.0 hooks: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v25.1.2 + rev: v25.1.3 hooks: - id: ansible-lint name: Ansible-lint From 8cc3738fda2c745b73bd1f7c36342084479d5fda Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 26 Feb 2025 08:23:24 +0000 Subject: [PATCH 30/42] added pre-commit badge Signed-off-by: Mark Bolwell --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a16287d..d3bf75a 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ ![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) ![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) From 48a471a037ccb4cc67658f1e50ede9d22d1d3f93 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 26 Feb 2025 08:23:46 +0000 Subject: [PATCH 31/42] issue #296 thanks to @dbsanders Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.4.2.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_5/cis_5.4.2.x.yml b/tasks/section_5/cis_5.4.2.x.yml index ef15f1a..12390b3 100644 --- a/tasks/section_5/cis_5.4.2.x.yml +++ b/tasks/section_5/cis_5.4.2.x.yml @@ -190,7 +190,7 @@ regexp: \s*umask line: "umask {{ rhel9cis_root_umask }}" create: true - mode: 'u+x,go-rwx' + mode: 'u-x,go-rwx' - name: "5.4.2.7 | PATCH | Ensure system accounts do not have a valid login shell" when: From 5c919fb19da8e7216e690dca9ade67b1d523d412 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 26 Feb 2025 08:27:12 +0000 Subject: [PATCH 32/42] added #298 & #299 thanks to @brent-bean Signed-off-by: Mark Bolwell --- tasks/section_6/cis_6.2.2.1.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 00e949b..945c2e4 100644 --- a/tasks/section_6/cis_6.2.2.1.x.yml +++ b/tasks/section_6/cis_6.2.2.1.x.yml @@ -17,7 +17,7 @@ name: systemd-journal-remote state: present -- name: "6.2.2.1.2 | PATCH | Ensure systemd-journal-remote authentication is configured" +- name: "6.2.2.1.2 | PATCH | Ensure systemd-journal-upload authentication is configured" when: - rhel9cis_rule_6_2_2_1_2 - not rhel9cis_system_is_log_server @@ -40,7 +40,7 @@ - { regexp: 'ServerCertificateFile=', line: 'ServerCertificateFile={{ rhel9cis_journal_servercertificatefile }}'} - { regexp: 'TrustedCertificateFile=', line: 'TrustedCertificateFile={{ rhel9cis_journal_trustedcertificatefile }}'} -- name: "6.2.2.1.3 | PATCH | Ensure systemd-journal-remote is enabled and active" +- name: "6.2.2.1.3 | PATCH | Ensure systemd-journal-upload is enabled and active" when: - not rhel9cis_system_is_log_server - rhel9cis_rule_6_2_2_1_3 From 40078515fe95fa31cab24e4bd00c3c0e7eec370c Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 26 Feb 2025 11:01:35 +0000 Subject: [PATCH 33/42] updated 1.4.2 thanks to @brent-bean #300 Signed-off-by: Mark Bolwell --- handlers/main.yml | 9 ++++++++ tasks/section_1/cis_1.4.x.yml | 40 +++++++++++++++++++++++++++++++---- vars/main.yml | 3 +++ 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/handlers/main.yml b/handlers/main.yml index 3c51ddf..1a3b66e 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -144,6 +144,15 @@ state: remounted listen: "Remount /var/log/audit" +- name: "Remounting /boot/efi" + vars: + mount_point: '/boot/efi' + ansible.posix.mount: + path: "{{ mount_point }}" + state: remounted + notify: Change_requires_reboot + listen: "Remount /boot/efi" + - name: Reload sysctl ansible.builtin.command: sysctl --system changed_when: true diff --git a/tasks/section_1/cis_1.4.x.yml b/tasks/section_1/cis_1.4.x.yml index d422f14..ee941c0 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -29,7 +29,8 @@ - rule_1.4.2 - NIST800-53R5_AC-3 block: - - name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured" + - name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured | bios based system" + when: rhel9cis_legacy_boot ansible.builtin.file: path: "/boot/grub2/{{ item.path }}" owner: root @@ -39,6 +40,37 @@ modification_time: preserve access_time: preserve loop: - - { path: 'grub.cfg', mode: '0700' } - - { path: 'grubenv', mode: 'go-rwx' } - - { path: 'user.cfg', mode: 'go-rwx' } + - { path: 'grub.cfg', mode: 'u-x,go-rwx' } + - { path: 'grubenv', mode: 'u-x,go-rwx' } + - { path: 'user.cfg', mode: 'u-x,go-rwx' } + + - name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured | efi based system" + when: not rhel9cis_legacy_boot + vars: + efi_mount_options: ['umask=0077','fmask=0077','uid=0','gid=0'] + block: + - 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' | cut -d ' ' -f4 + changed_when: false + register: discovered_efi_fstab + + - 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 + ',' }}" + loop: "{{ efi_mount_options }}" + + - name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured | efi based system | Add mount options" + ansible.builtin.lineinfile: + path: /etc/fstab + regexp: (.*/boot/efi\s*\w*\s*){{ discovered_efi_fstab.stdout }}(.*) + line: \1{{ discovered_efi_fstab.stdout + efi_mount_opts_addition }}\2 + backrefs: true + notify: Remount /boot/efi + + - debug: + msg: + - "{{ discovered_efi_fstab.stdout }}" + - "{{ efi_mount_opts_addition }}" + + - pause: diff --git a/vars/main.yml b/vars/main.yml index c1d0fb3..cdca90d 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -22,6 +22,9 @@ rhel9cis_allowed_crypto_policies_modules: warn_control_list: "" warn_count: 0 +# Default empty values for 1.4.2 +efi_mount_opts_addition: '' + gpg_key_package: "{{ ansible_facts.distribution | lower }}-gpg-keys" ## Controls 6.3.3.x - Audit template From d6fb1734e3a3b9b4104e19e65f91813026fe2217 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 26 Feb 2025 11:27:36 +0000 Subject: [PATCH 34/42] fixed thanks to @brent-bean #301 Signed-off-by: Mark Bolwell --- templates/audit/99_auditd.rules.j2 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/templates/audit/99_auditd.rules.j2 b/templates/audit/99_auditd.rules.j2 index b9e632c..66ef19d 100644 --- a/templates/audit/99_auditd.rules.j2 +++ b/templates/audit/99_auditd.rules.j2 @@ -23,6 +23,7 @@ -w {{ rhel9cis_sudolog_location }} -p wa -k sudo_log_file {% endif %} {% if rhel9cis_rule_6_3_3_4 %} +{% set syscalls = ["adjtimex","settimeofday"] %} {% set arch_syscalls = [] %} {% for syscall in syscalls %} {% if syscall in supported_syscalls %} @@ -31,6 +32,14 @@ {% endfor %} -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) }} +-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 %} From 12be5388ffb49d508a49b4fb3dd0278b6ae9f639 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 26 Feb 2025 12:26:19 +0000 Subject: [PATCH 35/42] improved logic Signed-off-by: Mark Bolwell --- tasks/section_1/cis_1.4.x.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tasks/section_1/cis_1.4.x.yml b/tasks/section_1/cis_1.4.x.yml index ee941c0..004bfca 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -50,7 +50,7 @@ efi_mount_options: ['umask=0077','fmask=0077','uid=0','gid=0'] block: - 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' | cut -d ' ' -f4 + ansible.builtin.shell: grep "^[^#;]" /etc/fstab | grep '/boot/efi' | awk -F" " '{print $4}' changed_when: false register: discovered_efi_fstab @@ -67,10 +67,3 @@ line: \1{{ discovered_efi_fstab.stdout + efi_mount_opts_addition }}\2 backrefs: true notify: Remount /boot/efi - - - debug: - msg: - - "{{ discovered_efi_fstab.stdout }}" - - "{{ efi_mount_opts_addition }}" - - - pause: From ed1bc1c074ad0c626d6a184f141f3712bd96db50 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 26 Feb 2025 12:26:46 +0000 Subject: [PATCH 36/42] 7.1.10 extended in case file absent Signed-off-by: Mark Bolwell --- tasks/section_7/cis_7.1.x.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasks/section_7/cis_7.1.x.yml b/tasks/section_7/cis_7.1.x.yml index 83c83a0..b23fb89 100644 --- a/tasks/section_7/cis_7.1.x.yml +++ b/tasks/section_7/cis_7.1.x.yml @@ -169,6 +169,8 @@ owner: root group: root mode: 'u-x,go-wx' + failed_when: discovered_file_exists.state not in '[ file, absent ]' + register: discovered_file_exists - name: "7.1.11 | PATCH | Ensure world writable files and directories are secured" when: From 8cd7d765c52737bc334599be7fd923299cef19c2 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 26 Feb 2025 12:26:58 +0000 Subject: [PATCH 37/42] updated layout Signed-off-by: Mark Bolwell --- templates/audit/99_auditd.rules.j2 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/templates/audit/99_auditd.rules.j2 b/templates/audit/99_auditd.rules.j2 index 66ef19d..4d9c0d3 100644 --- a/templates/audit/99_auditd.rules.j2 +++ b/templates/audit/99_auditd.rules.j2 @@ -37,6 +37,7 @@ {% for syscall in syscalls %} {% if syscall in supported_syscalls %} {{ arch_syscalls.append(syscall) }} +-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 %} @@ -50,8 +51,8 @@ {{ arch_syscalls.append(syscall) }} {% endif %} {% endfor %} --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 +-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 -w /etc/issue.net -p wa -k system-locale -w /etc/hosts -p wa -k system-locale @@ -178,7 +179,7 @@ -a always,exit -F path=/usr/bin/setfacl -F perm=x -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_chng {% endif %} {% if rhel9cis_rule_6_3_3_17 %} --a always,exit -F path=/usr/bin/chacl -F perm=x -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k priv_chng +-a always,exit -F path=/usr/bin/chacl -F perm=x -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_chng {% endif %} {% if rhel9cis_rule_6_3_3_18 %} -a always,exit -F path=/usr/sbin/usermod -F perm=x -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k usermod From 5a612675e2e8ca9e03a8281c390b0cde8c9e1f29 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 26 Feb 2025 14:04:01 +0000 Subject: [PATCH 38/42] improve authselect logic Signed-off-by: Mark Bolwell --- tasks/main.yml | 8 +------- tasks/section_5/cis_5.3.2.x.yml | 4 +--- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index 2e5049c..a0a58f8 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -116,17 +116,11 @@ 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 current | head -1 | awk '{print $NF}' + ansible.builtin.shell: authselect list changed_when: false failed_when: prelim_authselect_current_profile.rc not in [ 0, 1 ] register: prelim_authselect_current_profile - - name: "Check authselect profile is selected | Ensure profile name is set" - ansible.builtin.assert: - that: prelim_authselect_current_profile is defined - success_msg: "Authselect is running and profile is selected" - fail_msg: Authselect updates have been selected there are issues with profile selection" - - name: "Ensure root password is set" when: rhel9cis_rule_5_4_2_4 tags: diff --git a/tasks/section_5/cis_5.3.2.x.yml b/tasks/section_5/cis_5.3.2.x.yml index eadb9b5..5917019 100644 --- a/tasks/section_5/cis_5.3.2.x.yml +++ b/tasks/section_5/cis_5.3.2.x.yml @@ -14,9 +14,7 @@ - rule_5.3.2.1 block: - name: "5.3.2.1 | PATCH | Ensure active authselect profile includes pam modules | Create custom profiles" - when: - - rhel9cis_authselect_custom_profile_name not in prelim_authselect_current_profile.stdout or - prelim_authselect_current_profile.stdout is not defined + when: rhel9cis_authselect_custom_profile_name not in prelim_authselect_current_profile.stdout ansible.builtin.command: "/usr/bin/authselect create-profile {{ rhel9cis_authselect_custom_profile_name }} -b {{ rhel9cis_authselect_default_profile_to_copy }}" changed_when: false args: From 74f17b7ee8e052f11cb2d830fd3d1c4c7573dea1 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 26 Feb 2025 14:04:13 +0000 Subject: [PATCH 39/42] updated logic Signed-off-by: Mark Bolwell --- tasks/section_6/cis_6.2.4.1.yml | 42 ++++++++++++++------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/tasks/section_6/cis_6.2.4.1.yml b/tasks/section_6/cis_6.2.4.1.yml index 814c46c..9e8b9b3 100644 --- a/tasks/section_6/cis_6.2.4.1.yml +++ b/tasks/section_6/cis_6.2.4.1.yml @@ -8,6 +8,8 @@ - patch - logfiles - rule_6.2.4.1 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 block: - name: "6.2.4.1 | AUDIT | Ensure access to all logfiles has been configured | find log files" ansible.builtin.shell: find /var/log/ -type f -exec ls {} \; @@ -15,43 +17,35 @@ failed_when: false register: discovered_logfiles - - name: "6.2.4.1 | PATCH | Ensure access to all logfiles has been configured | change permissions" + - name: "6.2.4.1 | PATCH | Ensure access to all logfiles has been configured | change permissions SSSD min 660" when: - discovered_logfiles.stdout_lines | length > 0 - - ('audit.log' in item or 'journal' in item) or - item == '/var/log/secure' or - item == '/var/log/syslog' or - item == '/var/log/messages' or - item == '/var/log/auth.log' + - item is match("/var/log/(gdm|sssd)") ansible.builtin.file: path: "{{ item }}" - mode: 'u-x,g-wx,o-rwx' + mode: 'ug-x,o-rwx' failed_when: discovered_logfile_list.state not in '[ file, absent ]' register: discovered_logfile_list loop: "{{ discovered_logfiles.stdout_lines }}" - - name: "6.2.4.1 | PATCH | Ensure access to all logfiles has been configured | change permissions" + - name: "6.2.4.1 | PATCH | Ensure access to all logfiles has been configured | change permissions tmp min 664" when: - discovered_logfiles.stdout_lines | length > 0 - - ('anaconda' in item or 'dnf' in item or 'secure' in item or 'messages' in item or 'hawkey' in item) - ansible.builtin.file: - path: "{{ item }}" - mode: 'u-x,g-x,o-rwx' - failed_when: discovered_logfile_list.state not in '[ file, absent ]' - register: discovered_logfile_list - loop: "{{ discovered_logfiles.stdout_lines }}" - - - name: "6.2.4.1 | PATCH | Ensure access to all logfiles has been configured | change permissions" - when: - - discovered_logfiles.stdout_lines | length > 0 - - ('sssd' in item or 'lastlog' in item) or - item == "/var/log/btmp" or - item == "/var/log/utmp" or - item == "/var/log/wtmp" or - item == "/var/log/lastlog" + - item is match("/var/log/((u|b|w)tmp*|lastlog)") ansible.builtin.file: path: "{{ item }}" mode: 'ug-x,o-wx' failed_when: discovered_logfile_list.state not in '[ file, absent ]' register: discovered_logfile_list loop: "{{ discovered_logfiles.stdout_lines }}" + + - name: "6.2.4.1 | PATCH | Ensure access to all logfiles has been configured | change permissions else all 640" + when: + - discovered_logfiles.stdout_lines | length > 0 + - item is not match("/var/log/((u|b|w)tmp*|lastlog|sssd)") + ansible.builtin.file: + path: "{{ item }}" + mode: 'u-x,g-wx,o-rwx' + failed_when: discovered_logfile_list.state not in '[ file, absent ]' + register: discovered_logfile_list + loop: "{{ discovered_logfiles.stdout_lines }}" From 4d8cc6eb607ebc8d7f3b481de0736763a118acea Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 26 Feb 2025 14:04:22 +0000 Subject: [PATCH 40/42] updated minclass Signed-off-by: Mark Bolwell --- defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults/main.yml b/defaults/main.yml index f5c38b1..da5ca20 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -923,7 +923,7 @@ rhel9cis_passwd_complex_file: etc/security/pwquality.conf.d/50-pwcomplexity.conf # Options are: minclass or credits # ensure only one is selected rhel9cis_passwd_complex_option: minclass # pragma: allowlist secret -rhel9cis_passwd_minclass: 3 +rhel9cis_passwd_minclass: 4 # rhel9cis_passwd_complex: credits rhel9cis_passwd_dcredit: -1 rhel9cis_passwd_ucredit: -2 From 1bfde74ad6ce5385fbdfc2f9d99456f66d6a3f67 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 27 Feb 2025 13:02:54 +0000 Subject: [PATCH 41/42] Improve logic Signed-off-by: Mark Bolwell --- tasks/section_1/cis_1.4.x.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasks/section_1/cis_1.4.x.yml b/tasks/section_1/cis_1.4.x.yml index 004bfca..8d8c21b 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -57,10 +57,11 @@ - 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" + when: efi_mount_opts_addition | length > 0 ansible.builtin.lineinfile: path: /etc/fstab regexp: (.*/boot/efi\s*\w*\s*){{ discovered_efi_fstab.stdout }}(.*) From a1a719fbe7026dbf0d550bc8b394a09fac7b1890 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Thu, 27 Feb 2025 13:47:25 +0000 Subject: [PATCH 42/42] lint update Signed-off-by: Mark Bolwell --- tasks/section_1/cis_1.4.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_1/cis_1.4.x.yml b/tasks/section_1/cis_1.4.x.yml index 8d8c21b..d3534cd 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -47,7 +47,7 @@ - name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured | efi based system" when: not rhel9cis_legacy_boot vars: - efi_mount_options: ['umask=0077','fmask=0077','uid=0','gid=0'] + efi_mount_options: ['umask=0077', 'fmask=0077', 'uid=0', 'gid=0'] block: - 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}'