diff --git a/.github/workflows/devel_pipeline_validation.yml b/.github/workflows/devel_pipeline_validation.yml index 912b3db6..c9328cbc 100644 --- a/.github/workflows/devel_pipeline_validation.yml +++ b/.github/workflows/devel_pipeline_validation.yml @@ -27,7 +27,7 @@ jobs: # This will create messages for first time contributers and direct them to the Discord server welcome: - runs-on: self-hosted + runs-on: ubuntu-latest steps: - uses: actions/first-interaction@main diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 260cffed..1c697451 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ ci: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: # Safety - id: detect-aws-credentials @@ -37,13 +37,13 @@ repos: exclude: .config/.gitleaks-report.json - repo: https://github.com/gitleaks/gitleaks - rev: v8.18.4 + rev: v8.21.2 hooks: - id: gitleaks args: ['--baseline-path', '.config/.gitleaks-report.json'] - repo: https://github.com/ansible-community/ansible-lint - rev: v24.7.0 + rev: v24.10.0 hooks: - id: ansible-lint name: Ansible-lint diff --git a/README.md b/README.md index 3260cb0a..86ebd368 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Refer to [Contributing Guide](./CONTRIBUTING.rst) This role **will make changes to the system** which may have unintended consequences. This is not an auditing tool but rather a remediation tool to be used after an audit has been conducted. -Check Mode is not supported! The role will complete in check mode without errors, but it is not supported and should be used with caution. The RHEL8-CIS-Audit role or a compliance scanner should be used for compliance checking over check mode. +Check Mode is not supported! The role will complete in check mode without errors, but it is not supported and should be used with caution. The RHEL9-CIS-Audit role or a compliance scanner should be used for compliance checking over check mode. This role was developed against a clean install of the Operating System. If you are implementing to an existing system please review this role for any site specific changes that are needed. @@ -128,11 +128,9 @@ os_check: false **Technical Dependencies:** - Python3 -- Ansible 2.10+ +- Ansible 2.12+ - python-def (should be included in RHEL 9) - libselinux-python -- pip packages - - jmespath - collections found in collections/requirements.yml pre-commit is available if installed on your host for pull request testing. diff --git a/defaults/main.yml b/defaults/main.yml index 622af55f..0cc7a2b1 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -49,15 +49,10 @@ rhel9cis_selinux_disable: false # UEFI boot('/etc/grub2-efi.cfg') or in case of BIOS legacy-boot('/etc/grub2.cfg'). rhel9cis_legacy_boot: false -## Python Binary -## This is used for python3 Installations where python2 OS modules are used in ansible -python2_bin: /bin/python2.7 - ## Benchmark name used by audting control role # The audit variable found at the base ## metadata for Audit benchmark benchmark_version: 'v1.0.0' - benchmark: RHEL9-CIS # Whether to skip the system reboot before audit @@ -526,6 +521,10 @@ rhel9cis_selinux_pol: targeted rhel9cis_selinux_enforce: enforcing # Whether or not to run tasks related to auditing/patching the desktop environment +## Control 1.8.1-10 +# This variable governs whether rules dealing with GUI specific packages(and/or their settings) +# Discovered value can be overridden to true is required +rhel9cis_gui: "{{ prelim_gnome_present.stat.exists | default(false) }}" ## Section 2. Services @@ -567,12 +566,6 @@ rhel9cis_chrony_server_minsources: 2 # Set the respective variable to true to keep the service, # otherwise the service is stopped and disabled -## Control 1.8.10-10, 2.2.1 -# This variable governs whether rules dealing with GUI specific packages(and/or their settings) should -# be executed either to: -# - secure GDM, if GUI is needed('rhel9cis_gui: true') -# - or remove GDM and X-Windows-system, if no GUI is needed('rhel9cis_gui: false') -rhel9cis_gui: false ## Control 2.2.2 - Ensure Avahi Server is not installed # This variable, when set to false, will specify that Avahi Server packages should be uninstalled. rhel9cis_avahi_server: false @@ -1144,6 +1137,11 @@ rhel9cis_force_user_mindays: false # This can break current connecting user access rhel9cis_force_user_warnage: false +## Control 5.6.2 - Ensure system accounts are secured | Set nologin +# The system users on this list are allowed to have a shell (e.g. applications +# that require a shell to function) +rhel9cis_system_users_shell: [] + ## Control 5.6.3 - Ensure default user shell timeout is 900 seconds or less # Session timeout setting file (TMOUT setting can be set in multiple files) # Timeout value is in seconds. (60 seconds * 10 = 600) diff --git a/handlers/main.yml b/handlers/main.yml index dd97feca..c302106b 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -57,8 +57,6 @@ - name: Grub2cfg ansible.builtin.shell: "grub2-mkconfig -o /boot/grub2/grub.cfg" ignore_errors: true # noqa ignore-errors - tags: - - skip_ansible_lint - name: Restart rsyslog ansible.builtin.systemd: @@ -102,8 +100,6 @@ - name: Restart auditd ansible.builtin.shell: service auditd restart - tags: - - skip_ansible_lint - name: Change_requires_reboot ansible.builtin.set_fact: diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 1db6db55..13afd85c 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -190,6 +190,13 @@ - rhel9cis_force_gpg_key_import - ansible_facts.distribution == 'RedHat' +- name: "PRELIM | Discover Gnome Desktop Environment" + ansible.builtin.stat: + path: /usr/share/gnome/gnome-version.xml + register: prelim_gnome_present + tags: + - always + - name: "PRELIM | Section 4.1 | Configure System Accounting (auditd)" ansible.builtin.package: name: audit diff --git a/tasks/section_1/cis_1.1.2.x.yml b/tasks/section_1/cis_1.1.2.x.yml index 10d6d2de..861e679f 100644 --- a/tasks/section_1/cis_1.1.2.x.yml +++ b/tasks/section_1/cis_1.1.2.x.yml @@ -32,7 +32,7 @@ src: "{{ item.device }}" fstype: "{{ item.fstype }}" state: present - opts: defaults,{% if rhel9cis_rule_1_1_2_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_2_3 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_2_4 %}nosuid{% endif %} + opts: "{{ item.options }}{% if ('nodev' not in item.options and rhel9cis_rule_1_1_2_2) %},nodev{% endif %}{% if ('noexec' not in item.options and rhel9cis_rule_1_1_2_3) %},noexec{% endif %}{% if ('nosuid' not in item.options and rhel9cis_rule_1_1_2_4) %},nosuid{% endif %}" notify: Remount tmp loop: "{{ ansible_facts.mounts }}" loop_control: diff --git a/tasks/section_1/cis_1.1.3.x.yml b/tasks/section_1/cis_1.1.3.x.yml index 3a64a066..d219b391 100644 --- a/tasks/section_1/cis_1.1.3.x.yml +++ b/tasks/section_1/cis_1.1.3.x.yml @@ -31,7 +31,7 @@ src: "{{ item.device }}" fstype: "{{ item.fstype }}" state: present - opts: defaults,{% if rhel9cis_rule_1_1_3_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_3_3 %}nosuid{% endif %} + opts: "{{ item.options }}{% if ('nodev' not in item.options and rhel9cis_rule_1_1_3_2) %},nodev{% endif %}{% if ('nosuid' not in item.options and rhel9cis_rule_1_1_3_3) %},nosuid{% endif %}" loop: "{{ ansible_facts.mounts }}" loop_control: label: "{{ item.device }}" @@ -45,6 +45,5 @@ - level1-workstation - patch - mounts - - skip_ansible_lint - rule_1.1.3.2 - rule_1.1.3.3 diff --git a/tasks/section_1/cis_1.1.4.x.yml b/tasks/section_1/cis_1.1.4.x.yml index 713dba6e..d04ac02d 100644 --- a/tasks/section_1/cis_1.1.4.x.yml +++ b/tasks/section_1/cis_1.1.4.x.yml @@ -33,7 +33,7 @@ src: "{{ item.device }}" fstype: "{{ item.fstype }}" state: present - opts: defaults,{% if rhel9cis_rule_1_1_4_2 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_4_3 %}nosuid,{% endif %}{% if rhel9cis_rule_1_1_4_4 %}nodev{% endif %} + opts: "{{ item.options }}{% if ('noexec' not in item.options and rhel9cis_rule_1_1_4_2) %},noexec{% endif %}{% if ('nosuid' not in item.options and rhel9cis_rule_1_1_4_3) %},nosuid{% endif %}{% if ('nodev' not in item.options and rhel9cis_rule_1_1_4_4) %},nodev{% endif %}" loop: "{{ ansible_facts.mounts }}" loop_control: label: "{{ item.device }}" @@ -48,7 +48,6 @@ - level1-workstation - patch - mounts - - skip_ansible_lint - rule_1.1.4.2 - rule_1.1.4.3 - rule_1.1.4.4 diff --git a/tasks/section_1/cis_1.1.5.x.yml b/tasks/section_1/cis_1.1.5.x.yml index ac8b8275..af4e230c 100644 --- a/tasks/section_1/cis_1.1.5.x.yml +++ b/tasks/section_1/cis_1.1.5.x.yml @@ -22,7 +22,6 @@ - audit - mounts - rule_1.1.5.1 - - skip_ansible_lint - name: | "1.1.5.2 | PATCH | Ensure nodev option set on /var/log partition" @@ -33,7 +32,7 @@ src: "{{ item.device }}" fstype: "{{ item.fstype }}" state: present - opts: defaults,{% if rhel9cis_rule_1_1_5_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_5_3 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_5_4 %}nosuid{% endif %} + opts: "{{ item.options }}{% if ('nodev' not in item.options and rhel9cis_rule_1_1_5_2) %},nodev{% endif %}{% if ('noexec' not in item.options and rhel9cis_rule_1_1_5_3) %},noexec{% endif %}{% if ('nosuid' not in item.options and rhel9cis_rule_1_1_5_4) %},nosuid{% endif %}" loop: "{{ ansible_facts.mounts }}" loop_control: label: "{{ item.device }}" @@ -48,7 +47,6 @@ - level1-workstation - patch - mounts - - skip_ansible_lint - rule_1.1.5.2 - rule_1.1.5.3 - rule_1.1.5.4 diff --git a/tasks/section_1/cis_1.1.6.x.yml b/tasks/section_1/cis_1.1.6.x.yml index 5a7c8f40..d20e83d8 100644 --- a/tasks/section_1/cis_1.1.6.x.yml +++ b/tasks/section_1/cis_1.1.6.x.yml @@ -32,7 +32,7 @@ src: "{{ item.device }}" fstype: "{{ item.fstype }}" state: present - opts: defaults,{% if rhel9cis_rule_1_1_6_2 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_6_3 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_6_4 %}nosuid{% endif %} + opts: "{{ item.options }}{% if ('noexec' not in item.options and rhel9cis_rule_1_1_6_2) %},noexec{% endif %}{% if ('nodev' not in item.options and rhel9cis_rule_1_1_6_3) %},nodev{% endif %}{% if ('nosuid' not in item.options and rhel9cis_rule_1_1_6_4) %},nosuid{% endif %}" loop: "{{ ansible_facts.mounts }}" loop_control: label: "{{ item.device }}" @@ -47,7 +47,6 @@ - level1-workstation - patch - mounts - - skip_ansible_lint - rule_1.1.6.2 - rule_1.1.6.3 - rule_1.1.6.4 diff --git a/tasks/section_1/cis_1.1.7.x.yml b/tasks/section_1/cis_1.1.7.x.yml index d1133618..d081811e 100644 --- a/tasks/section_1/cis_1.1.7.x.yml +++ b/tasks/section_1/cis_1.1.7.x.yml @@ -22,7 +22,6 @@ - audit - mounts - rule_1.1.7.1 - - skip_ansible_lint - name: | "1.1.7.2 | PATCH | Ensure nodev option set on /home partition @@ -32,7 +31,7 @@ src: "{{ item.device }}" fstype: "{{ item.fstype }}" state: present - opts: defaults,{% if rhel9cis_rule_1_1_7_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_7_3 %}nosuid{% endif %} + opts: "{{ item.options }}{% if ('nodev' not in item.options and rhel9cis_rule_1_1_7_2) %},nodev{% endif %}{% if ('nosuid' not in item.options and rhel9cis_rule_1_1_7_3) %},nosuid{% endif %}" loop: "{{ ansible_facts.mounts }}" loop_control: label: "{{ item.device }}" @@ -48,4 +47,3 @@ - mounts - rule_1.1.7.2 - rule_1.1.7.3 - - skip_ansible_lint diff --git a/tasks/section_1/cis_1.1.8.x.yml b/tasks/section_1/cis_1.1.8.x.yml index 6a50de89..5ebf6669 100644 --- a/tasks/section_1/cis_1.1.8.x.yml +++ b/tasks/section_1/cis_1.1.8.x.yml @@ -29,7 +29,6 @@ - audit - mounts - rule_1.1.8.1 - - skip_ansible_lint - name: | "1.1.8.2 | PATCH | Ensure nodev option set on /dev/shm partition | Set nodev option diff --git a/tasks/section_1/cis_1.2.x.yml b/tasks/section_1/cis_1.2.x.yml index fc0bf272..3c57e417 100644 --- a/tasks/section_1/cis_1.2.x.yml +++ b/tasks/section_1/cis_1.2.x.yml @@ -44,7 +44,7 @@ - name: "1.2.2 | PATCH | Ensure gpgcheck is globally activated | Update yum.repos" ansible.builtin.replace: name: "{{ item.path }}" - regexp: "^gpgcheck=0" + regexp: ^gpgcheck\s*=\s*0 replace: "gpgcheck=1" loop: "{{ yum_repos.files }}" loop_control: @@ -85,7 +85,6 @@ - manual - audit - rule_1.2.3 - - skip_ansible_lint - name: "1.2.4 | AUDIT | Ensure repo_gpgcheck is globally activated" block: @@ -104,7 +103,7 @@ - name: "1.2.4 | PATCH | Ensure repo_gpgcheck is globally activated | amend repo files" ansible.builtin.replace: path: "{{ item.path }}" - regexp: '^repo_gpgcheck( |)=( |)0' + regexp: ^repo_gpgcheck\s*=\s*0 replace: repo_gpgcheck=1 loop: "{{ repo_files.files }}" loop_control: diff --git a/tasks/section_1/cis_1.8.x.yml b/tasks/section_1/cis_1.8.x.yml index ce35a48f..36f60524 100644 --- a/tasks/section_1/cis_1.8.x.yml +++ b/tasks/section_1/cis_1.8.x.yml @@ -131,7 +131,7 @@ - name: "1.8.5 | PATCH | Ensure GDM screen locks cannot be overridden | Make lock file" ansible.builtin.template: src: etc/dconf/db/00-screensaver_lock.j2 - dest: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d/locks/00-screensaver" + dest: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d/locks/00-screensaver_lock" owner: root group: root mode: '0644' diff --git a/tasks/section_1/cis_1.9.yml b/tasks/section_1/cis_1.9.yml index e226948c..39f0cd9f 100644 --- a/tasks/section_1/cis_1.9.yml +++ b/tasks/section_1/cis_1.9.yml @@ -7,10 +7,8 @@ notify: Change_requires_reboot when: - rhel9cis_rule_1_9 - - not system_is_ec2 tags: - level1-server - level1-workstation - patch - rule_1.9 - - skip_ansible_lint diff --git a/tasks/section_5/cis_5.6.x.yml b/tasks/section_5/cis_5.6.x.yml index 52713888..11bed39a 100644 --- a/tasks/section_5/cis_5.6.x.yml +++ b/tasks/section_5/cis_5.6.x.yml @@ -13,6 +13,7 @@ - item.id != "shutdown" - item.id != "halt" - item.id != "nfsnobody" + - item.id not in rhel9cis_system_users_shell - item.uid < min_int_uid | int - item.shell != "/bin/false" - item.shell != "/usr/sbin/nologin" diff --git a/tasks/section_6/cis_6.1.x.yml b/tasks/section_6/cis_6.1.x.yml index a0e8dd6c..a89c16c5 100644 --- a/tasks/section_6/cis_6.1.x.yml +++ b/tasks/section_6/cis_6.1.x.yml @@ -164,7 +164,7 @@ - name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | Flatten no_user_items results for easier use" ansible.builtin.set_fact: - discovered_unowned_files_flatten: "{{ rhel_09_6_1_10_audit.results | map(attribute='stdout_lines') | flatten }}" + discovered_unowned_files_flatten: "{{ rhel_09_6_1_10_audit.results | selectattr('stdout_lines', 'defined') | map(attribute='stdout_lines') | flatten }}" - name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | Displaying any unowned files or directories" ansible.builtin.debug: @@ -204,7 +204,7 @@ - name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | Flatten no_user_items results for easier use" ansible.builtin.set_fact: - discovered_ungrouped_files_flatten: "{{ rhel_09_6_1_11_audit.results | map(attribute='stdout_lines') | flatten }}" + discovered_ungrouped_files_flatten: "{{ rhel_09_6_1_11_audit.results | selectattr('stdout_lines', 'defined') | map(attribute='stdout_lines') | flatten }}" - name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | Displaying all ungrouped files or directories" ansible.builtin.debug: