diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c25682f..2561fb5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -42,13 +42,13 @@ repos: name: Detect Secrets test - repo: https://github.com/gitleaks/gitleaks - rev: v8.26.0 + rev: v8.27.2 hooks: - id: gitleaks name: Run Gitleaks test - repo: https://github.com/ansible-community/ansible-lint - rev: v25.5.0 + rev: v25.6.1 hooks: - id: ansible-lint name: Ansible-lint diff --git a/Changelog.md b/Changelog.md index 8ca9c4f..b6db646 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,7 +8,6 @@ - Improved documentation and variable compilation for crypto policies - Addresses #318 - Thank you @kodebach & @bgro - Improved logic for 5.2.4 to exclude rhel9cis_sudoers_exclude_nopasswd_list in pre-check tasks/main.yml -- rule_6.3.3.5 updated for missing checks ## 2.0.1 - Based on CIS v2.0.0 @@ -20,9 +19,8 @@ ## 2.0.0 - Based on CIS v2.0.0 -- #325 - thanks to @mindrb -- May 2025 QA Fixes - - Typo fixes and Banner verbiage +- #322, #325 - thanks to @mindrb +- #320 - thanks to @anup-ad ## 1.1.6 - Based on CIS v1.0.0 @@ -38,7 +36,7 @@ - updated controls 6.2.10-6.2.14 - audit - steps moved to prelim - - update to copy and archive logic and variables + - update to coipy and archive logic and variables - removed vars not used - updated quotes used in mode tasks - pre-commit update @@ -72,7 +70,7 @@ - lint updates - .secrets updated - file mode quoted -- updated 5.6.5 thanks to feedback from S!ghs on discord community +- updated 5.6.5 thansk to feedback from S!ghs on discord community ## 1.1.1 - Based on CIS v1.0.0 @@ -104,7 +102,7 @@ ## 1.0.10 - [#72](https://github.com/ansible-lockdown/RHEL9-CIS/issues/72) - - Only run check when playbook user not a superuser + - Only run check when paybook user not a superuser - fix for 5.5.3 thanks to @nrg-fv ## 1.0.9 @@ -176,7 +174,7 @@ Jan-2023 release - updated ansible minimum to 2.10 - Lint file updates and improvements -- auditd now shows diff after initial template added +- auditd now shows diff ater initial template added - many control rewritten - Many controls moved ID references - Audit updates aligned @@ -241,11 +239,11 @@ Jan-2023 release - not all controls work with rhel8 releases any longer - selinux disabled 1.6.1.4 - logrotate - 4.3.x -- updated to rhel8cis v2.0 benchmark requirements +- updated to rhel8cis v2.0 benchamrk requirements - removed iptables firewall controls (not valid on rhel9) -- added more to logrotate 4.3.x - sure to logrotate now a separate package +- added more to logrotate 4.3.x - sure to logrotate now a seperate package - grub path now standard to /boot/grub2/grub.cfg -- 1.6.1.4 from rh8 removed as selinux.cfg doesn't disable selinux any longer +- 1.6.1.4 from rh8 removed as selinux.cfg doesnt disable selinux any longer - workflow update - removed doc update diff --git a/tasks/main.yml b/tasks/main.yml index 9582bed..7912aca 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -101,7 +101,7 @@ ansible.builtin.assert: that: (not prelim_ansible_user_password_set.stdout.startswith("!")) or (ansible_env.SUDO_USER in rhel9cis_sudoers_exclude_nopasswd_list) fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_env.SUDO_USER }} is locked - It can break access" - success_msg: "The local account is not locked for {{ ansible_env.SUDO_USER }} is not locked or included in the exception list for rule 5.2.4" + success_msg: "The local account {{ ansible_env.SUDO_USER }} is not locked or included in the exception list for rule 5.2.4" - name: "Check authselect profile is selected" when: rhel9cis_allow_authselect_updates @@ -131,6 +131,7 @@ - name: "Ensure root password is set" ansible.builtin.shell: passwd -S root | grep -E "(Password set, SHA512 crypt|Password locked)" changed_when: false + failed_when: prelim_root_passwd_set.rc not in [ 0, 1 ] register: prelim_root_passwd_set - name: "Ensure root password is set" diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 80decfd..3e2d4cd 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -305,6 +305,7 @@ tags: always ansible.builtin.shell: grep ^log_file /etc/audit/auditd.conf | awk '{ print $NF }' changed_when: false + check_mode: false register: prelim_auditd_logfile - name: "PRELIM | AUDIT | Audit conf and rules files | list files" diff --git a/tasks/section_6/cis_6.1.x.yml b/tasks/section_6/cis_6.1.x.yml index a162da1..1db531b 100644 --- a/tasks/section_6/cis_6.1.x.yml +++ b/tasks/section_6/cis_6.1.x.yml @@ -123,7 +123,6 @@ /usr/sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512 /usr/sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512 /usr/sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512 - validate: aide -D --config %s register: aide_file_integrity_check failed_when: - not ansible_check_mode diff --git a/tasks/section_6/cis_6.2.2.x.yml b/tasks/section_6/cis_6.2.2.x.yml index a57efe2..fe0f8c4 100644 --- a/tasks/section_6/cis_6.2.2.x.yml +++ b/tasks/section_6/cis_6.2.2.x.yml @@ -50,7 +50,7 @@ - name: "6.2.2.3 | PATCH | Ensure journald Compress is configured | comment out current entries" ansible.builtin.replace: path: /etc/systemd/journald.conf - regexp: ^(?i)(\s*compress=) + regexp: (?i)(\s*compress=) replace: '#\1' - name: "6.2.2.4 | PATCH | Ensure journald Storage is configured" @@ -76,5 +76,5 @@ - name: "6.2.2.4 | PATCH | Ensure journald Storage is configured | comment out current entries" ansible.builtin.replace: path: /etc/systemd/journald.conf - regexp: ^(?i)(\s*storage=) + regexp: (?i)(\s*storage=) replace: '#\1' diff --git a/tasks/section_7/cis_7.2.x.yml b/tasks/section_7/cis_7.2.x.yml index 3be2ad3..debc9a6 100644 --- a/tasks/section_7/cis_7.2.x.yml +++ b/tasks/section_7/cis_7.2.x.yml @@ -286,8 +286,8 @@ vars: warn_control_id: '7.2.9' block: - - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Check for files" - ansible.builtin.shell: find /home/ -name "\.*" + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured" + ansible.builtin.shell: find {{ prelim_interactive_users_home.stdout_lines | list | join(' ') }} -name "\.*" -type f changed_when: false failed_when: discovered_homedir_hidden_files.rc not in [ 0, 1 ] check_mode: false @@ -296,25 +296,63 @@ - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Warning on files found" when: - discovered_homedir_hidden_files.stdout | length > 0 - - rhel9cis_dotperm_ansiblemanaged + - not rhel9cis_dotperm_ansiblemanaged ansible.builtin.debug: msg: - - "Warning!! We have discovered group or world-writable dot files on your system and this host is configured for manual intervention. Please investigate these files further." + - "Warning!! Please investigate that hidden files found in users home directories match control requirements." - - name: "7.2.9 | PATCH | Ensure local interactive user dot files access is configured | Set warning count" + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Set warning count" when: - discovered_homedir_hidden_files.stdout | length > 0 - - rhel9cis_dotperm_ansiblemanaged + - not rhel9cis_dotperm_ansiblemanaged ansible.builtin.import_tasks: file: warning_facts.yml - - name: "7.2.9 | PATCH | Ensure local interactive user dot files access is configured | Changes files if configured" + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured" when: - discovered_homedir_hidden_files.stdout | length > 0 - rhel9cis_dotperm_ansiblemanaged - ansible.builtin.file: - path: '{{ item }}' - mode: 'go-w' - owner: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_raw.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='uid') | last }}" - group: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_raw.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='gid') | last }}" - with_items: "{{ discovered_homedir_hidden_files.stdout_lines }}" + block: + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Changes files if configured .bash_history & .netrc" + when: + - discovered_homedir_hidden_files.stdout | length > 0 + - item | basename in ['.bash_history','.netrc'] + ansible.builtin.file: + path: "{{ item }}" + mode: 'u-x,go-rwx' + failed_when: discovered_dot_bash_history_to_change.state not in '[ file, absent ]' + register: discovered_dot_bash_history_to_change + loop: "{{ discovered_homedir_hidden_files.stdout_lines }}" + + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Changes files if configured file mode" + ansible.builtin.file: + path: '{{ item }}' + mode: 'u-x,go-wx' + failed_when: discovered_dot_bash_history_to_change.state not in '[ file, absent ]' + register: discovered_dot_bash_history_to_change + loop: "{{ discovered_homedir_hidden_files.stdout_lines }}" + + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | Changes files ownerships" + ansible.builtin.file: + path: "{{ item }}" + owner: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='uid') | last }}" + group: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='gid') | last }}" + failed_when: discovered_dot_bash_history_to_change.state not in '[ file, absent ]' + register: discovered_dot_bash_history_to_change + loop: "{{ discovered_homedir_hidden_files.stdout_lines }}" + + - name: "7.2.9 | PATCH | Ensure local interactive user dot files access is configured | Changes files if configured" + ansible.builtin.file: + path: '{{ item }}' + mode: 'go-w' + owner: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='uid') | last }}" + group: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_home.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='gid') | last }}" + with_items: "{{ discovered_homedir_hidden_files.stdout_lines }}" + + - name: "7.2.9 | AUDIT | Ensure local interactive user dot files access is configured | rename .forward or .rhosts files" + when: + - item | basename in ['.forward','.rhosts'] + - item is not search ("CIS") + ansible.builtin.command: "mv {{ item }} {{ item }}_CIS_TOBEREVIEWED" + changed_when: true + loop: "{{ discovered_homedir_hidden_files.stdout_lines }}" diff --git a/templates/ansible_vars_goss.yml.j2 b/templates/ansible_vars_goss.yml.j2 index ad44fb3..7cb906b 100644 --- a/templates/ansible_vars_goss.yml.j2 +++ b/templates/ansible_vars_goss.yml.j2 @@ -34,7 +34,7 @@ rhel9cis_selinux_disable: {{ rhel9cis_selinux_disable }} # UEFI boot('/etc/grub2-efi.cfg') or in case of BIOS legacy-boot('/etc/grub2.cfg'). rhel9cis_legacy_boot: {{ rhel9cis_legacy_boot }} -## Benchmark name used by audting control role +## Benchmark name used by auditing control role # The audit variable found at the base ## metadata for Audit benchmark benchmark_version: 'v2.0.0' @@ -151,7 +151,7 @@ rhel9cis_rule_1_8_8: {{ rhel9cis_rule_1_8_8 }} rhel9cis_rule_1_8_9: {{ rhel9cis_rule_1_8_9 }} rhel9cis_rule_1_8_10: {{ rhel9cis_rule_1_8_10 }} -# Section 2 rules are controling Services (Special Purpose Services, and service clients) +# Section 2 rules are controlling Services (Special Purpose Services, and service clients) ## Configure Server Services rhel9cis_rule_2_1_1: {{ rhel9cis_rule_2_1_1 }} rhel9cis_rule_2_1_2: {{ rhel9cis_rule_2_1_2 }} @@ -625,21 +625,21 @@ rhel9cis_authselect_custom_profile_name: {{ rhel9cis_authselect_custom_profile_n # These are discovered via logins.def if set true rhel9cis_discover_int_uid: {{ rhel9cis_discover_int_uid }} # This variable sets the minimum number from which to search for UID -# Note that the value will be dynamically overwritten if variable `dicover_int_uid` has +# Note that the value will be dynamically overwritten if variable `discover_int_uid` has # been set to `true`. min_int_uid: 1000 ### Controls: # - Ensure local interactive user home directories exist # - Ensure local interactive users own their home directories # This variable sets the maximum number at which the search stops for UID -# Note that the value will be dynamically overwritten if variable `dicover_int_uid` has +# Note that the value will be dynamically overwritten if variable `discover_int_uid` has # been set to `true`. max_int_uid: 65533 ## Section6 vars ## Control 6.1.2 AIDE schedule -# how aide sceduler runs can be one of cron or timer +# how aide scheduler runs can be one of cron or timer rhel9cis_aide_scan: {{ rhel9cis_aide_scan }} # These are the crontab settings for periodical checking of the filesystem's integrity using AIDE. diff --git a/templates/etc/crypto-policies/policies/modules/NO-SSHWEAKCIPHERS.pmod.j2 b/templates/etc/crypto-policies/policies/modules/NO-SSHWEAKCIPHERS.pmod.j2 index d325a11..393cf88 100644 --- a/templates/etc/crypto-policies/policies/modules/NO-SSHWEAKCIPHERS.pmod.j2 +++ b/templates/etc/crypto-policies/policies/modules/NO-SSHWEAKCIPHERS.pmod.j2 @@ -1,4 +1,4 @@ # This is a subpolicy to disable weak ciphers # for the SSH protocol (libssh and OpenSSH) # Carried out as part of CIS Benchmark rules combined 1.6.6 and 5.1.4 -cipher@SSH ={% if rhel9cis_rule_1_6_6 %} -CHACHA20-POLY1305{% endif %}{% if rhel9cis_rule_5_1_5 %} -3DES-CBC -AES-128-CBC -AES-192-CBC -AES-256-CBC{% endif %} +cipher@SSH ={% if rhel9cis_rule_1_6_6 %} -CHACHA20-POLY1305{% endif %}{% if rhel9cis_rule_5_1_4 %} -3DES-CBC -AES-128-CBC -AES-192-CBC -AES-256-CBC{% endif %}