- name: Ensure aide is installed package: name: aide state: present when: - enable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - package_aide_installed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90843-4 - CJIS-5.10.1.3 - NIST-800-53-CM-6(a) - PCI-DSS-Req-11.5 - PCI-DSSv4-11.5.2 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_aide_installed - name: Ensure AIDE is installed package: name: '{{ item }}' state: present with_items: - aide when: - aide_build_database | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83438-2 - CJIS-5.10.1.3 - NIST-800-53-CM-6(a) - PCI-DSS-Req-11.5 - PCI-DSSv4-11.5.2 - aide_build_database - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Build and Test AIDE Database command: /usr/sbin/aide --init changed_when: true when: - aide_build_database | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83438-2 - CJIS-5.10.1.3 - NIST-800-53-CM-6(a) - PCI-DSS-Req-11.5 - PCI-DSSv4-11.5.2 - aide_build_database - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check whether the stock AIDE Database exists stat: path: /var/lib/aide/aide.db.new.gz register: aide_database_stat when: - aide_build_database | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83438-2 - CJIS-5.10.1.3 - NIST-800-53-CM-6(a) - PCI-DSS-Req-11.5 - PCI-DSSv4-11.5.2 - aide_build_database - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Stage AIDE Database copy: src: /var/lib/aide/aide.db.new.gz dest: /var/lib/aide/aide.db.gz backup: true remote_src: true when: - aide_build_database | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - (aide_database_stat.stat.exists is defined and aide_database_stat.stat.exists) tags: - CCE-83438-2 - CJIS-5.10.1.3 - NIST-800-53-CM-6(a) - PCI-DSS-Req-11.5 - PCI-DSSv4-11.5.2 - aide_build_database - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure aide is installed package: name: '{{ item }}' state: present with_items: - aide when: - aide_check_audit_tools | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87757-1 - NIST-800-53-AU-9(3) - NIST-800-53-AU-9(3).1 - aide_check_audit_tools - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set audit_tools fact set_fact: audit_tools: - /usr/sbin/auditctl - /usr/sbin/auditd - /usr/sbin/augenrules - /usr/sbin/aureport - /usr/sbin/ausearch - /usr/sbin/autrace - /usr/sbin/rsyslogd when: - aide_check_audit_tools | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87757-1 - NIST-800-53-AU-9(3) - NIST-800-53-AU-9(3).1 - aide_check_audit_tools - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure existing AIDE configuration for audit tools are correct lineinfile: path: /etc/aide.conf regexp: ^{{ item }}\s line: '{{ item }} p+i+n+u+g+s+b+acl+xattrs+sha512' with_items: '{{ audit_tools }}' when: - aide_check_audit_tools | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87757-1 - NIST-800-53-AU-9(3) - NIST-800-53-AU-9(3).1 - aide_check_audit_tools - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Configure AIDE to properly protect audit tools lineinfile: path: /etc/aide.conf line: '{{ item }} p+i+n+u+g+s+b+acl+xattrs+sha512' with_items: '{{ audit_tools }}' when: - aide_check_audit_tools | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87757-1 - NIST-800-53-AU-9(3) - NIST-800-53-AU-9(3).1 - aide_check_audit_tools - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure AIDE is installed package: name: '{{ item }}' state: present with_items: - aide when: - aide_periodic_cron_checking | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83437-4 - CJIS-5.10.1.3 - NIST-800-53-CM-6(a) - NIST-800-53-SI-7 - NIST-800-53-SI-7(1) - PCI-DSS-Req-11.5 - PCI-DSSv4-11.5.2 - aide_periodic_cron_checking - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set cron package name - RedHat set_fact: cron_pkg_name: cronie when: - aide_periodic_cron_checking | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_os_family == "RedHat" or ansible_os_family == "Suse" tags: - CCE-83437-4 - CJIS-5.10.1.3 - NIST-800-53-CM-6(a) - NIST-800-53-SI-7 - NIST-800-53-SI-7(1) - PCI-DSS-Req-11.5 - PCI-DSSv4-11.5.2 - aide_periodic_cron_checking - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set cron package name - Debian set_fact: cron_pkg_name: cron when: - aide_periodic_cron_checking | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_os_family == "Debian" tags: - CCE-83437-4 - CJIS-5.10.1.3 - NIST-800-53-CM-6(a) - NIST-800-53-SI-7 - NIST-800-53-SI-7(1) - PCI-DSS-Req-11.5 - PCI-DSSv4-11.5.2 - aide_periodic_cron_checking - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Install cron package: name: '{{ cron_pkg_name }}' state: present when: - aide_periodic_cron_checking | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83437-4 - CJIS-5.10.1.3 - NIST-800-53-CM-6(a) - NIST-800-53-SI-7 - NIST-800-53-SI-7(1) - PCI-DSS-Req-11.5 - PCI-DSSv4-11.5.2 - aide_periodic_cron_checking - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Configure Periodic Execution of AIDE cron: name: run AIDE check minute: 5 hour: 4 weekday: 0 user: root job: /usr/sbin/aide --check when: - aide_periodic_cron_checking | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83437-4 - CJIS-5.10.1.3 - NIST-800-53-CM-6(a) - NIST-800-53-SI-7 - NIST-800-53-SI-7(1) - PCI-DSS-Req-11.5 - PCI-DSSv4-11.5.2 - aide_periodic_cron_checking - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Configure System Cryptography Policy lineinfile: path: /etc/crypto-policies/config regexp: ^(?!#)(\S+)$ line: '{{ var_system_crypto_policy }}' create: true tags: - CCE-83450-7 - NIST-800-53-AC-17(2) - NIST-800-53-AC-17(a) - NIST-800-53-CM-6(a) - NIST-800-53-MA-4(6) - NIST-800-53-SC-12(2) - NIST-800-53-SC-12(3) - NIST-800-53-SC-13 - configure_crypto_policy - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy when: - configure_crypto_policy | bool - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Verify that Crypto Policy is Set (runtime) command: /usr/bin/update-crypto-policies --set {{ var_system_crypto_policy }} tags: - CCE-83450-7 - NIST-800-53-AC-17(2) - NIST-800-53-AC-17(a) - NIST-800-53-CM-6(a) - NIST-800-53-MA-4(6) - NIST-800-53-SC-12(2) - NIST-800-53-SC-12(3) - NIST-800-53-SC-13 - configure_crypto_policy - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy when: - configure_crypto_policy | bool - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Configure SSH to use System Crypto Policy lineinfile: dest: /etc/sysconfig/sshd state: absent regexp: ^\s*(?i)CRYPTO_POLICY.*$ tags: - CCE-83445-7 - NIST-800-53-AC-17(2) - NIST-800-53-AC-17(a) - NIST-800-53-CM-6(a) - NIST-800-53-MA-4(6) - NIST-800-53-SC-13 - PCI-DSS-Req-2.2 - PCI-DSSv4-2.2 - configure_ssh_crypto_policy - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required when: - configure_ssh_crypto_policy | bool - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - name: Gather the package facts package_facts: manager: auto tags: - CCE-83549-6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_gdm_removed when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - package_gdm_removed | bool - name: Ensure gdm is removed package: name: gdm state: absent when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - package_gdm_removed | bool - '"gdm" in ansible_facts.packages' tags: - CCE-83549-6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_gdm_removed - name: Gather the package facts package_facts: manager: auto tags: - CCE-87295-2 - PCI-DSS-Req-6.2 - PCI-DSSv4-6.3.3 - dconf_db_up_to_date - high_severity - low_complexity - medium_disruption - no_reboot_needed - unknown_strategy when: - dconf_db_up_to_date | bool - high_severity | bool - low_complexity | bool - medium_disruption | bool - no_reboot_needed | bool - unknown_strategy | bool - name: Run dconf update ansible.builtin.command: cmd: dconf update when: - dconf_db_up_to_date | bool - high_severity | bool - low_complexity | bool - medium_disruption | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87295-2 - PCI-DSS-Req-6.2 - PCI-DSSv4-6.3.3 - dconf_db_up_to_date - high_severity - low_complexity - medium_disruption - no_reboot_needed - unknown_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-88285-2 - NIST-800-53-AC-23 - NIST-800-53-CM-6(a) - dconf_gnome_disable_user_list - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy when: - dconf_gnome_disable_user_list | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - name: Disable the GNOME3 Login User List ini_file: dest: /etc/dconf/db/distro.d/00-security-settings section: org/gnome/login-screen option: disable-user-list value: 'true' no_extra_spaces: true create: true when: - dconf_gnome_disable_user_list | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88285-2 - NIST-800-53-AC-23 - NIST-800-53-CM-6(a) - dconf_gnome_disable_user_list - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Prevent user modification of GNOME3 disablement of Login User List lineinfile: path: /etc/dconf/db/distro.d/locks/00-security-settings-lock regexp: ^/org/gnome/login-screen/disable-user-list$ line: /org/gnome/login-screen/disable-user-list create: true when: - dconf_gnome_disable_user_list | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88285-2 - NIST-800-53-AC-23 - NIST-800-53-CM-6(a) - dconf_gnome_disable_user_list - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - dconf_gnome_disable_user_list | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88285-2 - NIST-800-53-AC-23 - NIST-800-53-CM-6(a) - dconf_gnome_disable_user_list - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-86033-8 - gnome_gdm_disable_xdmcp - high_severity - low_complexity - medium_disruption - no_reboot_needed - unknown_strategy when: - gnome_gdm_disable_xdmcp | bool - high_severity | bool - low_complexity | bool - medium_disruption | bool - no_reboot_needed | bool - unknown_strategy | bool - name: Disable XDMCP in GDM ini_file: path: /etc/gdm/custom.conf section: xdmcp option: Enable value: 'false' create: true mode: 420 when: - gnome_gdm_disable_xdmcp | bool - high_severity | bool - low_complexity | bool - medium_disruption | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' tags: - CCE-86033-8 - gnome_gdm_disable_xdmcp - high_severity - low_complexity - medium_disruption - no_reboot_needed - unknown_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-87734-0 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - dconf_gnome_disable_automount - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy when: - dconf_gnome_disable_automount | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - name: Disable GNOME3 Automounting - automount ini_file: dest: /etc/dconf/db/local.d/00-security-settings section: org/gnome/desktop/media-handling option: automount value: 'false' create: true no_extra_spaces: true when: - dconf_gnome_disable_automount | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87734-0 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - dconf_gnome_disable_automount - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Prevent user modification of GNOME3 Automounting - automount lineinfile: path: /etc/dconf/db/local.d/locks/00-security-settings-lock regexp: ^/org/gnome/desktop/media-handling/automount$ line: /org/gnome/desktop/media-handling/automount create: true when: - dconf_gnome_disable_automount | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87734-0 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - dconf_gnome_disable_automount - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - dconf_gnome_disable_automount | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87734-0 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - dconf_gnome_disable_automount - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-90128-0 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - dconf_gnome_disable_automount_open - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy when: - dconf_gnome_disable_automount_open | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - name: Disable GNOME3 Automounting - automount-open ini_file: dest: /etc/dconf/db/local.d/00-security-settings section: org/gnome/desktop/media-handling option: automount-open value: 'false' create: true no_extra_spaces: true when: - dconf_gnome_disable_automount_open | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90128-0 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - dconf_gnome_disable_automount_open - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Prevent user modification of GNOME3 Automounting - automount-open lineinfile: path: /etc/dconf/db/local.d/locks/00-security-settings-lock regexp: ^/org/gnome/desktop/media-handling/automount-open$ line: /org/gnome/desktop/media-handling/automount-open create: true when: - dconf_gnome_disable_automount_open | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90128-0 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - dconf_gnome_disable_automount_open - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - dconf_gnome_disable_automount_open | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90128-0 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - dconf_gnome_disable_automount_open - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-90257-7 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - dconf_gnome_disable_autorun - low_complexity - low_severity - medium_disruption - no_reboot_needed - unknown_strategy when: - dconf_gnome_disable_autorun | bool - low_complexity | bool - low_severity | bool - medium_disruption | bool - no_reboot_needed | bool - unknown_strategy | bool - name: Disable GNOME3 Automounting - autorun-never ini_file: dest: /etc/dconf/db/local.d/00-security-settings section: org/gnome/desktop/media-handling option: autorun-never value: 'true' create: true no_extra_spaces: true when: - dconf_gnome_disable_autorun | bool - low_complexity | bool - low_severity | bool - medium_disruption | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90257-7 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - dconf_gnome_disable_autorun - low_complexity - low_severity - medium_disruption - no_reboot_needed - unknown_strategy - name: Prevent user modification of GNOME3 Automounting - autorun-never lineinfile: path: /etc/dconf/db/local.d/locks/00-security-settings-lock regexp: ^/org/gnome/desktop/media-handling/autorun-never$ line: /org/gnome/desktop/media-handling/autorun-never create: true when: - dconf_gnome_disable_autorun | bool - low_complexity | bool - low_severity | bool - medium_disruption | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90257-7 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - dconf_gnome_disable_autorun - low_complexity - low_severity - medium_disruption - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - dconf_gnome_disable_autorun | bool - low_complexity | bool - low_severity | bool - medium_disruption | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90257-7 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - dconf_gnome_disable_autorun - low_complexity - low_severity - medium_disruption - no_reboot_needed - unknown_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-86510-5 - CJIS-5.5.5 - NIST-800-171-3.1.10 - NIST-800-53-AC-11(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.8 - PCI-DSSv4-8.2.8 - dconf_gnome_screensaver_idle_delay - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy when: - dconf_gnome_screensaver_idle_delay | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - name: Set GNOME3 Screensaver Inactivity Timeout ini_file: dest: /etc/dconf/db/local.d/00-security-settings section: org/gnome/desktop/session option: idle-delay value: uint32 {{ inactivity_timeout_value }} create: true no_extra_spaces: true when: - dconf_gnome_screensaver_idle_delay | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86510-5 - CJIS-5.5.5 - NIST-800-171-3.1.10 - NIST-800-53-AC-11(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.8 - PCI-DSSv4-8.2.8 - dconf_gnome_screensaver_idle_delay - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - dconf_gnome_screensaver_idle_delay | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86510-5 - CJIS-5.5.5 - NIST-800-171-3.1.10 - NIST-800-53-AC-11(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.8 - PCI-DSSv4-8.2.8 - dconf_gnome_screensaver_idle_delay - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-86954-5 - NIST-800-171-3.1.10 - NIST-800-53-AC-11(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.8 - dconf_gnome_screensaver_lock_delay - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy when: - dconf_gnome_screensaver_lock_delay | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - name: Set GNOME3 Screensaver Lock Delay After Activation Period ini_file: dest: /etc/dconf/db/local.d/00-security-settings section: org/gnome/desktop/screensaver option: lock-delay value: uint32 {{ var_screensaver_lock_delay }} create: true no_extra_spaces: true when: - dconf_gnome_screensaver_lock_delay | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86954-5 - NIST-800-171-3.1.10 - NIST-800-53-AC-11(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.8 - dconf_gnome_screensaver_lock_delay - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - dconf_gnome_screensaver_lock_delay | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86954-5 - NIST-800-171-3.1.10 - NIST-800-53-AC-11(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.8 - dconf_gnome_screensaver_lock_delay - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-87491-7 - NIST-800-171-3.1.10 - NIST-800-53-CM-6(a) - dconf_gnome_screensaver_user_locks - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy when: - dconf_gnome_screensaver_user_locks | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - name: Prevent user modification of GNOME lock-delay lineinfile: path: /etc/dconf/db/local.d/locks/00-security-settings-lock regexp: ^/org/gnome/desktop/screensaver/lock-delay$ line: /org/gnome/desktop/screensaver/lock-delay create: true when: - dconf_gnome_screensaver_user_locks | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87491-7 - NIST-800-171-3.1.10 - NIST-800-53-CM-6(a) - dconf_gnome_screensaver_user_locks - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - dconf_gnome_screensaver_user_locks | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87491-7 - NIST-800-171-3.1.10 - NIST-800-53-CM-6(a) - dconf_gnome_screensaver_user_locks - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-85971-0 - NIST-800-171-3.1.10 - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.8 - PCI-DSSv4-8.2.8 - dconf_gnome_session_idle_user_locks - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy when: - dconf_gnome_session_idle_user_locks | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - name: Prevent user modification of GNOME Session idle-delay lineinfile: path: /etc/dconf/db/local.d/locks/00-security-settings-lock regexp: ^/org/gnome/desktop/session/idle-delay$ line: /org/gnome/desktop/session/idle-delay create: true when: - dconf_gnome_session_idle_user_locks | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-85971-0 - NIST-800-171-3.1.10 - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.8 - PCI-DSSv4-8.2.8 - dconf_gnome_session_idle_user_locks - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - dconf_gnome_session_idle_user_locks | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-85971-0 - NIST-800-171-3.1.10 - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.8 - PCI-DSSv4-8.2.8 - dconf_gnome_session_idle_user_locks - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Ensure sudo is installed package: name: sudo state: present when: - enable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - package_sudo_installed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83523-1 - NIST-800-53-CM-6(a) - PCI-DSSv4-10.2.1.5 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_sudo_installed - name: Gather the package facts package_facts: manager: auto tags: - CCE-83538-9 - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_add_use_pty when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_add_use_pty | bool - name: Ensure use_pty is enabled in /etc/sudoers lineinfile: path: /etc/sudoers regexp: ^[\s]*Defaults.*\buse_pty\b.*$ line: Defaults use_pty validate: /usr/sbin/visudo -cf %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_add_use_pty | bool - '"sudo" in ansible_facts.packages' tags: - CCE-83538-9 - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_add_use_pty - name: Gather the package facts package_facts: manager: auto tags: - CCE-83527-2 - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - low_complexity - low_disruption - low_severity - no_reboot_needed - restrict_strategy - sudo_custom_logfile when: - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_custom_logfile | bool - name: Ensure logfile is enabled with the appropriate value in /etc/sudoers lineinfile: path: /etc/sudoers regexp: ^[\s]*Defaults\s(.*)\blogfile=[-]?.+\b(.*)$ line: Defaults \1logfile={{ var_sudo_logfile }}\2 validate: /usr/sbin/visudo -cf %s backrefs: true register: edit_sudoers_logfile_option when: - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_custom_logfile | bool - '"sudo" in ansible_facts.packages' tags: - CCE-83527-2 - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - low_complexity - low_disruption - low_severity - no_reboot_needed - restrict_strategy - sudo_custom_logfile - name: Enable logfile option with appropriate value in /etc/sudoers lineinfile: path: /etc/sudoers line: Defaults logfile={{ var_sudo_logfile }} validate: /usr/sbin/visudo -cf %s when: - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_custom_logfile | bool - '"sudo" in ansible_facts.packages' - edit_sudoers_logfile_option is defined and not edit_sudoers_logfile_option.changed tags: - CCE-83527-2 - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - low_complexity - low_disruption - low_severity - no_reboot_needed - restrict_strategy - sudo_custom_logfile - name: Find /etc/sudoers.d/ files find: paths: - /etc/sudoers.d/ register: sudoers tags: - CCE-83543-9 - NIST-800-53-CM-6(a) - NIST-800-53-IA-11 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_authentication when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_require_authentication | bool - name: Remove lines containing NOPASSWD from sudoers files replace: regexp: (^(?!#).*[\s]+NOPASSWD[\s]*\:.*$) replace: '# \g<1>' path: '{{ item.path }}' validate: /usr/sbin/visudo -cf %s with_items: - path: /etc/sudoers - '{{ sudoers.files }}' tags: - CCE-83543-9 - NIST-800-53-CM-6(a) - NIST-800-53-IA-11 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_authentication when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_require_authentication | bool - name: Find /etc/sudoers.d/ files find: paths: - /etc/sudoers.d/ register: sudoers tags: - CCE-83543-9 - NIST-800-53-CM-6(a) - NIST-800-53-IA-11 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_authentication when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_require_authentication | bool - name: Remove lines containing !authenticate from sudoers files replace: regexp: (^(?!#).*[\s]+\!authenticate.*$) replace: '# \g<1>' path: '{{ item.path }}' validate: /usr/sbin/visudo -cf %s with_items: - path: /etc/sudoers - '{{ sudoers.files }}' tags: - CCE-83543-9 - NIST-800-53-CM-6(a) - NIST-800-53-IA-11 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_authentication when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_require_authentication | bool - name: Gather the package facts package_facts: manager: auto tags: - CCE-90029-0 - NIST-800-53-IA-11 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_reauthentication when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_require_reauthentication | bool - name: Find out if /etc/sudoers.d/* files contain 'Defaults timestamp_timeout' to be deduplicated find: path: /etc/sudoers.d patterns: '*' contains: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=.* register: sudoers_d_defaults_timestamp_timeout when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_require_reauthentication | bool - '"sudo" in ansible_facts.packages' tags: - CCE-90029-0 - NIST-800-53-IA-11 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_reauthentication - name: Remove found occurrences of 'Defaults timestamp_timeout' from /etc/sudoers.d/* files lineinfile: path: '{{ item.path }}' regexp: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=.* state: absent with_items: '{{ sudoers_d_defaults_timestamp_timeout.files }}' when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_require_reauthentication | bool - '"sudo" in ansible_facts.packages' tags: - CCE-90029-0 - NIST-800-53-IA-11 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_reauthentication - name: Ensure timestamp_timeout is enabled with the appropriate value in /etc/sudoers lineinfile: path: /etc/sudoers regexp: ^[\s]*Defaults\s(.*)\btimestamp_timeout[\s]*=[\s]*[-]?\w+\b(.*)$ line: Defaults \1timestamp_timeout={{ var_sudo_timestamp_timeout }}\2 validate: /usr/sbin/visudo -cf %s backrefs: true register: edit_sudoers_timestamp_timeout_option when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_require_reauthentication | bool - '"sudo" in ansible_facts.packages' tags: - CCE-90029-0 - NIST-800-53-IA-11 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_reauthentication - name: Enable timestamp_timeout option with appropriate value in /etc/sudoers lineinfile: path: /etc/sudoers line: Defaults timestamp_timeout={{ var_sudo_timestamp_timeout }} validate: /usr/sbin/visudo -cf %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sudo_require_reauthentication | bool - '"sudo" in ansible_facts.packages' - edit_sudoers_timestamp_timeout_option is defined and not edit_sudoers_timestamp_timeout_option.changed tags: - CCE-90029-0 - NIST-800-53-IA-11 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_reauthentication - name: Gather the package facts package_facts: manager: auto tags: - CCE-83457-2 - CJIS-5.10.4.1 - NIST-800-171-3.4.8 - NIST-800-53-CM-11(a) - NIST-800-53-CM-11(b) - NIST-800-53-CM-5(3) - NIST-800-53-CM-6(a) - NIST-800-53-SA-12 - NIST-800-53-SA-12(10) - NIST-800-53-SC-12 - NIST-800-53-SC-12(3) - NIST-800-53-SI-7 - PCI-DSS-Req-6.2 - PCI-DSSv4-6.3.3 - configure_strategy - ensure_gpgcheck_globally_activated - high_severity - low_complexity - medium_disruption - no_reboot_needed when: - configure_strategy | bool - ensure_gpgcheck_globally_activated | bool - high_severity | bool - low_complexity | bool - medium_disruption | bool - no_reboot_needed | bool - name: Ensure GPG check is globally activated ini_file: dest: /etc/dnf/dnf.conf section: main option: gpgcheck value: 1 no_extra_spaces: true create: false when: - configure_strategy | bool - ensure_gpgcheck_globally_activated | bool - high_severity | bool - low_complexity | bool - medium_disruption | bool - no_reboot_needed | bool - '"yum" in ansible_facts.packages' tags: - CCE-83457-2 - CJIS-5.10.4.1 - NIST-800-171-3.4.8 - NIST-800-53-CM-11(a) - NIST-800-53-CM-11(b) - NIST-800-53-CM-5(3) - NIST-800-53-CM-6(a) - NIST-800-53-SA-12 - NIST-800-53-SA-12(10) - NIST-800-53-SC-12 - NIST-800-53-SC-12(3) - NIST-800-53-SI-7 - PCI-DSS-Req-6.2 - PCI-DSSv4-6.3.3 - configure_strategy - ensure_gpgcheck_globally_activated - high_severity - low_complexity - medium_disruption - no_reboot_needed - name: Enable authselect - Select authselect profile ansible.builtin.command: cmd: authselect select "{{ var_authselect_profile }}" register: result_authselect_select failed_when: false tags: - CCE-89732-2 - NIST-800-53-AC-3 - configure_strategy - enable_authselect - low_complexity - medium_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - enable_authselect | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Enable authselect - Verify if PAM has been altered ansible.builtin.command: cmd: rpm -qV pam register: result_altered_authselect failed_when: false when: - configure_strategy | bool - enable_authselect | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - result_authselect_select.rc != 0 tags: - CCE-89732-2 - NIST-800-53-AC-3 - configure_strategy - enable_authselect - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Enable authselect - Informative message based on the authselect integrity check ansible.builtin.assert: that: - result_altered_authselect is skipped or result_altered_authselect.rc == 0 fail_msg: - Files in the 'pam' package have been altered, so the authselect configuration won't be forced. tags: - CCE-89732-2 - NIST-800-53-AC-3 - configure_strategy - enable_authselect - low_complexity - medium_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - enable_authselect | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Enable authselect - Force authselect profile select ansible.builtin.command: cmd: authselect select --force "{{ var_authselect_profile }}" when: - configure_strategy | bool - enable_authselect | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - result_authselect_select.rc != 0 - result_altered_authselect is skipped or result_altered_authselect.rc == 0 tags: - CCE-89732-2 - NIST-800-53-AC-3 - configure_strategy - enable_authselect - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Modify the System Login Banner - Ensure Correct Banner copy: dest: /etc/issue content: '{{ login_banner_text | regex_replace("^\^(.*)\$$", "\1") | regex_replace("^\((.*\.)\|.*\)$", "\1") | regex_replace("\[\\s\\n\]\+"," ") | regex_replace("\(\?:\[\\n\]\+\|\(\?:\\\\n\)\+\)", "\n") | regex_replace("\\", "") | wordwrap() }}' when: - banner_etc_issue | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83557-9 - NIST-800-171-3.1.9 - NIST-800-53-AC-8(a) - NIST-800-53-AC-8(c) - banner_etc_issue - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Modify the System Login Banner for Remote Connections - ensure correct banner copy: dest: /etc/issue.net content: '{{ remote_login_banner_text | regex_replace("^\^(.*)\$$", "\1") | regex_replace("^\((.*\.)\|.*\)$", "\1") | regex_replace("\[\\s\\n\]\+"," ") | regex_replace("\(\?:\[\\n\]\+\|\(\?:\\\\n\)\+\)", "\n") | regex_replace("\\", "") | wordwrap() }}' when: - banner_etc_issue_net | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86148-4 - banner_etc_issue_net - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Modify the System Message of the Day Banner - ensure correct banner copy: dest: /etc/motd content: '{{ motd_banner_text | regex_replace("^\^(.*)\$$", "\1") | regex_replace("^\((.*\.)\|.*\)$", "\1") | regex_replace("\[\\s\\n\]\+"," ") | regex_replace("\(\?:\[\\n\]\+\|\(\?:\\\\n\)\+\)", "\n") | regex_replace("\\", "") | wordwrap() }}' when: - banner_etc_motd | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83559-5 - banner_etc_motd - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Test for existence /etc/issue stat: path: /etc/issue register: file_exists tags: - CCE-86699-6 - configure_strategy - file_groupowner_etc_issue - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_etc_issue | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /etc/issue file: path: /etc/issue group: '0' when: - configure_strategy | bool - file_groupowner_etc_issue | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86699-6 - configure_strategy - file_groupowner_etc_issue - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/issue.net stat: path: /etc/issue.net register: file_exists tags: - CCE-86052-8 - configure_strategy - file_groupowner_etc_issue_net - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_etc_issue_net | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /etc/issue.net file: path: /etc/issue.net group: '0' when: - configure_strategy | bool - file_groupowner_etc_issue_net | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86052-8 - configure_strategy - file_groupowner_etc_issue_net - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/motd stat: path: /etc/motd register: file_exists tags: - CCE-86697-0 - configure_strategy - file_groupowner_etc_motd - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_etc_motd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /etc/motd file: path: /etc/motd group: '0' when: - configure_strategy | bool - file_groupowner_etc_motd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86697-0 - configure_strategy - file_groupowner_etc_motd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/issue stat: path: /etc/issue register: file_exists tags: - CCE-86700-2 - configure_strategy - file_owner_etc_issue - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_etc_issue | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /etc/issue file: path: /etc/issue owner: '0' when: - configure_strategy | bool - file_owner_etc_issue | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86700-2 - configure_strategy - file_owner_etc_issue - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/issue.net stat: path: /etc/issue.net register: file_exists tags: - CCE-86057-7 - configure_strategy - file_owner_etc_issue_net - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_etc_issue_net | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /etc/issue.net file: path: /etc/issue.net owner: '0' when: - configure_strategy | bool - file_owner_etc_issue_net | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86057-7 - configure_strategy - file_owner_etc_issue_net - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/motd stat: path: /etc/motd register: file_exists tags: - CCE-86698-8 - configure_strategy - file_owner_etc_motd - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_etc_motd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /etc/motd file: path: /etc/motd owner: '0' when: - configure_strategy | bool - file_owner_etc_motd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86698-8 - configure_strategy - file_owner_etc_motd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/issue stat: path: /etc/issue register: file_exists tags: - CCE-83551-2 - configure_strategy - file_permissions_etc_issue - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_etc_issue | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-xs,g-xws,o-xwt on /etc/issue file: path: /etc/issue mode: u-xs,g-xws,o-xwt when: - configure_strategy | bool - file_permissions_etc_issue | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83551-2 - configure_strategy - file_permissions_etc_issue - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/issue.net stat: path: /etc/issue.net register: file_exists tags: - CCE-86048-6 - configure_strategy - file_permissions_etc_issue_net - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_etc_issue_net | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-xs,g-xws,o-xwt on /etc/issue.net file: path: /etc/issue.net mode: u-xs,g-xws,o-xwt when: - configure_strategy | bool - file_permissions_etc_issue_net | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86048-6 - configure_strategy - file_permissions_etc_issue_net - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/motd stat: path: /etc/motd register: file_exists tags: - CCE-83554-6 - configure_strategy - file_permissions_etc_motd - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_etc_motd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-xs,g-xws,o-xwt on /etc/motd file: path: /etc/motd mode: u-xs,g-xws,o-xwt when: - configure_strategy | bool - file_permissions_etc_motd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83554-6 - configure_strategy - file_permissions_etc_motd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-87599-7 - NIST-800-171-3.1.9 - NIST-800-53-AC-8(a) - NIST-800-53-AC-8(b) - NIST-800-53-AC-8(c) - dconf_gnome_banner_enabled - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy when: - dconf_gnome_banner_enabled | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - name: Enable GNOME3 Login Warning Banner ini_file: dest: /etc/dconf/db/distro.d/00-security-settings section: org/gnome/login-screen option: banner-message-enable value: 'true' create: true no_extra_spaces: true when: - dconf_gnome_banner_enabled | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' tags: - CCE-87599-7 - NIST-800-171-3.1.9 - NIST-800-53-AC-8(a) - NIST-800-53-AC-8(b) - NIST-800-53-AC-8(c) - dconf_gnome_banner_enabled - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Prevent user modification of GNOME banner-message-enabled lineinfile: path: /etc/dconf/db/distro.d/locks/00-security-settings-lock regexp: ^/org/gnome/login-screen/banner-message-enable$ line: /org/gnome/login-screen/banner-message-enable create: true when: - dconf_gnome_banner_enabled | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' tags: - CCE-87599-7 - NIST-800-171-3.1.9 - NIST-800-53-AC-8(a) - NIST-800-53-AC-8(b) - NIST-800-53-AC-8(c) - dconf_gnome_banner_enabled - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - dconf_gnome_banner_enabled | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' tags: - CCE-87599-7 - NIST-800-171-3.1.9 - NIST-800-53-AC-8(a) - NIST-800-53-AC-8(b) - NIST-800-53-AC-8(c) - dconf_gnome_banner_enabled - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-86529-5 - NIST-800-171-3.1.9 - NIST-800-53-AC-8(a) - NIST-800-53-AC-8(c) - dconf_gnome_login_banner_text - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy when: - dconf_gnome_login_banner_text | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - name: Set the GNOME3 Login Warning Banner Text file: path: /etc/dconf/db/{{ item }} owner: root group: root mode: 493 state: directory with_items: - distro.d - distro.d/locks when: - dconf_gnome_login_banner_text | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' tags: - CCE-86529-5 - NIST-800-171-3.1.9 - NIST-800-53-AC-8(a) - NIST-800-53-AC-8(c) - dconf_gnome_login_banner_text - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Set the GNOME3 Login Warning Banner Text file: path: /etc/dconf/db/distro.d/{{ item }} owner: root group: root mode: 420 state: touch with_items: - 00-security-settings - locks/00-security-settings-lock when: - dconf_gnome_login_banner_text | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' tags: - CCE-86529-5 - NIST-800-171-3.1.9 - NIST-800-53-AC-8(a) - NIST-800-53-AC-8(c) - dconf_gnome_login_banner_text - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Set the GNOME3 Login Warning Banner Text ini_file: dest: /etc/dconf/db/distro.d/00-security-settings section: org/gnome/login-screen option: banner-message-text value: '''{{ login_banner_text | regex_replace("^\^(.*)\$$", "\1") | regex_replace("^\((.*\.)\|.*\)$", "\1") | regex_replace("\[\\s\\n\]\+"," ") | regex_replace("\(\?:\[\\n\]\+\|\(\?:\\\\n\)\+\)", "(n)*") | regex_replace("\\", "") | regex_replace("\(n\)\*", "\\n") }}''' create: true no_extra_spaces: true when: - dconf_gnome_login_banner_text | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' tags: - CCE-86529-5 - NIST-800-171-3.1.9 - NIST-800-53-AC-8(a) - NIST-800-53-AC-8(c) - dconf_gnome_login_banner_text - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Prevent user modification of the GNOME3 Login Warning Banner Text lineinfile: path: /etc/dconf/db/distro.d/locks/00-security-settings-lock regexp: ^/org/gnome/login-screen/banner-message-text$ line: /org/gnome/login-screen/banner-message-text create: true state: present when: - dconf_gnome_login_banner_text | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' tags: - CCE-86529-5 - NIST-800-171-3.1.9 - NIST-800-53-AC-8(a) - NIST-800-53-AC-8(c) - dconf_gnome_login_banner_text - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - dconf_gnome_login_banner_text | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - '"gdm" in ansible_facts.packages' tags: - CCE-86529-5 - NIST-800-171-3.1.9 - NIST-800-53-AC-8(a) - NIST-800-53-AC-8(c) - dconf_gnome_login_banner_text - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-86354-8 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_password_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed when: - accounts_password_pam_pwhistory_remember_password_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: 'Limit Password Reuse: password-auth - Check if system relies on authselect tool' ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present when: - accounts_password_pam_pwhistory_remember_password_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' tags: - CCE-86354-8 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_password_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: 'Limit Password Reuse: password-auth - Collect the available authselect features' ansible.builtin.command: cmd: authselect list-features minimal register: result_authselect_available_features changed_when: false when: - accounts_password_pam_pwhistory_remember_password_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists tags: - CCE-86354-8 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_password_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: 'Limit Password Reuse: password-auth - Enable pam_pwhistory.so using authselect feature' block: - name: 'Limit Password Reuse: password-auth - Check integrity of authselect current profile' ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: 'Limit Password Reuse: password-auth - Informative message based on the authselect integrity check result' ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: 'Limit Password Reuse: password-auth - Get authselect current features' ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_check_cmd is success - name: 'Limit Password Reuse: password-auth - Ensure "with-pwhistory" feature is enabled using authselect tool' ansible.builtin.command: cmd: authselect enable-feature with-pwhistory register: result_authselect_enable_feature_cmd when: - result_authselect_check_cmd is success - result_authselect_features.stdout is not search("with-pwhistory") - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_enable_feature_cmd is not skipped - result_authselect_enable_feature_cmd is success when: - accounts_password_pam_pwhistory_remember_password_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists - result_authselect_available_features.stdout is search("with-pwhistory") tags: - CCE-86354-8 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_password_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: 'Limit Password Reuse: password-auth - Enable pam_pwhistory.so in appropriate PAM files' block: - name: 'Limit Password Reuse: password-auth - Define the PAM file to be edited as a local fact' ansible.builtin.set_fact: pam_file_path: /etc/pam.d/password-auth - name: 'Limit Password Reuse: password-auth - Check if system relies on authselect tool' ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: 'Limit Password Reuse: password-auth - Ensure authselect custom profile is used if authselect is present' block: - name: 'Limit Password Reuse: password-auth - Check integrity of authselect current profile' ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: 'Limit Password Reuse: password-auth - Informative message based on the authselect integrity check result' ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: 'Limit Password Reuse: password-auth - Get authselect current profile' ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: 'Limit Password Reuse: password-auth - Define the current authselect profile as a local fact' ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: 'Limit Password Reuse: password-auth - Define the new authselect custom profile as a local fact' ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: 'Limit Password Reuse: password-auth - Get authselect current features to also enable them in the custom profile' ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: 'Limit Password Reuse: password-auth - Check if any custom profile with the same name was already created' ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: 'Limit Password Reuse: password-auth - Create an authselect custom profile based on the current profile' ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: 'Limit Password Reuse: password-auth - Ensure the authselect custom profile is selected' ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: 'Limit Password Reuse: password-auth - Restore the authselect features in the custom profile' ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: 'Limit Password Reuse: password-auth - Change the PAM file to be edited according to the custom authselect profile' ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: 'Limit Password Reuse: password-auth - Check if expected PAM module line is present in {{ pam_file_path }}' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+{{ var_password_pam_remember_control_flag.split(",")[0] }}\s+pam_pwhistory.so\s*.* state: absent check_mode: true changed_when: false register: result_pam_line_present - name: 'Limit Password Reuse: password-auth - Include or update the PAM module line in {{ pam_file_path }}' block: - name: 'Limit Password Reuse: password-auth - Check if required PAM module line is present in {{ pam_file_path }} with different control' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+.*\s+pam_pwhistory.so\s* state: absent check_mode: true changed_when: false register: result_pam_line_other_control_present - name: 'Limit Password Reuse: password-auth - Ensure the correct control for the required PAM module line in {{ pam_file_path }}' ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: ^(\s*password\s+).*(\bpam_pwhistory.so.*) replace: \1{{ var_password_pam_remember_control_flag.split(",")[0] }} \2 register: result_pam_module_edit when: - result_pam_line_other_control_present.found == 1 - name: 'Limit Password Reuse: password-auth - Ensure the required PAM module line is included in {{ pam_file_path }}' ansible.builtin.lineinfile: dest: '{{ pam_file_path }}' insertafter: ^password.*requisite.*pam_pwquality\.so line: password {{ var_password_pam_remember_control_flag.split(",")[0] }} pam_pwhistory.so register: result_pam_module_add when: - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found > 1 - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present is defined - result_authselect_present.stat.exists - "(result_pam_module_add is defined and result_pam_module_add.changed)\n or (result_pam_module_edit is defined and\ \ result_pam_module_edit.changed)" when: - result_pam_line_present.found is defined - result_pam_line_present.found == 0 when: - accounts_password_pam_pwhistory_remember_password_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' - '(result_authselect_available_features.stdout is defined and result_authselect_available_features.stdout is not search("with-pwhistory")) or result_authselect_available_features is not defined ' tags: - CCE-86354-8 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_password_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: 'Limit Password Reuse: password-auth - Check the presence of /etc/security/pwhistory.conf file' ansible.builtin.stat: path: /etc/security/pwhistory.conf register: result_pwhistory_conf_check when: - accounts_password_pam_pwhistory_remember_password_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' tags: - CCE-86354-8 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_password_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: 'Limit Password Reuse: password-auth - pam_pwhistory.so parameters are configured in /etc/security/pwhistory.conf file' block: - name: 'Limit Password Reuse: password-auth - Ensure the pam_pwhistory.so remember parameter in /etc/security/pwhistory.conf' ansible.builtin.lineinfile: path: /etc/security/pwhistory.conf regexp: ^\s*remember\s*= line: remember = {{ var_password_pam_remember }} state: present - name: 'Limit Password Reuse: password-auth - Ensure the pam_pwhistory.so remember parameter is removed from PAM files' block: - name: 'Limit Password Reuse: password-auth - Check if /etc/pam.d/password-auth file is present' ansible.builtin.stat: path: /etc/pam.d/password-auth register: result_pam_file_present - name: 'Limit Password Reuse: password-auth - Check the proper remediation for the system' block: - name: 'Limit Password Reuse: password-auth - Define the PAM file to be edited as a local fact' ansible.builtin.set_fact: pam_file_path: /etc/pam.d/password-auth - name: 'Limit Password Reuse: password-auth - Check if system relies on authselect tool' ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: 'Limit Password Reuse: password-auth - Ensure authselect custom profile is used if authselect is present' block: - name: 'Limit Password Reuse: password-auth - Check integrity of authselect current profile' ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: 'Limit Password Reuse: password-auth - Informative message based on the authselect integrity check result' ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: 'Limit Password Reuse: password-auth - Get authselect current profile' ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: 'Limit Password Reuse: password-auth - Define the current authselect profile as a local fact' ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: 'Limit Password Reuse: password-auth - Define the new authselect custom profile as a local fact' ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: 'Limit Password Reuse: password-auth - Get authselect current features to also enable them in the custom profile' ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: 'Limit Password Reuse: password-auth - Check if any custom profile with the same name was already created' ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: 'Limit Password Reuse: password-auth - Create an authselect custom profile based on the current profile' ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: 'Limit Password Reuse: password-auth - Ensure the authselect custom profile is selected' ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: 'Limit Password Reuse: password-auth - Restore the authselect features in the custom profile' ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: 'Limit Password Reuse: password-auth - Change the PAM file to be edited according to the custom authselect profile' ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: 'Limit Password Reuse: password-auth - Ensure the "remember" option from "pam_pwhistory.so" is not present in {{ pam_file_path }}' ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: (.*password.*pam_pwhistory.so.*)\bremember\b=?[0-9a-zA-Z]*(.*) replace: \1\2 register: result_pam_option_removal - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present.stat.exists - result_pam_option_removal is changed when: - result_pam_file_present.stat.exists when: - accounts_password_pam_pwhistory_remember_password_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' - result_pwhistory_conf_check.stat.exists tags: - CCE-86354-8 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_password_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: 'Limit Password Reuse: password-auth - pam_pwhistory.so parameters are configured in PAM files' block: - name: 'Limit Password Reuse: password-auth - Define the PAM file to be edited as a local fact' ansible.builtin.set_fact: pam_file_path: /etc/pam.d/password-auth - name: 'Limit Password Reuse: password-auth - Check if system relies on authselect tool' ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: 'Limit Password Reuse: password-auth - Ensure authselect custom profile is used if authselect is present' block: - name: 'Limit Password Reuse: password-auth - Check integrity of authselect current profile' ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: 'Limit Password Reuse: password-auth - Informative message based on the authselect integrity check result' ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: 'Limit Password Reuse: password-auth - Get authselect current profile' ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: 'Limit Password Reuse: password-auth - Define the current authselect profile as a local fact' ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: 'Limit Password Reuse: password-auth - Define the new authselect custom profile as a local fact' ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: 'Limit Password Reuse: password-auth - Get authselect current features to also enable them in the custom profile' ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: 'Limit Password Reuse: password-auth - Check if any custom profile with the same name was already created' ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: 'Limit Password Reuse: password-auth - Create an authselect custom profile based on the current profile' ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: 'Limit Password Reuse: password-auth - Ensure the authselect custom profile is selected' ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: 'Limit Password Reuse: password-auth - Restore the authselect features in the custom profile' ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: 'Limit Password Reuse: password-auth - Change the PAM file to be edited according to the custom authselect profile' ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: 'Limit Password Reuse: password-auth - Check if expected PAM module line is present in {{ pam_file_path }}' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+requisite\s+pam_pwhistory.so\s*.* state: absent check_mode: true changed_when: false register: result_pam_line_present - name: 'Limit Password Reuse: password-auth - Include or update the PAM module line in {{ pam_file_path }}' block: - name: 'Limit Password Reuse: password-auth - Check if required PAM module line is present in {{ pam_file_path }} with different control' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+.*\s+pam_pwhistory.so\s* state: absent check_mode: true changed_when: false register: result_pam_line_other_control_present - name: 'Limit Password Reuse: password-auth - Ensure the correct control for the required PAM module line in {{ pam_file_path }}' ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: ^(\s*password\s+).*(\bpam_pwhistory.so.*) replace: \1requisite \2 register: result_pam_module_edit when: - result_pam_line_other_control_present.found == 1 - name: 'Limit Password Reuse: password-auth - Ensure the required PAM module line is included in {{ pam_file_path }}' ansible.builtin.lineinfile: dest: '{{ pam_file_path }}' line: password requisite pam_pwhistory.so register: result_pam_module_add when: - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found > 1 - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present is defined - result_authselect_present.stat.exists - "(result_pam_module_add is defined and result_pam_module_add.changed)\n or (result_pam_module_edit is defined and\ \ result_pam_module_edit.changed)" when: - result_pam_line_present.found is defined - result_pam_line_present.found == 0 - name: 'Limit Password Reuse: password-auth - Check if the required PAM module option is present in {{ pam_file_path }}' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+requisite\s+pam_pwhistory.so\s*.*\sremember\b state: absent check_mode: true changed_when: false register: result_pam_module_remember_option_present - name: 'Limit Password Reuse: password-auth - Ensure the "remember" PAM option for "pam_pwhistory.so" is included in {{ pam_file_path }}' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true regexp: ^(\s*password\s+requisite\s+pam_pwhistory.so.*) line: \1 remember={{ var_password_pam_remember }} state: present register: result_pam_remember_add when: - result_pam_module_remember_option_present.found == 0 - name: 'Limit Password Reuse: password-auth - Ensure the required value for "remember" PAM option from "pam_pwhistory.so" in {{ pam_file_path }}' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true regexp: ^(\s*password\s+requisite\s+pam_pwhistory.so\s+.*)(remember)=[0-9a-zA-Z]+\s*(.*) line: \1\2={{ var_password_pam_remember }} \3 register: result_pam_remember_edit when: - result_pam_module_remember_option_present.found > 0 - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present.stat.exists - (result_pam_remember_add is defined and result_pam_remember_add.changed) or (result_pam_remember_edit is defined and result_pam_remember_edit.changed) when: - accounts_password_pam_pwhistory_remember_password_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' - not result_pwhistory_conf_check.stat.exists tags: - CCE-86354-8 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_password_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-89176-2 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_system_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed when: - accounts_password_pam_pwhistory_remember_system_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: 'Limit Password Reuse: system-auth - Check if system relies on authselect tool' ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present when: - accounts_password_pam_pwhistory_remember_system_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' tags: - CCE-89176-2 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_system_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: 'Limit Password Reuse: system-auth - Collect the available authselect features' ansible.builtin.command: cmd: authselect list-features minimal register: result_authselect_available_features changed_when: false when: - accounts_password_pam_pwhistory_remember_system_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists tags: - CCE-89176-2 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_system_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: 'Limit Password Reuse: system-auth - Enable pam_pwhistory.so using authselect feature' block: - name: 'Limit Password Reuse: system-auth - Check integrity of authselect current profile' ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: 'Limit Password Reuse: system-auth - Informative message based on the authselect integrity check result' ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: 'Limit Password Reuse: system-auth - Get authselect current features' ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_check_cmd is success - name: 'Limit Password Reuse: system-auth - Ensure "with-pwhistory" feature is enabled using authselect tool' ansible.builtin.command: cmd: authselect enable-feature with-pwhistory register: result_authselect_enable_feature_cmd when: - result_authselect_check_cmd is success - result_authselect_features.stdout is not search("with-pwhistory") - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_enable_feature_cmd is not skipped - result_authselect_enable_feature_cmd is success when: - accounts_password_pam_pwhistory_remember_system_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists - result_authselect_available_features.stdout is search("with-pwhistory") tags: - CCE-89176-2 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_system_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: 'Limit Password Reuse: system-auth - Enable pam_pwhistory.so in appropriate PAM files' block: - name: 'Limit Password Reuse: system-auth - Define the PAM file to be edited as a local fact' ansible.builtin.set_fact: pam_file_path: /etc/pam.d/system-auth - name: 'Limit Password Reuse: system-auth - Check if system relies on authselect tool' ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: 'Limit Password Reuse: system-auth - Ensure authselect custom profile is used if authselect is present' block: - name: 'Limit Password Reuse: system-auth - Check integrity of authselect current profile' ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: 'Limit Password Reuse: system-auth - Informative message based on the authselect integrity check result' ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: 'Limit Password Reuse: system-auth - Get authselect current profile' ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: 'Limit Password Reuse: system-auth - Define the current authselect profile as a local fact' ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: 'Limit Password Reuse: system-auth - Define the new authselect custom profile as a local fact' ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: 'Limit Password Reuse: system-auth - Get authselect current features to also enable them in the custom profile' ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: 'Limit Password Reuse: system-auth - Check if any custom profile with the same name was already created' ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: 'Limit Password Reuse: system-auth - Create an authselect custom profile based on the current profile' ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: 'Limit Password Reuse: system-auth - Ensure the authselect custom profile is selected' ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: 'Limit Password Reuse: system-auth - Restore the authselect features in the custom profile' ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: 'Limit Password Reuse: system-auth - Change the PAM file to be edited according to the custom authselect profile' ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: 'Limit Password Reuse: system-auth - Check if expected PAM module line is present in {{ pam_file_path }}' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+{{ var_password_pam_remember_control_flag.split(",")[0] }}\s+pam_pwhistory.so\s*.* state: absent check_mode: true changed_when: false register: result_pam_line_present - name: 'Limit Password Reuse: system-auth - Include or update the PAM module line in {{ pam_file_path }}' block: - name: 'Limit Password Reuse: system-auth - Check if required PAM module line is present in {{ pam_file_path }} with different control' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+.*\s+pam_pwhistory.so\s* state: absent check_mode: true changed_when: false register: result_pam_line_other_control_present - name: 'Limit Password Reuse: system-auth - Ensure the correct control for the required PAM module line in {{ pam_file_path }}' ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: ^(\s*password\s+).*(\bpam_pwhistory.so.*) replace: \1{{ var_password_pam_remember_control_flag.split(",")[0] }} \2 register: result_pam_module_edit when: - result_pam_line_other_control_present.found == 1 - name: 'Limit Password Reuse: system-auth - Ensure the required PAM module line is included in {{ pam_file_path }}' ansible.builtin.lineinfile: dest: '{{ pam_file_path }}' insertafter: ^password.*requisite.*pam_pwquality\.so line: password {{ var_password_pam_remember_control_flag.split(",")[0] }} pam_pwhistory.so register: result_pam_module_add when: - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found > 1 - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present is defined - result_authselect_present.stat.exists - "(result_pam_module_add is defined and result_pam_module_add.changed)\n or (result_pam_module_edit is defined and\ \ result_pam_module_edit.changed)" when: - result_pam_line_present.found is defined - result_pam_line_present.found == 0 when: - accounts_password_pam_pwhistory_remember_system_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' - '(result_authselect_available_features.stdout is defined and result_authselect_available_features.stdout is not search("with-pwhistory")) or result_authselect_available_features is not defined ' tags: - CCE-89176-2 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_system_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: 'Limit Password Reuse: system-auth - Check the presence of /etc/security/pwhistory.conf file' ansible.builtin.stat: path: /etc/security/pwhistory.conf register: result_pwhistory_conf_check when: - accounts_password_pam_pwhistory_remember_system_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' tags: - CCE-89176-2 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_system_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: 'Limit Password Reuse: system-auth - pam_pwhistory.so parameters are configured in /etc/security/pwhistory.conf file' block: - name: 'Limit Password Reuse: system-auth - Ensure the pam_pwhistory.so remember parameter in /etc/security/pwhistory.conf' ansible.builtin.lineinfile: path: /etc/security/pwhistory.conf regexp: ^\s*remember\s*= line: remember = {{ var_password_pam_remember }} state: present - name: 'Limit Password Reuse: system-auth - Ensure the pam_pwhistory.so remember parameter is removed from PAM files' block: - name: 'Limit Password Reuse: system-auth - Check if /etc/pam.d/system-auth file is present' ansible.builtin.stat: path: /etc/pam.d/system-auth register: result_pam_file_present - name: 'Limit Password Reuse: system-auth - Check the proper remediation for the system' block: - name: 'Limit Password Reuse: system-auth - Define the PAM file to be edited as a local fact' ansible.builtin.set_fact: pam_file_path: /etc/pam.d/system-auth - name: 'Limit Password Reuse: system-auth - Check if system relies on authselect tool' ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: 'Limit Password Reuse: system-auth - Ensure authselect custom profile is used if authselect is present' block: - name: 'Limit Password Reuse: system-auth - Check integrity of authselect current profile' ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: 'Limit Password Reuse: system-auth - Informative message based on the authselect integrity check result' ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: 'Limit Password Reuse: system-auth - Get authselect current profile' ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: 'Limit Password Reuse: system-auth - Define the current authselect profile as a local fact' ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: 'Limit Password Reuse: system-auth - Define the new authselect custom profile as a local fact' ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: 'Limit Password Reuse: system-auth - Get authselect current features to also enable them in the custom profile' ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: 'Limit Password Reuse: system-auth - Check if any custom profile with the same name was already created' ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: 'Limit Password Reuse: system-auth - Create an authselect custom profile based on the current profile' ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: 'Limit Password Reuse: system-auth - Ensure the authselect custom profile is selected' ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: 'Limit Password Reuse: system-auth - Restore the authselect features in the custom profile' ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: 'Limit Password Reuse: system-auth - Change the PAM file to be edited according to the custom authselect profile' ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: 'Limit Password Reuse: system-auth - Ensure the "remember" option from "pam_pwhistory.so" is not present in {{ pam_file_path }}' ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: (.*password.*pam_pwhistory.so.*)\bremember\b=?[0-9a-zA-Z]*(.*) replace: \1\2 register: result_pam_option_removal - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present.stat.exists - result_pam_option_removal is changed when: - result_pam_file_present.stat.exists when: - accounts_password_pam_pwhistory_remember_system_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' - result_pwhistory_conf_check.stat.exists tags: - CCE-89176-2 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_system_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: 'Limit Password Reuse: system-auth - pam_pwhistory.so parameters are configured in PAM files' block: - name: 'Limit Password Reuse: system-auth - Define the PAM file to be edited as a local fact' ansible.builtin.set_fact: pam_file_path: /etc/pam.d/system-auth - name: 'Limit Password Reuse: system-auth - Check if system relies on authselect tool' ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: 'Limit Password Reuse: system-auth - Ensure authselect custom profile is used if authselect is present' block: - name: 'Limit Password Reuse: system-auth - Check integrity of authselect current profile' ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: 'Limit Password Reuse: system-auth - Informative message based on the authselect integrity check result' ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: 'Limit Password Reuse: system-auth - Get authselect current profile' ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: 'Limit Password Reuse: system-auth - Define the current authselect profile as a local fact' ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: 'Limit Password Reuse: system-auth - Define the new authselect custom profile as a local fact' ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: 'Limit Password Reuse: system-auth - Get authselect current features to also enable them in the custom profile' ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: 'Limit Password Reuse: system-auth - Check if any custom profile with the same name was already created' ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: 'Limit Password Reuse: system-auth - Create an authselect custom profile based on the current profile' ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: 'Limit Password Reuse: system-auth - Ensure the authselect custom profile is selected' ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: 'Limit Password Reuse: system-auth - Restore the authselect features in the custom profile' ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: 'Limit Password Reuse: system-auth - Change the PAM file to be edited according to the custom authselect profile' ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: 'Limit Password Reuse: system-auth - Check if expected PAM module line is present in {{ pam_file_path }}' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+requisite\s+pam_pwhistory.so\s*.* state: absent check_mode: true changed_when: false register: result_pam_line_present - name: 'Limit Password Reuse: system-auth - Include or update the PAM module line in {{ pam_file_path }}' block: - name: 'Limit Password Reuse: system-auth - Check if required PAM module line is present in {{ pam_file_path }} with different control' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+.*\s+pam_pwhistory.so\s* state: absent check_mode: true changed_when: false register: result_pam_line_other_control_present - name: 'Limit Password Reuse: system-auth - Ensure the correct control for the required PAM module line in {{ pam_file_path }}' ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: ^(\s*password\s+).*(\bpam_pwhistory.so.*) replace: \1requisite \2 register: result_pam_module_edit when: - result_pam_line_other_control_present.found == 1 - name: 'Limit Password Reuse: system-auth - Ensure the required PAM module line is included in {{ pam_file_path }}' ansible.builtin.lineinfile: dest: '{{ pam_file_path }}' line: password requisite pam_pwhistory.so register: result_pam_module_add when: - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found > 1 - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present is defined - result_authselect_present.stat.exists - "(result_pam_module_add is defined and result_pam_module_add.changed)\n or (result_pam_module_edit is defined and\ \ result_pam_module_edit.changed)" when: - result_pam_line_present.found is defined - result_pam_line_present.found == 0 - name: 'Limit Password Reuse: system-auth - Check if the required PAM module option is present in {{ pam_file_path }}' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+requisite\s+pam_pwhistory.so\s*.*\sremember\b state: absent check_mode: true changed_when: false register: result_pam_module_remember_option_present - name: 'Limit Password Reuse: system-auth - Ensure the "remember" PAM option for "pam_pwhistory.so" is included in {{ pam_file_path }}' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true regexp: ^(\s*password\s+requisite\s+pam_pwhistory.so.*) line: \1 remember={{ var_password_pam_remember }} state: present register: result_pam_remember_add when: - result_pam_module_remember_option_present.found == 0 - name: 'Limit Password Reuse: system-auth - Ensure the required value for "remember" PAM option from "pam_pwhistory.so" in {{ pam_file_path }}' ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true regexp: ^(\s*password\s+requisite\s+pam_pwhistory.so\s+.*)(remember)=[0-9a-zA-Z]+\s*(.*) line: \1\2={{ var_password_pam_remember }} \3 register: result_pam_remember_edit when: - result_pam_module_remember_option_present.found > 0 - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied' ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present.stat.exists - (result_pam_remember_add is defined and result_pam_remember_add.changed) or (result_pam_remember_edit is defined and result_pam_remember_edit.changed) when: - accounts_password_pam_pwhistory_remember_system_auth | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' - not result_pwhistory_conf_check.stat.exists tags: - CCE-89176-2 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-IA-5(1)(e) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.5 - accounts_password_pam_pwhistory_remember_system_auth - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-83587-6 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.6 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_deny - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_passwords_pam_faillock_deny | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Lock Accounts After Failed Password Attempts - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present when: - accounts_passwords_pam_faillock_deny | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' tags: - CCE-83587-6 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.6 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_deny - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Lock Accounts After Failed Password Attempts - Remediation where authselect tool is present block: - name: Lock Accounts After Failed Password Attempts - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Lock Accounts After Failed Password Attempts - Informative message based on the authselect integrity check result ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: Lock Accounts After Failed Password Attempts - Get authselect current features ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_check_cmd is success - name: Lock Accounts After Failed Password Attempts - Ensure "with-faillock" feature is enabled using authselect tool ansible.builtin.command: cmd: authselect enable-feature with-faillock register: result_authselect_enable_feature_cmd when: - result_authselect_check_cmd is success - result_authselect_features.stdout is not search("with-faillock") - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_enable_feature_cmd is not skipped - result_authselect_enable_feature_cmd is success when: - accounts_passwords_pam_faillock_deny | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists tags: - CCE-83587-6 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.6 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_deny - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Lock Accounts After Failed Password Attempts - Remediation where authselect tool is not present block: - name: Lock Accounts After Failed Password Attempts - Check if pam_faillock.so is already enabled ansible.builtin.lineinfile: path: /etc/pam.d/system-auth regexp: .*auth.*pam_faillock\.so (preauth|authfail) state: absent check_mode: true changed_when: false register: result_pam_faillock_is_enabled - name: Lock Accounts After Failed Password Attempts - Enable pam_faillock.so preauth editing PAM files ansible.builtin.lineinfile: path: '{{ item }}' line: auth required pam_faillock.so preauth insertbefore: ^auth.*sufficient.*pam_unix\.so.* state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_is_enabled.found == 0 - name: Lock Accounts After Failed Password Attempts - Enable pam_faillock.so authfail editing PAM files ansible.builtin.lineinfile: path: '{{ item }}' line: auth required pam_faillock.so authfail insertbefore: ^auth.*required.*pam_deny\.so.* state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_is_enabled.found == 0 - name: Lock Accounts After Failed Password Attempts - Enable pam_faillock.so account section editing PAM files ansible.builtin.lineinfile: path: '{{ item }}' line: account required pam_faillock.so insertbefore: ^account.*required.*pam_unix\.so.* state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_is_enabled.found == 0 when: - accounts_passwords_pam_faillock_deny | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' - not result_authselect_present.stat.exists tags: - CCE-83587-6 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.6 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_deny - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Lock Accounts After Failed Password Attempts - Check the presence of /etc/security/faillock.conf file ansible.builtin.stat: path: /etc/security/faillock.conf register: result_faillock_conf_check when: - accounts_passwords_pam_faillock_deny | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' tags: - CCE-83587-6 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.6 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_deny - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so deny parameter in /etc/security/faillock.conf ansible.builtin.lineinfile: path: /etc/security/faillock.conf regexp: ^\s*deny\s*= line: deny = {{ var_accounts_passwords_pam_faillock_deny }} state: present when: - accounts_passwords_pam_faillock_deny | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' - result_faillock_conf_check.stat.exists tags: - CCE-83587-6 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.6 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_deny - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so deny parameter not in PAM files block: - name: Lock Accounts After Failed Password Attempts - Check if /etc/pam.d/system-auth file is present ansible.builtin.stat: path: /etc/pam.d/system-auth register: result_pam_file_present - name: Lock Accounts After Failed Password Attempts - Check the proper remediation for the system block: - name: Lock Accounts After Failed Password Attempts - Define the PAM file to be edited as a local fact ansible.builtin.set_fact: pam_file_path: /etc/pam.d/system-auth - name: Lock Accounts After Failed Password Attempts - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: Lock Accounts After Failed Password Attempts - Ensure authselect custom profile is used if authselect is present block: - name: Lock Accounts After Failed Password Attempts - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Lock Accounts After Failed Password Attempts - Informative message based on the authselect integrity check result ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: Lock Accounts After Failed Password Attempts - Get authselect current profile ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: Lock Accounts After Failed Password Attempts - Define the current authselect profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: Lock Accounts After Failed Password Attempts - Define the new authselect custom profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: Lock Accounts After Failed Password Attempts - Get authselect current features to also enable them in the custom profile ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: Lock Accounts After Failed Password Attempts - Check if any custom profile with the same name was already created ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: Lock Accounts After Failed Password Attempts - Create an authselect custom profile based on the current profile ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Lock Accounts After Failed Password Attempts - Ensure the authselect custom profile is selected ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Lock Accounts After Failed Password Attempts - Restore the authselect features in the custom profile ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: Lock Accounts After Failed Password Attempts - Change the PAM file to be edited according to the custom authselect profile ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: Lock Accounts After Failed Password Attempts - Ensure the "deny" option from "pam_faillock.so" is not present in {{ pam_file_path }} ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: (.*auth.*pam_faillock.so.*)\bdeny\b=?[0-9a-zA-Z]*(.*) replace: \1\2 register: result_pam_option_removal - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present.stat.exists - result_pam_option_removal is changed when: - result_pam_file_present.stat.exists - name: Lock Accounts After Failed Password Attempts - Check if /etc/pam.d/password-auth file is present ansible.builtin.stat: path: /etc/pam.d/password-auth register: result_pam_file_present - name: Lock Accounts After Failed Password Attempts - Check the proper remediation for the system block: - name: Lock Accounts After Failed Password Attempts - Define the PAM file to be edited as a local fact ansible.builtin.set_fact: pam_file_path: /etc/pam.d/password-auth - name: Lock Accounts After Failed Password Attempts - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: Lock Accounts After Failed Password Attempts - Ensure authselect custom profile is used if authselect is present block: - name: Lock Accounts After Failed Password Attempts - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Lock Accounts After Failed Password Attempts - Informative message based on the authselect integrity check result ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: Lock Accounts After Failed Password Attempts - Get authselect current profile ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: Lock Accounts After Failed Password Attempts - Define the current authselect profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: Lock Accounts After Failed Password Attempts - Define the new authselect custom profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: Lock Accounts After Failed Password Attempts - Get authselect current features to also enable them in the custom profile ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: Lock Accounts After Failed Password Attempts - Check if any custom profile with the same name was already created ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: Lock Accounts After Failed Password Attempts - Create an authselect custom profile based on the current profile ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Lock Accounts After Failed Password Attempts - Ensure the authselect custom profile is selected ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Lock Accounts After Failed Password Attempts - Restore the authselect features in the custom profile ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: Lock Accounts After Failed Password Attempts - Change the PAM file to be edited according to the custom authselect profile ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: Lock Accounts After Failed Password Attempts - Ensure the "deny" option from "pam_faillock.so" is not present in {{ pam_file_path }} ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: (.*auth.*pam_faillock.so.*)\bdeny\b=?[0-9a-zA-Z]*(.*) replace: \1\2 register: result_pam_option_removal - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present.stat.exists - result_pam_option_removal is changed when: - result_pam_file_present.stat.exists when: - accounts_passwords_pam_faillock_deny | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' - result_faillock_conf_check.stat.exists tags: - CCE-83587-6 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.6 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_deny - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so deny parameter in PAM files block: - name: Lock Accounts After Failed Password Attempts - Check if pam_faillock.so deny parameter is already enabled in pam files ansible.builtin.lineinfile: path: /etc/pam.d/system-auth regexp: .*auth.*pam_faillock\.so (preauth|authfail).*deny state: absent check_mode: true changed_when: false register: result_pam_faillock_deny_parameter_is_present - name: Lock Accounts After Failed Password Attempts - Ensure the inclusion of pam_faillock.so preauth deny parameter in auth section ansible.builtin.lineinfile: path: '{{ item }}' backrefs: true regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*) line: \1required\3 deny={{ var_accounts_passwords_pam_faillock_deny }} state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_deny_parameter_is_present.found == 0 - name: Lock Accounts After Failed Password Attempts - Ensure the inclusion of pam_faillock.so authfail deny parameter in auth section ansible.builtin.lineinfile: path: '{{ item }}' backrefs: true regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*) line: \1required\3 deny={{ var_accounts_passwords_pam_faillock_deny }} state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_deny_parameter_is_present.found == 0 - name: Lock Accounts After Failed Password Attempts - Ensure the desired value for pam_faillock.so preauth deny parameter in auth section ansible.builtin.lineinfile: path: '{{ item }}' backrefs: true regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(deny)=[0-9]+(.*) line: \1required\3\4={{ var_accounts_passwords_pam_faillock_deny }}\5 state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_deny_parameter_is_present.found > 0 - name: Lock Accounts After Failed Password Attempts - Ensure the desired value for pam_faillock.so authfail deny parameter in auth section ansible.builtin.lineinfile: path: '{{ item }}' backrefs: true regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(deny)=[0-9]+(.*) line: \1required\3\4={{ var_accounts_passwords_pam_faillock_deny }}\5 state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_deny_parameter_is_present.found > 0 when: - accounts_passwords_pam_faillock_deny | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' - not result_faillock_conf_check.stat.exists tags: - CCE-83587-6 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.6 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_deny - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83588-4 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.7 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_unlock_time - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_passwords_pam_faillock_unlock_time | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Set Lockout Time for Failed Password Attempts - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present when: - accounts_passwords_pam_faillock_unlock_time | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' tags: - CCE-83588-4 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.7 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_unlock_time - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set Lockout Time for Failed Password Attempts - Remediation where authselect tool is present block: - name: Set Lockout Time for Failed Password Attempts - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Set Lockout Time for Failed Password Attempts - Informative message based on the authselect integrity check result ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: Set Lockout Time for Failed Password Attempts - Get authselect current features ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_check_cmd is success - name: Set Lockout Time for Failed Password Attempts - Ensure "with-faillock" feature is enabled using authselect tool ansible.builtin.command: cmd: authselect enable-feature with-faillock register: result_authselect_enable_feature_cmd when: - result_authselect_check_cmd is success - result_authselect_features.stdout is not search("with-faillock") - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_enable_feature_cmd is not skipped - result_authselect_enable_feature_cmd is success when: - accounts_passwords_pam_faillock_unlock_time | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists tags: - CCE-83588-4 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.7 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_unlock_time - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set Lockout Time for Failed Password Attempts - Remediation where authselect tool is not present block: - name: Set Lockout Time for Failed Password Attempts - Check if pam_faillock.so is already enabled ansible.builtin.lineinfile: path: /etc/pam.d/system-auth regexp: .*auth.*pam_faillock\.so (preauth|authfail) state: absent check_mode: true changed_when: false register: result_pam_faillock_is_enabled - name: Set Lockout Time for Failed Password Attempts - Enable pam_faillock.so preauth editing PAM files ansible.builtin.lineinfile: path: '{{ item }}' line: auth required pam_faillock.so preauth insertbefore: ^auth.*sufficient.*pam_unix\.so.* state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_is_enabled.found == 0 - name: Set Lockout Time for Failed Password Attempts - Enable pam_faillock.so authfail editing PAM files ansible.builtin.lineinfile: path: '{{ item }}' line: auth required pam_faillock.so authfail insertbefore: ^auth.*required.*pam_deny\.so.* state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_is_enabled.found == 0 - name: Set Lockout Time for Failed Password Attempts - Enable pam_faillock.so account section editing PAM files ansible.builtin.lineinfile: path: '{{ item }}' line: account required pam_faillock.so insertbefore: ^account.*required.*pam_unix\.so.* state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_is_enabled.found == 0 when: - accounts_passwords_pam_faillock_unlock_time | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' - not result_authselect_present.stat.exists tags: - CCE-83588-4 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.7 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_unlock_time - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set Lockout Time for Failed Password Attempts - Check the presence of /etc/security/faillock.conf file ansible.builtin.stat: path: /etc/security/faillock.conf register: result_faillock_conf_check when: - accounts_passwords_pam_faillock_unlock_time | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' tags: - CCE-83588-4 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.7 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_unlock_time - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set Lockout Time for Failed Password Attempts - Ensure the pam_faillock.so unlock_time parameter in /etc/security/faillock.conf ansible.builtin.lineinfile: path: /etc/security/faillock.conf regexp: ^\s*unlock_time\s*= line: unlock_time = {{ var_accounts_passwords_pam_faillock_unlock_time }} state: present when: - accounts_passwords_pam_faillock_unlock_time | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' - result_faillock_conf_check.stat.exists tags: - CCE-83588-4 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.7 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_unlock_time - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set Lockout Time for Failed Password Attempts - Ensure the pam_faillock.so unlock_time parameter not in PAM files block: - name: Set Lockout Time for Failed Password Attempts - Check if /etc/pam.d/system-auth file is present ansible.builtin.stat: path: /etc/pam.d/system-auth register: result_pam_file_present - name: Set Lockout Time for Failed Password Attempts - Check the proper remediation for the system block: - name: Set Lockout Time for Failed Password Attempts - Define the PAM file to be edited as a local fact ansible.builtin.set_fact: pam_file_path: /etc/pam.d/system-auth - name: Set Lockout Time for Failed Password Attempts - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: Set Lockout Time for Failed Password Attempts - Ensure authselect custom profile is used if authselect is present block: - name: Set Lockout Time for Failed Password Attempts - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Set Lockout Time for Failed Password Attempts - Informative message based on the authselect integrity check result ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: Set Lockout Time for Failed Password Attempts - Get authselect current profile ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: Set Lockout Time for Failed Password Attempts - Define the current authselect profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: Set Lockout Time for Failed Password Attempts - Define the new authselect custom profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: Set Lockout Time for Failed Password Attempts - Get authselect current features to also enable them in the custom profile ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: Set Lockout Time for Failed Password Attempts - Check if any custom profile with the same name was already created ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: Set Lockout Time for Failed Password Attempts - Create an authselect custom profile based on the current profile ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Set Lockout Time for Failed Password Attempts - Ensure the authselect custom profile is selected ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Set Lockout Time for Failed Password Attempts - Restore the authselect features in the custom profile ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: Set Lockout Time for Failed Password Attempts - Change the PAM file to be edited according to the custom authselect profile ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: Set Lockout Time for Failed Password Attempts - Ensure the "unlock_time" option from "pam_faillock.so" is not present in {{ pam_file_path }} ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: (.*auth.*pam_faillock.so.*)\bunlock_time\b=?[0-9a-zA-Z]*(.*) replace: \1\2 register: result_pam_option_removal - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present.stat.exists - result_pam_option_removal is changed when: - result_pam_file_present.stat.exists - name: Set Lockout Time for Failed Password Attempts - Check if /etc/pam.d/password-auth file is present ansible.builtin.stat: path: /etc/pam.d/password-auth register: result_pam_file_present - name: Set Lockout Time for Failed Password Attempts - Check the proper remediation for the system block: - name: Set Lockout Time for Failed Password Attempts - Define the PAM file to be edited as a local fact ansible.builtin.set_fact: pam_file_path: /etc/pam.d/password-auth - name: Set Lockout Time for Failed Password Attempts - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: Set Lockout Time for Failed Password Attempts - Ensure authselect custom profile is used if authselect is present block: - name: Set Lockout Time for Failed Password Attempts - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Set Lockout Time for Failed Password Attempts - Informative message based on the authselect integrity check result ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: Set Lockout Time for Failed Password Attempts - Get authselect current profile ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: Set Lockout Time for Failed Password Attempts - Define the current authselect profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: Set Lockout Time for Failed Password Attempts - Define the new authselect custom profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: Set Lockout Time for Failed Password Attempts - Get authselect current features to also enable them in the custom profile ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: Set Lockout Time for Failed Password Attempts - Check if any custom profile with the same name was already created ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: Set Lockout Time for Failed Password Attempts - Create an authselect custom profile based on the current profile ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Set Lockout Time for Failed Password Attempts - Ensure the authselect custom profile is selected ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Set Lockout Time for Failed Password Attempts - Restore the authselect features in the custom profile ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: Set Lockout Time for Failed Password Attempts - Change the PAM file to be edited according to the custom authselect profile ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: Set Lockout Time for Failed Password Attempts - Ensure the "unlock_time" option from "pam_faillock.so" is not present in {{ pam_file_path }} ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: (.*auth.*pam_faillock.so.*)\bunlock_time\b=?[0-9a-zA-Z]*(.*) replace: \1\2 register: result_pam_option_removal - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present.stat.exists - result_pam_option_removal is changed when: - result_pam_file_present.stat.exists when: - accounts_passwords_pam_faillock_unlock_time | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' - result_faillock_conf_check.stat.exists tags: - CCE-83588-4 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.7 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_unlock_time - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set Lockout Time for Failed Password Attempts - Ensure the pam_faillock.so unlock_time parameter in PAM files block: - name: Set Lockout Time for Failed Password Attempts - Check if pam_faillock.so unlock_time parameter is already enabled in pam files ansible.builtin.lineinfile: path: /etc/pam.d/system-auth regexp: .*auth.*pam_faillock\.so (preauth|authfail).*unlock_time state: absent check_mode: true changed_when: false register: result_pam_faillock_unlock_time_parameter_is_present - name: Set Lockout Time for Failed Password Attempts - Ensure the inclusion of pam_faillock.so preauth unlock_time parameter in auth section ansible.builtin.lineinfile: path: '{{ item }}' backrefs: true regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*) line: \1required\3 unlock_time={{ var_accounts_passwords_pam_faillock_unlock_time }} state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_unlock_time_parameter_is_present.found == 0 - name: Set Lockout Time for Failed Password Attempts - Ensure the inclusion of pam_faillock.so authfail unlock_time parameter in auth section ansible.builtin.lineinfile: path: '{{ item }}' backrefs: true regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*) line: \1required\3 unlock_time={{ var_accounts_passwords_pam_faillock_unlock_time }} state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_unlock_time_parameter_is_present.found == 0 - name: Set Lockout Time for Failed Password Attempts - Ensure the desired value for pam_faillock.so preauth unlock_time parameter in auth section ansible.builtin.lineinfile: path: '{{ item }}' backrefs: true regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(unlock_time)=[0-9]+(.*) line: \1required\3\4={{ var_accounts_passwords_pam_faillock_unlock_time }}\5 state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_unlock_time_parameter_is_present.found > 0 - name: Set Lockout Time for Failed Password Attempts - Ensure the desired value for pam_faillock.so authfail unlock_time parameter in auth section ansible.builtin.lineinfile: path: '{{ item }}' backrefs: true regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(unlock_time)=[0-9]+(.*) line: \1required\3\4={{ var_accounts_passwords_pam_faillock_unlock_time }}\5 state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_unlock_time_parameter_is_present.found > 0 when: - accounts_passwords_pam_faillock_unlock_time | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' - not result_faillock_conf_check.stat.exists tags: - CCE-83588-4 - CJIS-5.5.3 - NIST-800-171-3.1.8 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.7 - PCI-DSSv4-8.3.4 - accounts_passwords_pam_faillock_unlock_time - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83563-7 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(a) - NIST-800-53-IA-5(4) - NIST-800-53-IA-5(c) - accounts_password_pam_minclass - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_password_pam_minclass | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Ensure PAM Enforces Password Requirements - Minimum Different Categories - Ensure PAM variable minclass is set accordingly ansible.builtin.lineinfile: create: true dest: /etc/security/pwquality.conf regexp: ^#?\s*minclass line: minclass = {{ var_password_pam_minclass }} when: - accounts_password_pam_minclass | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' tags: - CCE-83563-7 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(a) - NIST-800-53-IA-5(4) - NIST-800-53-IA-5(c) - accounts_password_pam_minclass - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83579-3 - CJIS-5.6.2.1.1 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(a) - NIST-800-53-IA-5(4) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.3 - PCI-DSSv4-8.3.6 - PCI-DSSv4-8.3.9 - accounts_password_pam_minlen - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_password_pam_minlen | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Ensure PAM Enforces Password Requirements - Minimum Length - Ensure PAM variable minlen is set accordingly ansible.builtin.lineinfile: create: true dest: /etc/security/pwquality.conf regexp: ^#?\s*minlen line: minlen = {{ var_password_pam_minlen }} when: - accounts_password_pam_minlen | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"pam" in ansible_facts.packages' tags: - CCE-83579-3 - CJIS-5.6.2.1.1 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(a) - NIST-800-53-IA-5(4) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.3 - PCI-DSSv4-8.3.6 - PCI-DSSv4-8.3.9 - accounts_password_pam_minlen - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83569-4 - CJIS-5.5.3 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(4) - accounts_password_pam_retry - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed when: - accounts_password_pam_retry | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure PAM variable retry is set accordingly ansible.builtin.lineinfile: create: true dest: /etc/security/pwquality.conf regexp: ^\s*retry line: retry = {{ var_password_pam_retry }} when: - accounts_password_pam_retry | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' tags: - CCE-83569-4 - CJIS-5.5.3 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(4) - accounts_password_pam_retry - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Check if /etc/pam.d/password-auth file is present ansible.builtin.stat: path: /etc/pam.d/password-auth register: result_pam_file_present when: - accounts_password_pam_retry | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' tags: - CCE-83569-4 - CJIS-5.5.3 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(4) - accounts_password_pam_retry - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Check the proper remediation for the system block: - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Define the PAM file to be edited as a local fact ansible.builtin.set_fact: pam_file_path: /etc/pam.d/password-auth - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Ensure authselect custom profile is used if authselect is present block: - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Informative message based on the authselect integrity check result ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Get authselect current profile ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Define the current authselect profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Define the new authselect custom profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Get authselect current features to also enable them in the custom profile ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Check if any custom profile with the same name was already created ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Create an authselect custom profile based on the current profile ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Ensure the authselect custom profile is selected ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Restore the authselect features in the custom profile ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Change the PAM file to be edited according to the custom authselect profile ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Ensure the "retry" option from "pam_pwquality.so" is not present in {{ pam_file_path }} ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: (.*password.*.*.*pam_pwquality.so.*)\bretry\b=?[0-9a-zA-Z]*(.*) replace: \1\2 register: result_pam_option_removal - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present.stat.exists - result_pam_option_removal is changed when: - accounts_password_pam_retry | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' - result_pam_file_present.stat.exists tags: - CCE-83569-4 - CJIS-5.5.3 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(4) - accounts_password_pam_retry - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Check if /etc/pam.d/system-auth file is present ansible.builtin.stat: path: /etc/pam.d/system-auth register: result_pam_file_present when: - accounts_password_pam_retry | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' tags: - CCE-83569-4 - CJIS-5.5.3 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(4) - accounts_password_pam_retry - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Check the proper remediation for the system block: - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Define the PAM file to be edited as a local fact ansible.builtin.set_fact: pam_file_path: /etc/pam.d/system-auth - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Ensure authselect custom profile is used if authselect is present block: - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Informative message based on the authselect integrity check result ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Get authselect current profile ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Define the current authselect profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Define the new authselect custom profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Get authselect current features to also enable them in the custom profile ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Check if any custom profile with the same name was already created ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Create an authselect custom profile based on the current profile ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Ensure the authselect custom profile is selected ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Restore the authselect features in the custom profile ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Change the PAM file to be edited according to the custom authselect profile ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Ensure the "retry" option from "pam_pwquality.so" is not present in {{ pam_file_path }} ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: (.*password.*.*.*pam_pwquality.so.*)\bretry\b=?[0-9a-zA-Z]*(.*) replace: \1\2 register: result_pam_option_removal - name: Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present.stat.exists - result_pam_option_removal is changed when: - accounts_password_pam_retry | bool - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"pam" in ansible_facts.packages' - result_pam_file_present.stat.exists tags: - CCE-83569-4 - CJIS-5.5.3 - NIST-800-53-AC-7(a) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(4) - accounts_password_pam_retry - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-90590-1 - CJIS-5.6.2.2 - NIST-800-171-3.13.11 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(c) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.1 - PCI-DSSv4-8.3.2 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - set_password_hashing_algorithm_logindefs when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - set_password_hashing_algorithm_logindefs | bool - name: Set Password Hashing Algorithm in /etc/login.defs lineinfile: dest: /etc/login.defs regexp: ^#?ENCRYPT_METHOD line: ENCRYPT_METHOD {{ var_password_hashing_algorithm }} state: present create: true when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - set_password_hashing_algorithm_logindefs | bool - '"shadow-utils" in ansible_facts.packages' tags: - CCE-90590-1 - CJIS-5.6.2.2 - NIST-800-171-3.13.11 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(c) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.1 - PCI-DSSv4-8.3.2 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - set_password_hashing_algorithm_logindefs - name: Gather the package facts package_facts: manager: auto tags: - CCE-85946-2 - CJIS-5.6.2.2 - NIST-800-171-3.13.11 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(c) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.1 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - set_password_hashing_algorithm_passwordauth when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - set_password_hashing_algorithm_passwordauth | bool - name: Set PAM's Password Hashing Algorithm - password-auth - Check if /etc/pam.d/password-auth file is present ansible.builtin.stat: path: /etc/pam.d/password-auth register: result_pam_file_present when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - set_password_hashing_algorithm_passwordauth | bool - '"pam" in ansible_facts.packages' tags: - CCE-85946-2 - CJIS-5.6.2.2 - NIST-800-171-3.13.11 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(c) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.1 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - set_password_hashing_algorithm_passwordauth - name: Set PAM's Password Hashing Algorithm - password-auth - Check the proper remediation for the system block: - name: Set PAM's Password Hashing Algorithm - password-auth - Define the PAM file to be edited as a local fact ansible.builtin.set_fact: pam_file_path: /etc/pam.d/password-auth - name: Set PAM's Password Hashing Algorithm - password-auth - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect custom profile is used if authselect is present block: - name: Set PAM's Password Hashing Algorithm - password-auth - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Set PAM's Password Hashing Algorithm - password-auth - Informative message based on the authselect integrity check result ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: Set PAM's Password Hashing Algorithm - password-auth - Get authselect current profile ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: Set PAM's Password Hashing Algorithm - password-auth - Define the current authselect profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: Set PAM's Password Hashing Algorithm - password-auth - Define the new authselect custom profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: Set PAM's Password Hashing Algorithm - password-auth - Get authselect current features to also enable them in the custom profile ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: Set PAM's Password Hashing Algorithm - password-auth - Check if any custom profile with the same name was already created ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: Set PAM's Password Hashing Algorithm - password-auth - Create an authselect custom profile based on the current profile ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the authselect custom profile is selected ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Set PAM's Password Hashing Algorithm - password-auth - Restore the authselect features in the custom profile ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: Set PAM's Password Hashing Algorithm - password-auth - Change the PAM file to be edited according to the custom authselect profile ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: Set PAM's Password Hashing Algorithm - password-auth - Check if expected PAM module line is present in {{ pam_file_path }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+sufficient\s+pam_unix.so\s*.* state: absent check_mode: true changed_when: false register: result_pam_line_present - name: Set PAM's Password Hashing Algorithm - password-auth - Include or update the PAM module line in {{ pam_file_path }} block: - name: Set PAM's Password Hashing Algorithm - password-auth - Check if required PAM module line is present in {{ pam_file_path }} with different control ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+.*\s+pam_unix.so\s* state: absent check_mode: true changed_when: false register: result_pam_line_other_control_present - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the correct control for the required PAM module line in {{ pam_file_path }} ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: ^(\s*password\s+).*(\bpam_unix.so.*) replace: \1sufficient \2 register: result_pam_module_edit when: - result_pam_line_other_control_present.found == 1 - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the required PAM module line is included in {{ pam_file_path }} ansible.builtin.lineinfile: dest: '{{ pam_file_path }}' line: password sufficient pam_unix.so register: result_pam_module_add when: - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found > 1 - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present is defined - result_authselect_present.stat.exists - "(result_pam_module_add is defined and result_pam_module_add.changed)\n or (result_pam_module_edit is defined and\ \ result_pam_module_edit.changed)" when: - result_pam_line_present.found is defined - result_pam_line_present.found == 0 - name: Set PAM's Password Hashing Algorithm - password-auth - Check if the required PAM module option is present in {{ pam_file_path }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+sufficient\s+pam_unix.so\s*.*\ssha512\b state: absent check_mode: true changed_when: false register: result_pam_module_sha512_option_present - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the "sha512" PAM option for "pam_unix.so" is included in {{ pam_file_path }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true regexp: ^(\s*password\s+sufficient\s+pam_unix.so.*) line: \1 sha512 state: present register: result_pam_sha512_add when: - result_pam_module_sha512_option_present.found == 0 - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present.stat.exists - "(result_pam_sha512_add is defined and result_pam_sha512_add.changed)\n or (result_pam_sha512_edit is defined and result_pam_sha512_edit.changed)" when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - set_password_hashing_algorithm_passwordauth | bool - '"pam" in ansible_facts.packages' - result_pam_file_present.stat.exists tags: - CCE-85946-2 - CJIS-5.6.2.2 - NIST-800-171-3.13.11 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(c) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.1 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - set_password_hashing_algorithm_passwordauth - name: Gather the package facts package_facts: manager: auto tags: - CCE-83581-9 - CJIS-5.6.2.2 - NIST-800-171-3.13.11 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(c) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.1 - PCI-DSSv4-8.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - set_password_hashing_algorithm_systemauth when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - set_password_hashing_algorithm_systemauth | bool - name: Set PAM's Password Hashing Algorithm - Check if /etc/pam.d/system-auth file is present ansible.builtin.stat: path: /etc/pam.d/system-auth register: result_pam_file_present when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - set_password_hashing_algorithm_systemauth | bool - '"pam" in ansible_facts.packages' tags: - CCE-83581-9 - CJIS-5.6.2.2 - NIST-800-171-3.13.11 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(c) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.1 - PCI-DSSv4-8.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - set_password_hashing_algorithm_systemauth - name: Set PAM's Password Hashing Algorithm - Check the proper remediation for the system block: - name: Set PAM's Password Hashing Algorithm - Define the PAM file to be edited as a local fact ansible.builtin.set_fact: pam_file_path: /etc/pam.d/system-auth - name: Set PAM's Password Hashing Algorithm - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: Set PAM's Password Hashing Algorithm - Ensure authselect custom profile is used if authselect is present block: - name: Set PAM's Password Hashing Algorithm - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Set PAM's Password Hashing Algorithm - Informative message based on the authselect integrity check result ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: Set PAM's Password Hashing Algorithm - Get authselect current profile ansible.builtin.shell: cmd: authselect current -r | awk '{ print $1 }' register: result_authselect_profile changed_when: false when: - result_authselect_check_cmd is success - name: Set PAM's Password Hashing Algorithm - Define the current authselect profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: '{{ result_authselect_profile.stdout }}' when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is match("custom/") - name: Set PAM's Password Hashing Algorithm - Define the new authselect custom profile as a local fact ansible.builtin.set_fact: authselect_current_profile: '{{ result_authselect_profile.stdout }}' authselect_custom_profile: custom/hardening when: - result_authselect_profile is not skipped - result_authselect_profile.stdout is not match("custom/") - name: Set PAM's Password Hashing Algorithm - Get authselect current features to also enable them in the custom profile ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - name: Set PAM's Password Hashing Algorithm - Check if any custom profile with the same name was already created ansible.builtin.stat: path: /etc/authselect/{{ authselect_custom_profile }} register: result_authselect_custom_profile_present changed_when: false when: - authselect_current_profile is not match("custom/") - name: Set PAM's Password Hashing Algorithm - Create an authselect custom profile based on the current profile ansible.builtin.command: cmd: authselect create-profile hardening -b {{ authselect_current_profile }} when: - result_authselect_check_cmd is success - authselect_current_profile is not match("custom/") - not result_authselect_custom_profile_present.stat.exists - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=before-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Set PAM's Password Hashing Algorithm - Ensure the authselect custom profile is selected ansible.builtin.command: cmd: authselect select {{ authselect_custom_profile }} register: result_pam_authselect_select_profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - authselect_current_profile is not match("custom/") - authselect_custom_profile is not match(authselect_current_profile) - name: Set PAM's Password Hashing Algorithm - Restore the authselect features in the custom profile ansible.builtin.command: cmd: authselect enable-feature {{ item }} loop: '{{ result_authselect_features.stdout_lines }}' register: result_pam_authselect_restore_features when: - result_authselect_profile is not skipped - result_authselect_features is not skipped - result_pam_authselect_select_profile is not skipped - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b --backup=after-hardening-custom-profile when: - result_authselect_check_cmd is success - result_authselect_profile is not skipped - result_pam_authselect_restore_features is not skipped - name: Set PAM's Password Hashing Algorithm - Change the PAM file to be edited according to the custom authselect profile ansible.builtin.set_fact: pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path | basename }} when: - result_authselect_present.stat.exists - name: Set PAM's Password Hashing Algorithm - Check if expected PAM module line is present in {{ pam_file_path }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+sufficient\s+pam_unix.so\s*.* state: absent check_mode: true changed_when: false register: result_pam_line_present - name: Set PAM's Password Hashing Algorithm - Include or update the PAM module line in {{ pam_file_path }} block: - name: Set PAM's Password Hashing Algorithm - Check if required PAM module line is present in {{ pam_file_path }} with different control ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+.*\s+pam_unix.so\s* state: absent check_mode: true changed_when: false register: result_pam_line_other_control_present - name: Set PAM's Password Hashing Algorithm - Ensure the correct control for the required PAM module line in {{ pam_file_path }} ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: ^(\s*password\s+).*(\bpam_unix.so.*) replace: \1sufficient \2 register: result_pam_module_edit when: - result_pam_line_other_control_present.found == 1 - name: Set PAM's Password Hashing Algorithm - Ensure the required PAM module line is included in {{ pam_file_path }} ansible.builtin.lineinfile: dest: '{{ pam_file_path }}' line: password sufficient pam_unix.so register: result_pam_module_add when: - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found > 1 - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present is defined - result_authselect_present.stat.exists - "(result_pam_module_add is defined and result_pam_module_add.changed)\n or (result_pam_module_edit is defined and\ \ result_pam_module_edit.changed)" when: - result_pam_line_present.found is defined - result_pam_line_present.found == 0 - name: Set PAM's Password Hashing Algorithm - Check if the required PAM module option is present in {{ pam_file_path }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' regexp: ^\s*password\s+sufficient\s+pam_unix.so\s*.*\ssha512\b state: absent check_mode: true changed_when: false register: result_pam_module_sha512_option_present - name: Set PAM's Password Hashing Algorithm - Ensure the "sha512" PAM option for "pam_unix.so" is included in {{ pam_file_path }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true regexp: ^(\s*password\s+sufficient\s+pam_unix.so.*) line: \1 sha512 state: present register: result_pam_sha512_add when: - result_pam_module_sha512_option_present.found == 0 - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_present.stat.exists - "(result_pam_sha512_add is defined and result_pam_sha512_add.changed)\n or (result_pam_sha512_edit is defined and result_pam_sha512_edit.changed)" when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - set_password_hashing_algorithm_systemauth | bool - '"pam" in ansible_facts.packages' - result_pam_file_present.stat.exists tags: - CCE-83581-9 - CJIS-5.6.2.2 - NIST-800-171-3.13.11 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(c) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.1 - PCI-DSSv4-8.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - set_password_hashing_algorithm_systemauth - name: Gather the package facts package_facts: manager: auto tags: - CCE-83627-0 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.6 - NIST-800-53-AC-2(3) - NIST-800-53-CM-6(a) - NIST-800-53-IA-4(e) - PCI-DSS-Req-8.1.4 - PCI-DSSv4-8.2.6 - account_disable_post_pw_expiration - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - account_disable_post_pw_expiration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Set Account Expiration Following Inactivity lineinfile: create: true dest: /etc/default/useradd regexp: ^INACTIVE line: INACTIVE={{ var_account_disable_post_pw_expiration }} when: - account_disable_post_pw_expiration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"shadow-utils" in ansible_facts.packages' tags: - CCE-83627-0 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.6 - NIST-800-53-AC-2(3) - NIST-800-53-CM-6(a) - NIST-800-53-IA-4(e) - PCI-DSS-Req-8.1.4 - PCI-DSSv4-8.2.6 - account_disable_post_pw_expiration - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83606-4 - CJIS-5.6.2.1 - NIST-800-171-3.5.6 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.4 - PCI-DSSv4-8.3.10.1 - accounts_maximum_age_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_maximum_age_login_defs | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Set Password Maximum Age lineinfile: create: true dest: /etc/login.defs regexp: ^#?PASS_MAX_DAYS line: PASS_MAX_DAYS {{ var_accounts_maximum_age_login_defs }} when: - accounts_maximum_age_login_defs | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"shadow-utils" in ansible_facts.packages' tags: - CCE-83606-4 - CJIS-5.6.2.1 - NIST-800-171-3.5.6 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.4 - PCI-DSSv4-8.3.10.1 - accounts_maximum_age_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83610-6 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - PCI-DSSv4-8.3.9 - accounts_minimum_age_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_minimum_age_login_defs | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Set Password Minimum Age lineinfile: create: true dest: /etc/login.defs regexp: ^#?PASS_MIN_DAYS line: PASS_MIN_DAYS {{ var_accounts_minimum_age_login_defs }} when: - accounts_minimum_age_login_defs | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"shadow-utils" in ansible_facts.packages' tags: - CCE-83610-6 - CJIS-5.6.2.1.1 - NIST-800-171-3.5.8 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - PCI-DSSv4-8.3.9 - accounts_minimum_age_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Collect users with not correct maximum time period between password changes ansible.builtin.command: cmd: awk -F':' '(/^[^:]+:[^!*]/ && ($5 > {{ var_accounts_maximum_age_login_defs }} || $5 == "")) {print $1}' /etc/shadow register: user_names tags: - CCE-86031-2 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - accounts_password_set_max_life_existing - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_password_set_max_life_existing | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Change the maximum time period between password changes ansible.builtin.user: user: '{{ item }}' password_expire_max: '{{ var_accounts_maximum_age_login_defs }}' with_items: '{{ user_names.stdout_lines }}' when: - accounts_password_set_max_life_existing | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - user_names.stdout_lines | length > 0 tags: - CCE-86031-2 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - accounts_password_set_max_life_existing - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Collect users with not correct minimum time period between password changes command: 'awk -F'':'' ''(/^[^:]+:[^!*]/ && ($4 < {{ var_accounts_minimum_age_login_defs }} || $4 == "")) {print $1}'' /etc/shadow ' register: user_names tags: - CCE-89069-9 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - accounts_password_set_min_life_existing - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_password_set_min_life_existing | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Change the minimum time period between password changes command: 'chage -m {{ var_accounts_minimum_age_login_defs }} {{ item }} ' with_items: '{{ user_names.stdout_lines }}' when: - accounts_password_set_min_life_existing | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - user_names.stdout_lines | length > 0 tags: - CCE-89069-9 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - accounts_password_set_min_life_existing - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set Existing Passwords Warning Age - Collect Users With Incorrect Number of Days of Warning Before Password Expires ansible.builtin.command: cmd: awk -F':' '(($6 < {{ var_accounts_password_warn_age_login_defs }} || $6 == "") && $2 ~ /^\$/) {print $1}' /etc/shadow register: result_pass_warn_age_user_names changed_when: false tags: - CCE-86915-6 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - accounts_password_set_warn_age_existing - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - accounts_password_set_warn_age_existing | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Set Existing Passwords Warning Age - Ensure the Number of Days of Warning Before Password Expires ansible.builtin.command: cmd: chage --warndays {{ var_accounts_password_warn_age_login_defs }} {{ item }} with_items: '{{ result_pass_warn_age_user_names.stdout_lines }}' when: - accounts_password_set_warn_age_existing | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - result_pass_warn_age_user_names.stdout_lines | length > 0 tags: - CCE-86915-6 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - accounts_password_set_warn_age_existing - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-83609-8 - NIST-800-171-3.5.8 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.4 - PCI-DSSv4-8.3.9 - accounts_password_warn_age_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_password_warn_age_login_defs | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Set Password Warning Age lineinfile: dest: /etc/login.defs regexp: ^PASS_WARN_AGE *[0-9]* state: present line: PASS_WARN_AGE {{ var_accounts_password_warn_age_login_defs }} create: true when: - accounts_password_warn_age_login_defs | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"shadow-utils" in ansible_facts.packages' tags: - CCE-83609-8 - NIST-800-171-3.5.8 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - PCI-DSS-Req-8.2.4 - PCI-DSSv4-8.3.9 - accounts_password_warn_age_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Collect users with not correct INACTIVE parameter set ansible.builtin.command: cmd: awk -F':' '(($7 > {{ var_account_disable_post_pw_expiration }} || $7 == "") && $2 ~ /^\$/) {print $1}' /etc/shadow register: user_names changed_when: false tags: - CCE-86759-8 - NIST-800-171-3.5.6 - NIST-800-53-AC-2(3) - NIST-800-53-CM-6(a) - NIST-800-53-IA-4(e) - PCI-DSS-Req-8.1.4 - accounts_set_post_pw_existing - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_set_post_pw_existing | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Change the period of inactivity ansible.builtin.command: cmd: chage --inactive {{ var_account_disable_post_pw_expiration }} {{ item }} with_items: '{{ user_names.stdout_lines }}' when: - accounts_set_post_pw_existing | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - user_names.stdout_lines | length > 0 tags: - CCE-86759-8 - NIST-800-171-3.5.6 - NIST-800-53-AC-2(3) - NIST-800-53-CM-6(a) - NIST-800-53-IA-4(e) - PCI-DSS-Req-8.1.4 - accounts_set_post_pw_existing - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Prevent Login to Accounts With Empty Password - Check if system relies on authselect ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present when: - configure_strategy | bool - high_severity | bool - low_complexity | bool - medium_disruption | bool - no_empty_passwords | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83611-4 - CJIS-5.5.2 - NIST-800-171-3.1.1 - NIST-800-171-3.1.5 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(a) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.3 - PCI-DSSv4-8.3.6 - PCI-DSSv4-8.3.9 - configure_strategy - high_severity - low_complexity - medium_disruption - no_empty_passwords - no_reboot_needed - name: Prevent Login to Accounts With Empty Password - Remediate using authselect block: - name: Prevent Login to Accounts With Empty Password - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Prevent Login to Accounts With Empty Password - Informative message based on the authselect integrity check result ansible.builtin.assert: that: - result_authselect_check_cmd.rc == 0 fail_msg: - authselect integrity check failed. Remediation aborted! - This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact. - It is not recommended to manually edit the PAM files when authselect tool is available. - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. success_msg: - authselect integrity check passed - name: Prevent Login to Accounts With Empty Password - Get authselect current features ansible.builtin.shell: cmd: authselect current | tail -n+3 | awk '{ print $2 }' register: result_authselect_features changed_when: false when: - result_authselect_check_cmd is success - name: Prevent Login to Accounts With Empty Password - Ensure "without-nullok" feature is enabled using authselect tool ansible.builtin.command: cmd: authselect enable-feature without-nullok register: result_authselect_enable_feature_cmd when: - result_authselect_check_cmd is success - result_authselect_features.stdout is not search("without-nullok") - name: Prevent Login to Accounts With Empty Password - Ensure authselect changes are applied ansible.builtin.command: cmd: authselect apply-changes -b when: - result_authselect_enable_feature_cmd is not skipped - result_authselect_enable_feature_cmd is success when: - configure_strategy | bool - high_severity | bool - low_complexity | bool - medium_disruption | bool - no_empty_passwords | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - result_authselect_present.stat.exists tags: - CCE-83611-4 - CJIS-5.5.2 - NIST-800-171-3.1.1 - NIST-800-171-3.1.5 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(a) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.3 - PCI-DSSv4-8.3.6 - PCI-DSSv4-8.3.9 - configure_strategy - high_severity - low_complexity - medium_disruption - no_empty_passwords - no_reboot_needed - name: Prevent Login to Accounts With Empty Password - Remediate directly editing PAM files ansible.builtin.replace: dest: '{{ item }}' regexp: nullok loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - configure_strategy | bool - high_severity | bool - low_complexity | bool - medium_disruption | bool - no_empty_passwords | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - not result_authselect_present.stat.exists tags: - CCE-83611-4 - CJIS-5.5.2 - NIST-800-171-3.1.1 - NIST-800-171-3.1.5 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(a) - NIST-800-53-IA-5(c) - PCI-DSS-Req-8.2.3 - PCI-DSSv4-8.3.6 - PCI-DSSv4-8.3.9 - configure_strategy - high_severity - low_complexity - medium_disruption - no_empty_passwords - no_reboot_needed - name: Collect users with no password command: 'awk -F: ''!$2 {print $1}'' /etc/shadow ' register: users_nopasswd when: - high_severity | bool - low_complexity | bool - low_disruption | bool - no_empty_passwords_etc_shadow | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-85972-8 - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - high_severity - low_complexity - low_disruption - no_empty_passwords_etc_shadow - no_reboot_needed - restrict_strategy - name: Lock users with no password command: 'passwd -l {{ item }} ' with_items: '{{ users_nopasswd.stdout_lines }}' when: - high_severity | bool - low_complexity | bool - low_disruption | bool - no_empty_passwords_etc_shadow | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - users_nopasswd.stdout_lines | length > 0 tags: - CCE-85972-8 - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - high_severity - low_complexity - low_disruption - no_empty_passwords_etc_shadow - no_reboot_needed - restrict_strategy - name: Get all /etc/passwd file entries getent: database: passwd split: ':' tags: - CCE-83624-7 - NIST-800-171-3.1.1 - NIST-800-171-3.1.5 - NIST-800-53-AC-6(5) - NIST-800-53-IA-2 - NIST-800-53-IA-4(b) - PCI-DSS-Req-8.5 - PCI-DSSv4-8.2.2 - PCI-DSSv4-8.2.3 - accounts_no_uid_except_zero - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy when: - accounts_no_uid_except_zero | bool - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Lock the password of the user accounts other than root with uid 0 command: passwd -l {{ item.key }} loop: '{{ getent_passwd | dict2items | rejectattr(''key'', ''search'', ''root'') | list }}' when: - accounts_no_uid_except_zero | bool - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - restrict_strategy | bool - item.value.1 == '0' tags: - CCE-83624-7 - NIST-800-171-3.1.1 - NIST-800-171-3.1.5 - NIST-800-53-AC-6(5) - NIST-800-53-IA-2 - NIST-800-53-IA-4(b) - PCI-DSS-Req-8.5 - PCI-DSSv4-8.2.2 - PCI-DSSv4-8.2.3 - accounts_no_uid_except_zero - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy - name: Ensure that System Accounts Are Locked - Get All Local Users From /etc/passwd ansible.builtin.getent: database: passwd split: ':' tags: - CCE-86113-8 - NIST-800-53-AC-6 - NIST-800-53-CM-6(a) - low_complexity - medium_disruption - medium_severity - no_password_auth_for_systemaccounts - no_reboot_needed - restrict_strategy when: - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_password_auth_for_systemaccounts | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Ensure that System Accounts Are Locked - Create local_users Variable From getent_passwd Facts ansible.builtin.set_fact: local_users: '{{ ansible_facts.getent_passwd | dict2items }}' tags: - CCE-86113-8 - NIST-800-53-AC-6 - NIST-800-53-CM-6(a) - low_complexity - medium_disruption - medium_severity - no_password_auth_for_systemaccounts - no_reboot_needed - restrict_strategy when: - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_password_auth_for_systemaccounts | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Ensure that System Accounts Are Locked - Lock System Accounts ansible.builtin.user: name: '{{ item.key }}' password_lock: true loop: '{{ local_users }}' when: - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_password_auth_for_systemaccounts | bool - no_reboot_needed | bool - restrict_strategy | bool - item.value[1]|int < 1000 - item.key not in ['root', 'halt', 'sync', 'shutdown', 'nfsnobody'] tags: - CCE-86113-8 - NIST-800-53-AC-6 - NIST-800-53-CM-6(a) - low_complexity - medium_disruption - medium_severity - no_password_auth_for_systemaccounts - no_reboot_needed - restrict_strategy - name: Ensure that System Accounts Do Not Run a Shell Upon Login - Get All Local Users From /etc/passwd ansible.builtin.getent: database: passwd split: ':' tags: - CCE-83623-9 - NIST-800-53-AC-6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - PCI-DSSv4-8.6.1 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - no_shelllogin_for_systemaccounts - restrict_strategy when: - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - no_shelllogin_for_systemaccounts | bool - restrict_strategy | bool - name: Ensure that System Accounts Do Not Run a Shell Upon Login - Create local_users Variable From getent_passwd Facts ansible.builtin.set_fact: local_users: '{{ ansible_facts.getent_passwd | dict2items }}' tags: - CCE-83623-9 - NIST-800-53-AC-6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - PCI-DSSv4-8.6.1 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - no_shelllogin_for_systemaccounts - restrict_strategy when: - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - no_shelllogin_for_systemaccounts | bool - restrict_strategy | bool - name: Ensure that System Accounts Do Not Run a Shell Upon Login - Disable Login Shell for System Accounts ansible.builtin.user: name: '{{ item.key }}' shell: /sbin/nologin loop: '{{ local_users }}' when: - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - no_shelllogin_for_systemaccounts | bool - restrict_strategy | bool - item.key not in ['root'] - item.value[1]|int < 1000 - item.value[5] not in ['/sbin/shutdown', '/sbin/halt', '/bin/sync'] tags: - CCE-83623-9 - NIST-800-53-AC-6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - PCI-DSSv4-8.6.1 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - no_shelllogin_for_systemaccounts - restrict_strategy - name: Correct any occurrence of TMOUT in /etc/profile replace: path: /etc/profile regexp: ^[^#].*TMOUT=.* replace: declare -xr TMOUT={{ var_accounts_tmout }} register: profile_replaced when: - accounts_tmout | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83633-8 - NIST-800-171-3.1.11 - NIST-800-53-AC-12 - NIST-800-53-AC-2(5) - NIST-800-53-CM-6(a) - NIST-800-53-SC-10 - PCI-DSSv4-8.6.1 - accounts_tmout - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set Interactive Session Timeout lineinfile: path: /etc/profile.d/tmout.sh create: true regexp: TMOUT= line: declare -xr TMOUT={{ var_accounts_tmout }} state: present when: - accounts_tmout | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83633-8 - NIST-800-171-3.1.11 - NIST-800-53-AC-12 - NIST-800-53-AC-2(5) - NIST-800-53-CM-6(a) - NIST-800-53-SC-10 - PCI-DSSv4-8.6.1 - accounts_tmout - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Get all local users from /etc/passwd ansible.builtin.getent: database: passwd split: ':' tags: - CCE-83639-5 - accounts_user_interactive_home_directory_exists - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_user_interactive_home_directory_exists | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Create local_users variable from the getent output ansible.builtin.set_fact: local_users: '{{ ansible_facts.getent_passwd|dict2items }}' tags: - CCE-83639-5 - accounts_user_interactive_home_directory_exists - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_user_interactive_home_directory_exists | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Ensure interactive users have a home directory exists ansible.builtin.user: name: '{{ item.key }}' create_home: true loop: '{{ local_users }}' when: - accounts_user_interactive_home_directory_exists | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - item.value[2]|int >= 1000 - item.value[2]|int != 65534 tags: - CCE-83639-5 - accounts_user_interactive_home_directory_exists - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Get all local users from /etc/passwd ansible.builtin.getent: database: passwd split: ':' tags: - CCE-83629-6 - file_groupownership_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - file_groupownership_home_directories | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Create local_users variable from the getent output ansible.builtin.set_fact: local_users: '{{ ansible_facts.getent_passwd|dict2items }}' tags: - CCE-83629-6 - file_groupownership_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - file_groupownership_home_directories | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Test for existence of home directories to avoid creating them, but only fixing group ownership ansible.builtin.stat: path: '{{ item.value[4] }}' register: path_exists loop: '{{ local_users }}' when: - file_groupownership_home_directories | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - item.value[1]|int >= 1000 - item.value[1]|int != 65534 tags: - CCE-83629-6 - file_groupownership_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure interactive local users are the group-owners of their respective home directories ansible.builtin.file: path: '{{ item.0.value[4] }}' group: '{{ item.0.value[2] }}' loop: '{{ local_users|zip(path_exists.results)|list }}' when: - file_groupownership_home_directories | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - item.1.stat is defined and item.1.stat.exists tags: - CCE-83629-6 - file_groupownership_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Get all local users from /etc/passwd ansible.builtin.getent: database: passwd split: ':' tags: - CCE-83634-6 - file_permissions_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - file_permissions_home_directories | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Create local_users variable from the getent output ansible.builtin.set_fact: local_users: '{{ ansible_facts.getent_passwd|dict2items }}' tags: - CCE-83634-6 - file_permissions_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - file_permissions_home_directories | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Test for existence home directories to avoid creating them. ansible.builtin.stat: path: '{{ item.value[4] }}' register: path_exists loop: '{{ local_users }}' when: - file_permissions_home_directories | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - item.value[1]|int >= 1000 - item.value[1]|int != 65534 tags: - CCE-83634-6 - file_permissions_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure interactive local users have proper permissions on their respective home directories ansible.builtin.file: path: '{{ item.0.value[4] }}' mode: u-s,g-w-s,o=- follow: false recurse: false loop: '{{ local_users|zip(path_exists.results)|list }}' when: - file_permissions_home_directories | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - item.1.stat is defined and item.1.stat.exists tags: - CCE-83634-6 - file_permissions_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Get root paths which are not symbolic links stat: path: '{{ item }}' changed_when: false failed_when: false register: root_paths with_items: '{{ ansible_env.PATH.split('':'') }}' tags: - CCE-83643-7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(a) - accounts_root_path_dirs_no_write - low_complexity - medium_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_root_path_dirs_no_write | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Disable writability to root directories file: path: '{{ item.item }}' mode: g-w,o-w with_items: '{{ root_paths.results }}' when: - accounts_root_path_dirs_no_write | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - root_paths.results is defined - item.stat.exists - not item.stat.islnk tags: - CCE-83643-7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(a) - accounts_root_path_dirs_no_write - low_complexity - medium_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if umask in /etc/bashrc is already set ansible.builtin.lineinfile: path: /etc/bashrc regexp: ^(\s*)umask\s+.* state: absent check_mode: true changed_when: false register: umask_replace tags: - CCE-83644-5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-8.6.1 - accounts_umask_etc_bashrc - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_umask_etc_bashrc | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Replace user umask in /etc/bashrc ansible.builtin.replace: path: /etc/bashrc regexp: ^(\s*)umask(\s+).* replace: \g<1>umask\g<2>{{ var_accounts_user_umask }} when: - accounts_umask_etc_bashrc | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - umask_replace.found > 0 tags: - CCE-83644-5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-8.6.1 - accounts_umask_etc_bashrc - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure the Default umask is Appended Correctly ansible.builtin.lineinfile: create: true path: /etc/bashrc line: umask {{ var_accounts_user_umask }} when: - accounts_umask_etc_bashrc | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - umask_replace.found == 0 tags: - CCE-83644-5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-8.6.1 - accounts_umask_etc_bashrc - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83647-8 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-8.6.1 - accounts_umask_etc_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_umask_etc_login_defs | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Check if UMASK is already set ansible.builtin.lineinfile: path: /etc/login.defs regexp: ^(\s*)UMASK\s+.* state: absent check_mode: true changed_when: false register: result_umask_is_set when: - accounts_umask_etc_login_defs | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"shadow-utils" in ansible_facts.packages' tags: - CCE-83647-8 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-8.6.1 - accounts_umask_etc_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Replace user UMASK in /etc/login.defs ansible.builtin.replace: path: /etc/login.defs regexp: ^(\s*)UMASK(\s+).* replace: \g<1>UMASK\g<2>{{ var_accounts_user_umask }} when: - accounts_umask_etc_login_defs | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"shadow-utils" in ansible_facts.packages' - result_umask_is_set.found > 0 tags: - CCE-83647-8 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-8.6.1 - accounts_umask_etc_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure the Default UMASK is Appended Correctly ansible.builtin.lineinfile: create: true path: /etc/login.defs line: UMASK {{ var_accounts_user_umask }} when: - accounts_umask_etc_login_defs | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"shadow-utils" in ansible_facts.packages' - result_umask_is_set.found == 0 tags: - CCE-83647-8 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-8.6.1 - accounts_umask_etc_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure the Default Umask is Set Correctly in /etc/profile - Locate Profile Configuration Files Where umask Is Defined ansible.builtin.find: paths: - /etc/profile.d patterns: - sh.local - '*.sh' contains: ^[\s]*umask\s+\d+ register: result_profile_d_files tags: - CCE-90828-5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-8.6.1 - accounts_umask_etc_profile - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_umask_etc_profile | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Ensure the Default Umask is Set Correctly in /etc/profile - Replace Existing umask Value in Files From /etc/profile.d ansible.builtin.replace: path: '{{ item.path }}' regexp: ^(\s*)umask\s+\d+ replace: \1umask {{ var_accounts_user_umask }} loop: '{{ result_profile_d_files.files }}' register: result_umask_replaced_profile_d when: - accounts_umask_etc_profile | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - result_profile_d_files.matched tags: - CCE-90828-5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-8.6.1 - accounts_umask_etc_profile - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure the Default Umask is Set Correctly in /etc/profile - Ensure umask Is Set in /etc/profile if Not Already Set Elsewhere ansible.builtin.lineinfile: create: true mode: 420 path: /etc/profile line: umask {{ var_accounts_user_umask }} when: - accounts_umask_etc_profile | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - not result_profile_d_files.matched tags: - CCE-90828-5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-8.6.1 - accounts_umask_etc_profile - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure the Default Umask is Set Correctly in /etc/profile - Ensure umask Value For All Existing umask Definition in /etc/profile ansible.builtin.replace: path: /etc/profile regexp: ^(\s*)umask\s+\d+ replace: \1umask {{ var_accounts_user_umask }} register: result_umask_replaced_profile tags: - CCE-90828-5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-8.6.1 - accounts_umask_etc_profile - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - accounts_umask_etc_profile | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Ensure audit is installed package: name: audit state: present when: - enable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - package_audit_installed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83649-4 - NIST-800-53-AC-7(a) - NIST-800-53-AU-12(2) - NIST-800-53-AU-14 - NIST-800-53-AU-2(a) - NIST-800-53-AU-7(1) - NIST-800-53-AU-7(2) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.1 - PCI-DSSv4-10.2.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_audit_installed - name: Gather the package facts package_facts: manager: auto tags: - CCE-90829-3 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-171-3.3.2 - NIST-800-171-3.3.6 - NIST-800-53-AC-2(g) - NIST-800-53-AC-6(9) - NIST-800-53-AU-10 - NIST-800-53-AU-12(c) - NIST-800-53-AU-14(1) - NIST-800-53-AU-2(d) - NIST-800-53-AU-3 - NIST-800-53-CM-6(a) - NIST-800-53-SI-4(23) - PCI-DSS-Req-10.1 - PCI-DSSv4-10.2.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_auditd_enabled when: - enable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - service_auditd_enabled | bool - name: Enable service auditd block: - name: Gather the package facts package_facts: manager: auto - name: Enable service auditd systemd: name: auditd enabled: 'yes' state: started masked: 'no' when: - '"audit" in ansible_facts.packages' when: - enable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - service_auditd_enabled | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"audit" in ansible_facts.packages' tags: - CCE-90829-3 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-171-3.3.2 - NIST-800-171-3.3.6 - NIST-800-53-AC-2(g) - NIST-800-53-AC-6(9) - NIST-800-53-AU-10 - NIST-800-53-AU-12(c) - NIST-800-53-AU-14(1) - NIST-800-53-AU-2(d) - NIST-800-53-AU-3 - NIST-800-53-CM-6(a) - NIST-800-53-SI-4(23) - PCI-DSS-Req-10.1 - PCI-DSSv4-10.2.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_auditd_enabled - name: Gather the package facts package_facts: manager: auto tags: - CCE-83651-0 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AC-17(1) - NIST-800-53-AU-10 - NIST-800-53-AU-14(1) - NIST-800-53-CM-6(a) - NIST-800-53-IR-5(1) - PCI-DSS-Req-10.3 - PCI-DSSv4-10.7 - grub2_audit_argument - low_disruption - low_severity - medium_complexity - reboot_required - restrict_strategy when: - grub2_audit_argument | bool - low_disruption | bool - low_severity | bool - medium_complexity | bool - reboot_required | bool - restrict_strategy | bool - name: Update grub defaults and the bootloader menu command: /sbin/grubby --update-kernel=ALL --args="audit=1" when: - grub2_audit_argument | bool - low_disruption | bool - low_severity | bool - medium_complexity | bool - reboot_required | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"grub2-common" in ansible_facts.packages' tags: - CCE-83651-0 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AC-17(1) - NIST-800-53-AU-10 - NIST-800-53-AU-14(1) - NIST-800-53-CM-6(a) - NIST-800-53-IR-5(1) - PCI-DSS-Req-10.3 - PCI-DSSv4-10.7 - grub2_audit_argument - low_disruption - low_severity - medium_complexity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83652-8 - NIST-800-53-CM-6(a) - grub2_audit_backlog_limit_argument - low_disruption - low_severity - medium_complexity - reboot_required - restrict_strategy when: - grub2_audit_backlog_limit_argument | bool - low_disruption | bool - low_severity | bool - medium_complexity | bool - reboot_required | bool - restrict_strategy | bool - name: Update grub defaults and the bootloader menu command: /sbin/grubby --update-kernel=ALL --args="audit_backlog_limit=8192" when: - grub2_audit_backlog_limit_argument | bool - low_disruption | bool - low_severity | bool - medium_complexity | bool - reboot_required | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"grub2-common" in ansible_facts.packages' tags: - CCE-83652-8 - NIST-800-53-CM-6(a) - grub2_audit_backlog_limit_argument - low_disruption - low_severity - medium_complexity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83716-1 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-171-3.4.3 - NIST-800-53-AC-6(9) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.2 - audit_rules_immutable - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_immutable | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Collect all files from /etc/audit/rules.d with .rules extension find: paths: /etc/audit/rules.d/ patterns: '*.rules' register: find_rules_d when: - audit_rules_immutable | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83716-1 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-171-3.4.3 - NIST-800-53-AC-6(9) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.2 - audit_rules_immutable - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Remove the -e option from all Audit config files lineinfile: path: '{{ item }}' regexp: ^\s*(?:-e)\s+.*$ state: absent loop: '{{ find_rules_d.files | map(attribute=''path'') | list + [''/etc/audit/audit.rules''] }}' when: - audit_rules_immutable | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83716-1 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-171-3.4.3 - NIST-800-53-AC-6(9) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.2 - audit_rules_immutable - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add Audit -e option into /etc/audit/rules.d/immutable.rules and /etc/audit/audit.rules lineinfile: path: '{{ item }}' create: true line: -e 2 mode: o-rwx loop: - /etc/audit/audit.rules - /etc/audit/rules.d/immutable.rules when: - audit_rules_immutable | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83716-1 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-171-3.4.3 - NIST-800-53-AC-6(9) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.2 - audit_rules_immutable - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83721-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_mac_modification - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_mac_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Check if watch rule for /etc/selinux/ already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/selinux/\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_mac_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83721-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_mac_modification - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key MAC-policy find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)MAC-policy$ patterns: '*.rules' register: find_watch_key when: - audit_rules_mac_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83721-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_mac_modification - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/MAC-policy.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/MAC-policy.rules when: - audit_rules_mac_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83721-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_mac_modification - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_mac_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83721-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_mac_modification - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /etc/selinux/ in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/selinux/ -p wa -k MAC-policy create: true mode: '0640' when: - audit_rules_mac_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83721-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_mac_modification - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /etc/selinux/ already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/selinux/\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_mac_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83721-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_mac_modification - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /etc/selinux/ in /etc/audit/audit.rules lineinfile: line: -w /etc/selinux/ -p wa -k MAC-policy state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_mac_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83721-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_mac_modification - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-86343-1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - audit_rules_mac_modification_usr_share - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_mac_modification_usr_share | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Check if watch rule for /usr/share/selinux/ already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/usr/share/selinux/\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_mac_modification_usr_share | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86343-1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - audit_rules_mac_modification_usr_share - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key MAC-policy find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)MAC-policy$ patterns: '*.rules' register: find_watch_key when: - audit_rules_mac_modification_usr_share | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-86343-1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - audit_rules_mac_modification_usr_share - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/MAC-policy.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/MAC-policy.rules when: - audit_rules_mac_modification_usr_share | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-86343-1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - audit_rules_mac_modification_usr_share - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_mac_modification_usr_share | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-86343-1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - audit_rules_mac_modification_usr_share - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /usr/share/selinux/ in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /usr/share/selinux/ -p wa -k MAC-policy create: true mode: '0640' when: - audit_rules_mac_modification_usr_share | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-86343-1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - audit_rules_mac_modification_usr_share - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /usr/share/selinux/ already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/usr/share/selinux/\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_mac_modification_usr_share | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86343-1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - audit_rules_mac_modification_usr_share - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /usr/share/selinux/ in /etc/audit/audit.rules lineinfile: line: -w /usr/share/selinux/ -p wa -k MAC-policy state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_mac_modification_usr_share | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-86343-1 - NIST-800-171-3.1.8 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - audit_rules_mac_modification_usr_share - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83735-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_media_export - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_media_export | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit mount tasks set_fact: audit_arch: b64 when: - audit_rules_media_export | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83735-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_media_export - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for mount for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - mount syscall_grouping: [] - name: Check existence of mount in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - mount syscall_grouping: [] - name: Check existence of mount in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_media_export | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83735-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_media_export - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for mount for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - mount syscall_grouping: [] - name: Check existence of mount in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - mount syscall_grouping: [] - name: Check existence of mount in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_media_export | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83735-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_media_export - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Set architecture for audit tasks set_fact: audit_arch: b64 when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Remediate audit rules for network configuration for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - sethostname - setdomainname syscall_grouping: - sethostname - setdomainname - name: Check existence of sethostname, setdomainname in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/audit_rules_networkconfig_modification.rules set_fact: audit_file="/etc/audit/rules.d/audit_rules_networkconfig_modification.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_rules_networkconfig_modification create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - sethostname - setdomainname syscall_grouping: - sethostname - setdomainname - name: Check existence of sethostname, setdomainname in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_rules_networkconfig_modification create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Remediate audit rules for network configuration for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - sethostname - setdomainname syscall_grouping: - sethostname - setdomainname - name: Check existence of sethostname, setdomainname in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/audit_rules_networkconfig_modification.rules set_fact: audit_file="/etc/audit/rules.d/audit_rules_networkconfig_modification.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=audit_rules_networkconfig_modification create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - sethostname - setdomainname syscall_grouping: - sethostname - setdomainname - name: Check existence of sethostname, setdomainname in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=audit_rules_networkconfig_modification create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/issue already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/issue\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_networkconfig_modification find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)audit_rules_networkconfig_modification$ patterns: '*.rules' register: find_watch_key when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use /etc/audit/rules.d/audit_rules_networkconfig_modification.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/audit_rules_networkconfig_modification.rules when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/issue in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/issue -p wa -k audit_rules_networkconfig_modification create: true mode: '0640' when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/issue already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/issue\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/issue in /etc/audit/audit.rules lineinfile: line: -w /etc/issue -p wa -k audit_rules_networkconfig_modification state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/issue.net already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/issue.net\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_networkconfig_modification find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)audit_rules_networkconfig_modification$ patterns: '*.rules' register: find_watch_key when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use /etc/audit/rules.d/audit_rules_networkconfig_modification.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/audit_rules_networkconfig_modification.rules when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/issue.net in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/issue.net -p wa -k audit_rules_networkconfig_modification create: true mode: '0640' when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/issue.net already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/issue.net\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/issue.net in /etc/audit/audit.rules lineinfile: line: -w /etc/issue.net -p wa -k audit_rules_networkconfig_modification state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/hosts already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/hosts\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_networkconfig_modification find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)audit_rules_networkconfig_modification$ patterns: '*.rules' register: find_watch_key when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use /etc/audit/rules.d/audit_rules_networkconfig_modification.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/audit_rules_networkconfig_modification.rules when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/hosts in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/hosts -p wa -k audit_rules_networkconfig_modification create: true mode: '0640' when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/hosts already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/hosts\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/hosts in /etc/audit/audit.rules lineinfile: line: -w /etc/hosts -p wa -k audit_rules_networkconfig_modification state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/sysconfig/network already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/sysconfig/network\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_networkconfig_modification find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)audit_rules_networkconfig_modification$ patterns: '*.rules' register: find_watch_key when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use /etc/audit/rules.d/audit_rules_networkconfig_modification.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/audit_rules_networkconfig_modification.rules when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/sysconfig/network in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/sysconfig/network -p wa -k audit_rules_networkconfig_modification create: true mode: '0640' when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/sysconfig/network already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/sysconfig/network\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/sysconfig/network in /etc/audit/audit.rules lineinfile: line: -w /etc/sysconfig/network -p wa -k audit_rules_networkconfig_modification state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_networkconfig_modification | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83706-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Check if watch rule for /var/run/utmp already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/var/run/utmp\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key session find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)session$ patterns: '*.rules' register: find_watch_key when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/session.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/session.rules when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /var/run/utmp in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /var/run/utmp -p wa -k session create: true mode: '0640' when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /var/run/utmp already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/var/run/utmp\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /var/run/utmp in /etc/audit/audit.rules lineinfile: line: -w /var/run/utmp -p wa -k session state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /var/log/btmp already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/var/log/btmp\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key session find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)session$ patterns: '*.rules' register: find_watch_key when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/session.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/session.rules when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /var/log/btmp in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /var/log/btmp -p wa -k session create: true mode: '0640' when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /var/log/btmp already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/var/log/btmp\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /var/log/btmp in /etc/audit/audit.rules lineinfile: line: -w /var/log/btmp -p wa -k session state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /var/log/wtmp already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/var/log/wtmp\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key session find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)session$ patterns: '*.rules' register: find_watch_key when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/session.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/session.rules when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /var/log/wtmp in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /var/log/wtmp -p wa -k session create: true mode: '0640' when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /var/log/wtmp already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/var/log/wtmp\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /var/log/wtmp in /etc/audit/audit.rules lineinfile: line: -w /var/log/wtmp -p wa -k session state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_session_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83713-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_session_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-86368-8 - audit_rules_suid_auid_privilege_function - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_suid_auid_privilege_function | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Service facts ansible.builtin.service_facts: null when: - audit_rules_suid_auid_privilege_function | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86368-8 - audit_rules_suid_auid_privilege_function - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check the rules script being used ansible.builtin.command: grep '^ExecStartPost' /usr/lib/systemd/system/auditd.service register: check_rules_scripts_result changed_when: false failed_when: false when: - audit_rules_suid_auid_privilege_function | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86368-8 - audit_rules_suid_auid_privilege_function - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set suid_audit_rules fact ansible.builtin.set_fact: suid_audit_rules: - rule: -a always,exit -F arch=b32 -S execve -C euid!=uid -F auid!=unset -k user_emulation regex: ^[\s]*-a[\s]+always,exit[\s]+-F[\s]+arch=b32[\s]+-C[\s]+euid!=uid[\s]+-F[\s]+auid!=unset[\s]+-S[\s]+execve[\s]+(?:-k[\s]+|-F[\s]+key=)[\S]+[\s]*$ - rule: -a always,exit -F arch=b64 -S execve -C euid!=uid -F auid!=unset -k user_emulation regex: ^[\s]*-a[\s]+always,exit[\s]+-F[\s]+arch=b64[\s]+-C[\s]+euid!=uid[\s]+-F[\s]+auid!=unset[\s]+-S[\s]+execve[\s]+(?:-k[\s]+|-F[\s]+key=)[\S]+[\s]*$ when: - audit_rules_suid_auid_privilege_function | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86368-8 - audit_rules_suid_auid_privilege_function - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Update /etc/audit/rules.d/user_emulation.rules to audit privileged functions ansible.builtin.lineinfile: path: /etc/audit/rules.d/user_emulation.rules line: '{{ item.rule }}' regexp: '{{ item.regex }}' create: true when: - audit_rules_suid_auid_privilege_function | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"auditd.service" in ansible_facts.services' - '"augenrules" in check_rules_scripts_result.stdout' register: augenrules_audit_rules_privilege_function_update_result with_items: '{{ suid_audit_rules }}' tags: - CCE-86368-8 - audit_rules_suid_auid_privilege_function - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Update Update /etc/audit/audit.rules to audit privileged functions ansible.builtin.lineinfile: path: /etc/audit/audit.rules line: '{{ item.rule }}' regexp: '{{ item.regex }}' create: true when: - audit_rules_suid_auid_privilege_function | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"auditd.service" in ansible_facts.services' - '"auditctl" in check_rules_scripts_result.stdout' register: auditctl_audit_rules_privilege_function_update_result with_items: '{{ suid_audit_rules }}' tags: - CCE-86368-8 - audit_rules_suid_auid_privilege_function - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Restart Auditd ansible.builtin.command: /usr/sbin/service auditd restart when: - audit_rules_suid_auid_privilege_function | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - (augenrules_audit_rules_privilege_function_update_result.changed or auditctl_audit_rules_privilege_function_update_result.changed) - ansible_facts.services["auditd.service"].state == "running" tags: - CCE-86368-8 - audit_rules_suid_auid_privilege_function - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Check if watch rule for /etc/sudoers already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/sudoers\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key actions find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)actions$ patterns: '*.rules' register: find_watch_key when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use /etc/audit/rules.d/actions.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/actions.rules when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/sudoers in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/sudoers -p wa -k actions create: true mode: '0640' when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/sudoers already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/sudoers\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/sudoers in /etc/audit/audit.rules lineinfile: line: -w /etc/sudoers -p wa -k actions state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/sudoers.d/ already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/sudoers.d/\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key actions find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)actions$ patterns: '*.rules' register: find_watch_key when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use /etc/audit/rules.d/actions.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/actions.rules when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/sudoers.d/ in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/sudoers.d/ -p wa -k actions create: true mode: '0640' when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/sudoers.d/ already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/sudoers.d/\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/sudoers.d/ in /etc/audit/audit.rules lineinfile: line: -w /etc/sudoers.d/ -p wa -k actions state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_sysadmin_actions | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83729-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(7)(b) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2.1.5 - PCI-DSSv4-10.2.2 - audit_rules_sysadmin_actions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83722-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_group - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_usergroup_modification_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Check if watch rule for /etc/group already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/group\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_usergroup_modification_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83722-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_group - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$ patterns: '*.rules' register: find_watch_key when: - audit_rules_usergroup_modification_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83722-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_group - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/audit_rules_usergroup_modification.rules when: - audit_rules_usergroup_modification_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83722-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_group - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_usergroup_modification_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83722-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_group - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /etc/group in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/group -p wa -k audit_rules_usergroup_modification create: true mode: '0640' when: - audit_rules_usergroup_modification_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83722-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_group - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /etc/group already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/group\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_usergroup_modification_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83722-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_group - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /etc/group in /etc/audit/audit.rules lineinfile: line: -w /etc/group -p wa -k audit_rules_usergroup_modification state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_usergroup_modification_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83722-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_group - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83723-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_gshadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_usergroup_modification_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Check if watch rule for /etc/gshadow already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/gshadow\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_usergroup_modification_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83723-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_gshadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$ patterns: '*.rules' register: find_watch_key when: - audit_rules_usergroup_modification_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83723-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_gshadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/audit_rules_usergroup_modification.rules when: - audit_rules_usergroup_modification_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83723-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_gshadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_usergroup_modification_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83723-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_gshadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /etc/gshadow in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/gshadow -p wa -k audit_rules_usergroup_modification create: true mode: '0640' when: - audit_rules_usergroup_modification_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83723-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_gshadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /etc/gshadow already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/gshadow\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_usergroup_modification_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83723-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_gshadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /etc/gshadow in /etc/audit/audit.rules lineinfile: line: -w /etc/gshadow -p wa -k audit_rules_usergroup_modification state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_usergroup_modification_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83723-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_gshadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83712-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_opasswd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_usergroup_modification_opasswd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Check if watch rule for /etc/security/opasswd already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/security/opasswd\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_usergroup_modification_opasswd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83712-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_opasswd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$ patterns: '*.rules' register: find_watch_key when: - audit_rules_usergroup_modification_opasswd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83712-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_opasswd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/audit_rules_usergroup_modification.rules when: - audit_rules_usergroup_modification_opasswd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83712-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_opasswd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_usergroup_modification_opasswd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83712-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_opasswd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /etc/security/opasswd in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/security/opasswd -p wa -k audit_rules_usergroup_modification create: true mode: '0640' when: - audit_rules_usergroup_modification_opasswd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83712-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_opasswd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /etc/security/opasswd already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/security/opasswd\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_usergroup_modification_opasswd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83712-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_opasswd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /etc/security/opasswd in /etc/audit/audit.rules lineinfile: line: -w /etc/security/opasswd -p wa -k audit_rules_usergroup_modification state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_usergroup_modification_opasswd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83712-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_opasswd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83714-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_passwd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_usergroup_modification_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Check if watch rule for /etc/passwd already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/passwd\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_usergroup_modification_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83714-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_passwd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$ patterns: '*.rules' register: find_watch_key when: - audit_rules_usergroup_modification_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83714-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_passwd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/audit_rules_usergroup_modification.rules when: - audit_rules_usergroup_modification_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83714-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_passwd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_usergroup_modification_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83714-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_passwd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /etc/passwd in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/passwd -p wa -k audit_rules_usergroup_modification create: true mode: '0640' when: - audit_rules_usergroup_modification_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83714-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_passwd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /etc/passwd already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/passwd\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_usergroup_modification_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83714-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_passwd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /etc/passwd in /etc/audit/audit.rules lineinfile: line: -w /etc/passwd -p wa -k audit_rules_usergroup_modification state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_usergroup_modification_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83714-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_passwd - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83725-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_shadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_usergroup_modification_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Check if watch rule for /etc/shadow already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/shadow\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_usergroup_modification_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83725-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_shadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$ patterns: '*.rules' register: find_watch_key when: - audit_rules_usergroup_modification_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83725-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_shadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/audit_rules_usergroup_modification.rules when: - audit_rules_usergroup_modification_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83725-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_shadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_usergroup_modification_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83725-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_shadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /etc/shadow in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/shadow -p wa -k audit_rules_usergroup_modification create: true mode: '0640' when: - audit_rules_usergroup_modification_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83725-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_shadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /etc/shadow already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/shadow\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_usergroup_modification_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83725-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_shadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /etc/shadow in /etc/audit/audit.rules lineinfile: line: -w /etc/shadow -p wa -k audit_rules_usergroup_modification state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_usergroup_modification_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83725-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - audit_rules_usergroup_modification_shadow - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-86433-0 - audit_sudo_log_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_sudo_log_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Check if watch rule for /var/log/sudo.log already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/var/log/sudo.log\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_sudo_log_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86433-0 - audit_sudo_log_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key logins find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)logins$ patterns: '*.rules' register: find_watch_key when: - audit_sudo_log_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-86433-0 - audit_sudo_log_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/logins.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/logins.rules when: - audit_sudo_log_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-86433-0 - audit_sudo_log_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_sudo_log_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-86433-0 - audit_sudo_log_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /var/log/sudo.log in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /var/log/sudo.log -p wa -k logins create: true mode: '0640' when: - audit_sudo_log_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-86433-0 - audit_sudo_log_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /var/log/sudo.log already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/var/log/sudo.log\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_sudo_log_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86433-0 - audit_sudo_log_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /var/log/sudo.log in /etc/audit/audit.rules lineinfile: line: -w /var/log/sudo.log -p wa -k logins state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_sudo_log_events | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-86433-0 - audit_sudo_log_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-86446-2 - configure_strategy - file_groupownership_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupownership_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Find /etc/audit/ file(s) matching ^audit(\.rules|d\.conf)$ command: find -H /etc/audit/ -maxdepth 1 -type f ! -group 0 -regex "^audit(\.rules|d\.conf)$" register: files_found changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_groupownership_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86446-2 - configure_strategy - file_groupownership_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner on /etc/audit/ file(s) matching ^audit(\.rules|d\.conf)$ file: path: '{{ item }}' group: '0' state: file with_items: - '{{ files_found.stdout_lines }}' when: - configure_strategy | bool - file_groupownership_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86446-2 - configure_strategy - file_groupownership_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/audit/rules.d/ file(s) matching ^.*\.rules$ command: find -H /etc/audit/rules.d/ -maxdepth 1 -type f ! -group 0 -regex "^.*\.rules$" register: files_found changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_groupownership_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86446-2 - configure_strategy - file_groupownership_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner on /etc/audit/rules.d/ file(s) matching ^.*\.rules$ file: path: '{{ item }}' group: '0' state: file with_items: - '{{ files_found.stdout_lines }}' when: - configure_strategy | bool - file_groupownership_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86446-2 - configure_strategy - file_groupownership_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-86445-4 - configure_strategy - file_ownership_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_ownership_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Find /etc/audit/ file(s) matching ^audit(\.rules|d\.conf)$ command: find -H /etc/audit/ -maxdepth 1 -type f ! -uid 0 -regex "^audit(\.rules|d\.conf)$" register: files_found changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_ownership_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86445-4 - configure_strategy - file_ownership_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner on /etc/audit/ file(s) matching ^audit(\.rules|d\.conf)$ file: path: '{{ item }}' owner: '0' state: file with_items: - '{{ files_found.stdout_lines }}' when: - configure_strategy | bool - file_ownership_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86445-4 - configure_strategy - file_ownership_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/audit/rules.d/ file(s) matching ^.*\.rules$ command: find -H /etc/audit/rules.d/ -maxdepth 1 -type f ! -uid 0 -regex "^.*\.rules$" register: files_found changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_ownership_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86445-4 - configure_strategy - file_ownership_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner on /etc/audit/rules.d/ file(s) matching ^.*\.rules$ file: path: '{{ item }}' owner: '0' state: file with_items: - '{{ files_found.stdout_lines }}' when: - configure_strategy | bool - file_ownership_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86445-4 - configure_strategy - file_ownership_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-88002-1 - configure_strategy - file_permissions_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Find /etc/audit/ file(s) command: find -H /etc/audit/ -maxdepth 1 -perm /u+xs,g+xws,o+xwrt -type f -regex ".*audit\(\.rules\|d\.conf\)$" register: files_found changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_permissions_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88002-1 - configure_strategy - file_permissions_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set permissions for /etc/audit/ file(s) file: path: '{{ item }}' mode: u-xs,g-xws,o-xwrt state: file with_items: - '{{ files_found.stdout_lines }}' when: - configure_strategy | bool - file_permissions_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88002-1 - configure_strategy - file_permissions_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/audit/rules.d/ file(s) command: find -H /etc/audit/rules.d/ -maxdepth 1 -perm /u+xs,g+xws,o+xwrt -type f -regex ".*\.rules$" register: files_found changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_permissions_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88002-1 - configure_strategy - file_permissions_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set permissions for /etc/audit/rules.d/ file(s) file: path: '{{ item }}' mode: u-xs,g-xws,o-xwrt state: file with_items: - '{{ files_found.stdout_lines }}' when: - configure_strategy | bool - file_permissions_audit_configuration | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88002-1 - configure_strategy - file_permissions_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-83720-3 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AC-6(1) - NIST-800-53-AU-9(4) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5 - PCI-DSSv4-10.3.1 - file_permissions_var_log_audit - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - file_permissions_var_log_audit | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Get audit log files command: grep -iw ^log_file /etc/audit/auditd.conf failed_when: false register: log_file_exists when: - file_permissions_var_log_audit | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83720-3 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AC-6(1) - NIST-800-53-AU-9(4) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5 - PCI-DSSv4-10.3.1 - file_permissions_var_log_audit - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Parse log file line command: awk -F '=' '/^log_file/ {print $2}' /etc/audit/auditd.conf register: log_file_line when: - file_permissions_var_log_audit | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - (log_file_exists.stdout | length > 0) tags: - CCE-83720-3 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AC-6(1) - NIST-800-53-AU-9(4) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5 - PCI-DSSv4-10.3.1 - file_permissions_var_log_audit - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set default log_file if not set set_fact: log_file: /var/log/audit/audit.log when: - file_permissions_var_log_audit | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - (log_file_exists is undefined) or (log_file_exists.stdout | length == 0) tags: - CCE-83720-3 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AC-6(1) - NIST-800-53-AU-9(4) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5 - PCI-DSSv4-10.3.1 - file_permissions_var_log_audit - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set log_file from log_file_line if not set already set_fact: log_file: '{{ log_file_line.stdout | trim }}' when: - file_permissions_var_log_audit | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - (log_file_line.stdout is defined) and (log_file_line.stdout | length > 0) tags: - CCE-83720-3 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AC-6(1) - NIST-800-53-AU-9(4) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5 - PCI-DSSv4-10.3.1 - file_permissions_var_log_audit - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Apply mode to log file file: path: '{{ log_file }}' mode: 384 failed_when: false when: - file_permissions_var_log_audit | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83720-3 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AC-6(1) - NIST-800-53-AU-9(4) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5 - PCI-DSSv4-10.3.1 - file_permissions_var_log_audit - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83830-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_chmod - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_chmod | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit chmod tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_chmod | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83830-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_chmod - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for chmod for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - chmod syscall_grouping: - chmod - fchmod - fchmodat - name: Check existence of chmod in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - chmod syscall_grouping: - chmod - fchmod - fchmodat - name: Check existence of chmod in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_chmod | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83830-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_chmod - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for chmod for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - chmod syscall_grouping: - chmod - fchmod - fchmodat - name: Check existence of chmod in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - chmod syscall_grouping: - chmod - fchmod - fchmodat - name: Check existence of chmod in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_chmod | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83830-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_chmod - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83812-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_chown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_chown | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit chown tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_chown | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83812-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_chown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for chown for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - chown syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of chown in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - chown syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of chown in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_chown | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83812-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_chown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for chown for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - chown syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of chown in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - chown syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of chown in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_chown | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83812-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_chown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83832-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchmod - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_fchmod | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit fchmod tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_fchmod | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83832-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchmod - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for fchmod for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - fchmod syscall_grouping: - chmod - fchmod - fchmodat - name: Check existence of fchmod in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fchmod syscall_grouping: - chmod - fchmod - fchmodat - name: Check existence of fchmod in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_fchmod | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83832-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchmod - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for fchmod for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - fchmod syscall_grouping: - chmod - fchmod - fchmodat - name: Check existence of fchmod in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fchmod syscall_grouping: - chmod - fchmod - fchmodat - name: Check existence of fchmod in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_fchmod | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83832-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchmod - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83822-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchmodat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_fchmodat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit fchmodat tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_fchmodat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83822-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchmodat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for fchmodat for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - fchmodat syscall_grouping: - chmod - fchmod - fchmodat - name: Check existence of fchmodat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fchmodat syscall_grouping: - chmod - fchmod - fchmodat - name: Check existence of fchmodat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_fchmodat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83822-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchmodat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for fchmodat for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - fchmodat syscall_grouping: - chmod - fchmod - fchmodat - name: Check existence of fchmodat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fchmodat syscall_grouping: - chmod - fchmod - fchmodat - name: Check existence of fchmodat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_fchmodat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83822-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchmodat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83829-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_fchown | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit fchown tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_fchown | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83829-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for fchown for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - fchown syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of fchown in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fchown syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of fchown in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_fchown | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83829-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for fchown for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - fchown syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of fchown in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fchown syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of fchown in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_fchown | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83829-2 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83831-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchownat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_fchownat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit fchownat tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_fchownat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83831-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchownat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for fchownat for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - fchownat syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of fchownat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fchownat syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of fchownat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_fchownat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83831-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchownat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for fchownat for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - fchownat syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of fchownat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fchownat syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of fchownat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_fchownat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83831-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchownat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83821-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fremovexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_fremovexattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit fremovexattr tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_fremovexattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83821-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fremovexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for fremovexattr for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - fremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fremovexattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fremovexattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fremovexattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fremovexattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_fremovexattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83821-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fremovexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for fremovexattr for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - fremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fremovexattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fremovexattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fremovexattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fremovexattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_fremovexattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83821-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fremovexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83817-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fsetxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_fsetxattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit fsetxattr tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_fsetxattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83817-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fsetxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for fsetxattr for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - fsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fsetxattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fsetxattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fsetxattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fsetxattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_fsetxattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83817-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fsetxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for fsetxattr for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - fsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fsetxattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fsetxattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fsetxattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - fsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of fsetxattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_fsetxattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83817-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fsetxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83833-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lchown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_lchown | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit lchown tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_lchown | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83833-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lchown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for lchown for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - lchown syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of lchown in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lchown syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of lchown in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_lchown | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83833-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lchown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for lchown for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - lchown syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of lchown in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lchown syscall_grouping: - chown - fchown - fchownat - lchown - name: Check existence of lchown in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_lchown | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83833-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lchown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83814-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lremovexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_lremovexattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit lremovexattr tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_lremovexattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83814-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lremovexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for lremovexattr for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - lremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lremovexattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lremovexattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lremovexattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lremovexattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_lremovexattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83814-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lremovexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for lremovexattr for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - lremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lremovexattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lremovexattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lremovexattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lremovexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lremovexattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_lremovexattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83814-4 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lremovexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83808-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lsetxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_lsetxattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit lsetxattr tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_lsetxattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83808-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lsetxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for lsetxattr for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - lsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lsetxattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lsetxattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lsetxattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lsetxattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_lsetxattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83808-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lsetxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for lsetxattr for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - lsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lsetxattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lsetxattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lsetxattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - lsetxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of lsetxattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_lsetxattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83808-6 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lsetxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83807-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_removexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_removexattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit removexattr tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_removexattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83807-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_removexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for removexattr for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - removexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of removexattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - removexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of removexattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - removexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of removexattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - removexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of removexattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_removexattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83807-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_removexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for removexattr for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - removexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of removexattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - removexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of removexattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - removexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of removexattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - removexattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of removexattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_removexattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83807-8 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_removexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83811-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_setxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_dac_modification_setxattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit setxattr tasks set_fact: audit_arch: b64 when: - audit_rules_dac_modification_setxattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83811-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_setxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for setxattr for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - setxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of setxattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - setxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of setxattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - setxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of setxattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - setxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of setxattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_setxattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83811-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_setxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for setxattr for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - setxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of setxattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - setxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of setxattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - setxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of setxattr in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - setxattr syscall_grouping: - fremovexattr - lremovexattr - removexattr - fsetxattr - lsetxattr - setxattr - name: Check existence of setxattr in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid=0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid=0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid=0 -F key=perm_mod create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_dac_modification_setxattr | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83811-0 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.5 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_setxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-87685-4 - audit_rules_execution_chacl - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_execution_chacl | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Perform remediation of Audit rules for /usr/bin/chacl block: - name: Declare list of syscalls set_fact: syscalls: [] syscall_grouping: [] - name: Check existence of in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F path=/usr/bin/chacl -F perm=x -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules set_fact: audit_file="/etc/audit/rules.d/privileged.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/chacl -F perm=x -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chacl -F perm=x -F auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: [] syscall_grouping: [] - name: Check existence of in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F path=/usr/bin/chacl -F perm=x -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/chacl -F perm=x -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chacl -F perm=x -F auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_execution_chacl | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87685-4 - audit_rules_execution_chacl - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-90482-1 - audit_rules_execution_setfacl - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_execution_setfacl | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Perform remediation of Audit rules for /usr/bin/setfacl block: - name: Declare list of syscalls set_fact: syscalls: [] syscall_grouping: [] - name: Check existence of in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F path=/usr/bin/setfacl -F perm=x -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules set_fact: audit_file="/etc/audit/rules.d/privileged.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/setfacl -F perm=x -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/setfacl -F perm=x -F auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: [] syscall_grouping: [] - name: Check existence of in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F path=/usr/bin/setfacl -F perm=x -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/setfacl -F perm=x -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/setfacl -F perm=x -F auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_execution_setfacl | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90482-1 - audit_rules_execution_setfacl - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83748-4 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - audit_rules_execution_chcon - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_execution_chcon | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Perform remediation of Audit rules for /usr/bin/chcon block: - name: Declare list of syscalls set_fact: syscalls: [] syscall_grouping: [] - name: Check existence of in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F path=/usr/bin/chcon -F perm=x -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules set_fact: audit_file="/etc/audit/rules.d/privileged.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/chcon -F perm=x -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chcon -F perm=x -F auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: [] syscall_grouping: [] - name: Check existence of in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F path=/usr/bin/chcon -F perm=x -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/chcon -F perm=x -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chcon -F perm=x -F auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_execution_chcon | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83748-4 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - audit_rules_execution_chcon - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83754-2 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_rename - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_file_deletion_events_rename | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit rename tasks set_fact: audit_arch: b64 when: - audit_rules_file_deletion_events_rename | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83754-2 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_rename - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for rename for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - rename syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of rename in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules set_fact: audit_file="/etc/audit/rules.d/delete.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - rename syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of rename in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_file_deletion_events_rename | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83754-2 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_rename - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for rename for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - rename syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of rename in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules set_fact: audit_file="/etc/audit/rules.d/delete.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - rename syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of rename in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_file_deletion_events_rename | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83754-2 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_rename - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83756-7 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_renameat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_file_deletion_events_renameat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit renameat tasks set_fact: audit_arch: b64 when: - audit_rules_file_deletion_events_renameat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83756-7 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_renameat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for renameat for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - renameat syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of renameat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules set_fact: audit_file="/etc/audit/rules.d/delete.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - renameat syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of renameat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_file_deletion_events_renameat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83756-7 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_renameat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for renameat for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - renameat syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of renameat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules set_fact: audit_file="/etc/audit/rules.d/delete.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - renameat syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of renameat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_file_deletion_events_renameat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83756-7 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_renameat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83757-5 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_unlink - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_file_deletion_events_unlink | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit unlink tasks set_fact: audit_arch: b64 when: - audit_rules_file_deletion_events_unlink | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83757-5 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_unlink - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for unlink for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - unlink syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of unlink in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules set_fact: audit_file="/etc/audit/rules.d/delete.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - unlink syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of unlink in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_file_deletion_events_unlink | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83757-5 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_unlink - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for unlink for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - unlink syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of unlink in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules set_fact: audit_file="/etc/audit/rules.d/delete.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - unlink syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of unlink in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_file_deletion_events_unlink | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83757-5 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_unlink - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83755-9 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_unlinkat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_file_deletion_events_unlinkat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit unlinkat tasks set_fact: audit_arch: b64 when: - audit_rules_file_deletion_events_unlinkat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83755-9 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_unlinkat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for unlinkat for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - unlinkat syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of unlinkat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules set_fact: audit_file="/etc/audit/rules.d/delete.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - unlinkat syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of unlinkat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_file_deletion_events_unlinkat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83755-9 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_unlinkat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for unlinkat for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - unlinkat syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of unlinkat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules set_fact: audit_file="/etc/audit/rules.d/delete.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - unlinkat syscall_grouping: - unlink - unlinkat - rename - renameat - rmdir - name: Check existence of unlinkat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=delete create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_file_deletion_events_unlinkat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83755-9 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_unlinkat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83786-4 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_creat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_unsuccessful_file_modification_creat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit creat tasks set_fact: audit_arch: b64 when: - audit_rules_unsuccessful_file_modification_creat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83786-4 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_creat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for creat EACCES for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - creat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of creat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - creat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of creat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_creat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83786-4 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_creat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for creat EACCES for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - creat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of creat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - creat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of creat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_creat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83786-4 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_creat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for creat EPERM for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - creat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of creat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - creat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of creat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_creat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83786-4 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_creat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for creat EPERM for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - creat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of creat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - creat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of creat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_creat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83786-4 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_creat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83800-3 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_ftruncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_unsuccessful_file_modification_ftruncate | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit ftruncate tasks set_fact: audit_arch: b64 when: - audit_rules_unsuccessful_file_modification_ftruncate | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83800-3 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_ftruncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for ftruncate EACCES for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - ftruncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of ftruncate in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - ftruncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of ftruncate in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_ftruncate | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83800-3 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_ftruncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for ftruncate EACCES for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - ftruncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of ftruncate in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - ftruncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of ftruncate in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_ftruncate | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83800-3 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_ftruncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for ftruncate EPERM for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - ftruncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of ftruncate in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - ftruncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of ftruncate in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_ftruncate | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83800-3 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_ftruncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for ftruncate EPERM for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - ftruncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of ftruncate in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - ftruncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of ftruncate in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_ftruncate | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83800-3 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_ftruncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83801-1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_open - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_unsuccessful_file_modification_open | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit open tasks set_fact: audit_arch: b64 when: - audit_rules_unsuccessful_file_modification_open | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83801-1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_open - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for open EACCES for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - open syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of open in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - open syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of open in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_open | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83801-1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_open - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for open EACCES for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - open syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of open in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - open syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of open in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_open | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83801-1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_open - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for open EPERM for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - open syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of open in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - open syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of open in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_open | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83801-1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_open - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for open EPERM for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - open syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of open in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - open syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of open in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_open | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83801-1 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_open - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83794-8 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_openat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_unsuccessful_file_modification_openat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit openat tasks set_fact: audit_arch: b64 when: - audit_rules_unsuccessful_file_modification_openat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83794-8 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_openat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for openat EACCES for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - openat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of openat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - openat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of openat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_openat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83794-8 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_openat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for openat EACCES for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - openat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of openat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - openat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of openat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_openat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83794-8 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_openat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for openat EPERM for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - openat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of openat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - openat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of openat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_openat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83794-8 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_openat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for openat EPERM for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - openat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of openat in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - openat syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of openat in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_openat | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83794-8 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_openat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83792-2 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_truncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_unsuccessful_file_modification_truncate | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Set architecture for audit truncate tasks set_fact: audit_arch: b64 when: - audit_rules_unsuccessful_file_modification_truncate | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83792-2 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_truncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for truncate EACCES for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - truncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of truncate in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - truncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of truncate in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_truncate | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83792-2 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_truncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for truncate EACCES for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - truncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of truncate in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - truncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of truncate in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_truncate | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83792-2 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_truncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for truncate EPERM for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - truncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of truncate in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - truncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of truncate in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_truncate | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83792-2 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_truncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Perform remediation of Audit rules for truncate EPERM for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - truncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of truncate in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules set_fact: audit_file="/etc/audit/rules.d/access.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - truncate syscall_grouping: - creat - ftruncate - truncate - open - openat - open_by_handle_at - name: Check existence of truncate in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_unsuccessful_file_modification_truncate | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83792-2 - NIST-800-171-3.1.7 - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.1 - PCI-DSS-Req-10.2.4 - PCI-DSSv4-10.2.1.1 - PCI-DSSv4-10.2.1.4 - audit_rules_unsuccessful_file_modification_truncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-88436-1 - audit_rules_kernel_module_loading_create - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - audit_rules_kernel_module_loading_create | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Set architecture for audit finit_module tasks set_fact: audit_arch: b64 when: - audit_rules_kernel_module_loading_create | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-88436-1 - audit_rules_kernel_module_loading_create - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Perform remediation of Audit rules for finit_module for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - create_module syscall_grouping: [] - name: Check existence of create_module in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules set_fact: audit_file="/etc/audit/rules.d/module-change.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - create_module syscall_grouping: [] - name: Check existence of create_module in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_kernel_module_loading_create | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88436-1 - audit_rules_kernel_module_loading_create - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Perform remediation of Audit rules for finit_module for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - create_module syscall_grouping: [] - name: Check existence of create_module in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules set_fact: audit_file="/etc/audit/rules.d/module-change.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - create_module syscall_grouping: [] - name: Check existence of create_module in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_kernel_module_loading_create | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-88436-1 - audit_rules_kernel_module_loading_create - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-83802-9 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_kernel_module_loading_delete - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - audit_rules_kernel_module_loading_delete | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Set architecture for audit delete_module tasks set_fact: audit_arch: b64 when: - audit_rules_kernel_module_loading_delete | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83802-9 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_kernel_module_loading_delete - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Perform remediation of Audit rules for delete_module for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - delete_module syscall_grouping: [] - name: Check existence of delete_module in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules set_fact: audit_file="/etc/audit/rules.d/module-change.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - delete_module syscall_grouping: [] - name: Check existence of delete_module in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_kernel_module_loading_delete | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83802-9 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_kernel_module_loading_delete - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Perform remediation of Audit rules for delete_module for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - delete_module syscall_grouping: [] - name: Check existence of delete_module in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules set_fact: audit_file="/etc/audit/rules.d/module-change.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - delete_module syscall_grouping: [] - name: Check existence of delete_module in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_kernel_module_loading_delete | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83802-9 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_kernel_module_loading_delete - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-83803-7 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_kernel_module_loading_finit - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - audit_rules_kernel_module_loading_finit | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Set architecture for audit finit_module tasks set_fact: audit_arch: b64 when: - audit_rules_kernel_module_loading_finit | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83803-7 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_kernel_module_loading_finit - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Perform remediation of Audit rules for finit_module for x86 platform block: - name: Declare list of syscalls set_fact: syscalls: - finit_module syscall_grouping: - init_module - finit_module - name: Check existence of finit_module in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules set_fact: audit_file="/etc/audit/rules.d/module-change.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - finit_module syscall_grouping: - init_module - finit_module - name: Check existence of finit_module in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_kernel_module_loading_finit | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83803-7 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_kernel_module_loading_finit - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Perform remediation of Audit rules for finit_module for x86_64 platform block: - name: Declare list of syscalls set_fact: syscalls: - finit_module syscall_grouping: - init_module - finit_module - name: Check existence of finit_module in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules set_fact: audit_file="/etc/audit/rules.d/module-change.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - finit_module syscall_grouping: - init_module - finit_module - name: Check existence of finit_module in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_kernel_module_loading_finit | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83803-7 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_kernel_module_loading_finit - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-90835-0 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_kernel_module_loading_init - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - audit_rules_kernel_module_loading_init | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Set architecture for audit init_module tasks set_fact: audit_arch: b64 when: - audit_rules_kernel_module_loading_init | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-90835-0 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_kernel_module_loading_init - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Perform remediation of Audit rules for init_module for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - init_module syscall_grouping: - init_module - finit_module - name: Check existence of init_module in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules set_fact: audit_file="/etc/audit/rules.d/module-change.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - init_module syscall_grouping: - init_module - finit_module - name: Check existence of init_module in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_kernel_module_loading_init | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90835-0 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_kernel_module_loading_init - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Perform remediation of Audit rules for init_module for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - init_module syscall_grouping: - init_module - finit_module - name: Check existence of init_module in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules set_fact: audit_file="/etc/audit/rules.d/module-change.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - init_module syscall_grouping: - init_module - finit_module - name: Check existence of init_module in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_kernel_module_loading_init | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-90835-0 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.7 - PCI-DSSv4-10.2.1.7 - audit_rules_kernel_module_loading_init - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-88749-7 - audit_rules_kernel_module_loading_query - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - audit_rules_kernel_module_loading_query | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Set architecture for audit query_module tasks set_fact: audit_arch: b64 when: - audit_rules_kernel_module_loading_query | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-88749-7 - audit_rules_kernel_module_loading_query - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Perform remediation of Audit rules for query_module for x86 platform block: - name: Declare list of syscalls set_fact: syscalls: - query_module syscall_grouping: - init_module - query_module - name: Check existence of query_module in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules set_fact: audit_file="/etc/audit/rules.d/module-change.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - query_module syscall_grouping: - init_module - query_module - name: Check existence of query_module in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_kernel_module_loading_query | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88749-7 - audit_rules_kernel_module_loading_query - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Perform remediation of Audit rules for query_module for x86_64 platform block: - name: Declare list of syscalls set_fact: syscalls: - query_module syscall_grouping: - init_module - query_module - name: Check existence of query_module in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/module-change.rules set_fact: audit_file="/etc/audit/rules.d/module-change.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - query_module syscall_grouping: - init_module - query_module - name: Check existence of query_module in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000 -F auid!=unset -F key=module-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_kernel_module_loading_query | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-88749-7 - audit_rules_kernel_module_loading_query - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-83783-1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_faillock - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_login_events_faillock | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Check if watch rule for /var/log/faillock already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/var/log/faillock\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_login_events_faillock | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83783-1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_faillock - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key logins find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)logins$ patterns: '*.rules' register: find_watch_key when: - audit_rules_login_events_faillock | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83783-1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_faillock - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/logins.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/logins.rules when: - audit_rules_login_events_faillock | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83783-1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_faillock - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_login_events_faillock | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83783-1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_faillock - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /var/log/faillock in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /var/log/faillock -p wa -k logins create: true mode: '0640' when: - audit_rules_login_events_faillock | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83783-1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_faillock - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /var/log/faillock already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/var/log/faillock\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_login_events_faillock | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83783-1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_faillock - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /var/log/faillock in /etc/audit/audit.rules lineinfile: line: -w /var/log/faillock -p wa -k logins state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_login_events_faillock | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83783-1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_faillock - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83785-6 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_lastlog - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy when: - audit_rules_login_events_lastlog | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - name: Check if watch rule for /var/log/lastlog already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/var/log/lastlog\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_login_events_lastlog | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83785-6 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_lastlog - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key logins find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)logins$ patterns: '*.rules' register: find_watch_key when: - audit_rules_login_events_lastlog | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83785-6 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_lastlog - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use /etc/audit/rules.d/logins.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/logins.rules when: - audit_rules_login_events_lastlog | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83785-6 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_lastlog - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_login_events_lastlog | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83785-6 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_lastlog - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /var/log/lastlog in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /var/log/lastlog -p wa -k logins create: true mode: '0640' when: - audit_rules_login_events_lastlog | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83785-6 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_lastlog - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Check if watch rule for /var/log/lastlog already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/var/log/lastlog\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_login_events_lastlog | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83785-6 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_lastlog - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Add watch rule for /var/log/lastlog in /etc/audit/audit.rules lineinfile: line: -w /var/log/lastlog -p wa -k logins state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_login_events_lastlog | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83785-6 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.3 - PCI-DSSv4-10.2.1.3 - audit_rules_login_events_lastlog - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83759-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSSv4-10.2.1.2 - audit_rules_privileged_commands - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - audit_rules_privileged_commands | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure auditd Collects Information on the Use of Privileged Commands - Set List of Mount Points Which Permits Execution of Privileged Commands ansible.builtin.set_fact: privileged_mount_points: '{{(ansible_facts.mounts | rejectattr(''options'', ''search'', ''noexec|nosuid'') | rejectattr(''mount'', ''match'', ''/proc($|/.*$)'') | map(attribute=''mount'') | list ) }}' when: - audit_rules_privileged_commands | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83759-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSSv4-10.2.1.2 - audit_rules_privileged_commands - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure auditd Collects Information on the Use of Privileged Commands - Search for Privileged Commands in Eligible Mount Points ansible.builtin.shell: cmd: find {{ item }} -xdev -perm /6000 -type f 2>/dev/null register: result_privileged_commands_search changed_when: false failed_when: false with_items: '{{ privileged_mount_points }}' when: - audit_rules_privileged_commands | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83759-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSSv4-10.2.1.2 - audit_rules_privileged_commands - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure auditd Collects Information on the Use of Privileged Commands - Set List of Privileged Commands Found in Eligible Mount Points ansible.builtin.set_fact: privileged_commands: '{{( result_privileged_commands_search.results | map(attribute=''stdout_lines'') | select() | list )[-1] }}' when: - audit_rules_privileged_commands | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83759-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSSv4-10.2.1.2 - audit_rules_privileged_commands - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure auditd Collects Information on the Use of Privileged Commands - Privileged Commands are Present in the System block: - name: Ensure auditd Collects Information on the Use of Privileged Commands - Ensure Rules for All Privileged Commands in augenrules Format ansible.builtin.lineinfile: path: /etc/audit/rules.d/privileged.rules line: -a always,exit -F path={{ item }} -F perm=x -F auid>=1000 -F auid!=unset -F key=privileged regexp: ^.*path={{ item | regex_escape() }} .*$ create: true with_items: - '{{ privileged_commands }}' - name: Ensure auditd Collects Information on the Use of Privileged Commands - Ensure Rules for All Privileged Commands in auditctl Format ansible.builtin.lineinfile: path: /etc/audit/audit.rules line: -a always,exit -F path={{ item }} -F perm=x -F auid>=1000 -F auid!=unset -F key=privileged regexp: ^.*path={{ item | regex_escape() }} .*$ create: true with_items: - '{{ privileged_commands }}' - name: Ensure auditd Collects Information on the Use of Privileged Commands - Search for Duplicated Rules in Other Files ansible.builtin.find: paths: /etc/audit/rules.d recurse: false contains: ^-a always,exit -F path={{ item }} .*$ patterns: '*.rules' with_items: - '{{ privileged_commands }}' register: result_augenrules_files - name: Ensure auditd Collects Information on the Use of Privileged Commands - Ensure Rules for Privileged Commands are Defined Only in One File ansible.builtin.lineinfile: path: '{{ item.1.path }}' regexp: ^-a always,exit -F path={{ item.0.item }} .*$ state: absent with_subelements: - '{{ result_augenrules_files.results }}' - files when: - item.1.path != '/etc/audit/rules.d/privileged.rules' when: - audit_rules_privileged_commands | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - privileged_commands is defined tags: - CCE-83759-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.2.2 - PCI-DSSv4-10.2.1.2 - audit_rules_privileged_commands - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-90262-7 - NIST-800-53-AU-12(a) - NIST-800-53-AU-12.1(ii) - NIST-800-53-AU-12.1(iv)AU-12(c) - NIST-800-53-AU-3 - NIST-800-53-AU-3.1 - NIST-800-53-MA-4(1)(a) - audit_rules_privileged_commands_kmod - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_privileged_commands_kmod | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Perform remediation of Audit rules for /usr/bin/kmod block: - name: Declare list of syscalls set_fact: syscalls: [] syscall_grouping: [] - name: Check existence of in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F path=/usr/bin/kmod -F perm=x -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules set_fact: audit_file="/etc/audit/rules.d/privileged.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/kmod -F perm=x -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/kmod -F perm=x -F auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: [] syscall_grouping: [] - name: Check existence of in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F path=/usr/bin/kmod -F perm=x -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/kmod -F perm=x -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/kmod -F perm=x -F auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_privileged_commands_kmod | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90262-7 - NIST-800-53-AU-12(a) - NIST-800-53-AU-12.1(ii) - NIST-800-53-AU-12.1(iv)AU-12(c) - NIST-800-53-AU-3 - NIST-800-53-AU-3.1 - NIST-800-53-MA-4(1)(a) - audit_rules_privileged_commands_kmod - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-87212-7 - audit_rules_privileged_commands_usermod - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_privileged_commands_usermod | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Perform remediation of Audit rules for /usr/sbin/usermod block: - name: Declare list of syscalls set_fact: syscalls: [] syscall_grouping: [] - name: Check existence of in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F path=/usr/sbin/usermod -F perm=x -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules set_fact: audit_file="/etc/audit/rules.d/privileged.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/usermod -F perm=x -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/usermod -F perm=x -F auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: [] syscall_grouping: [] - name: Check existence of in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F path=/usr/sbin/usermod -F perm=x -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/usermod -F perm=x -F auid>=1000 -F auid!=unset (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/usermod -F perm=x -F auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_privileged_commands_usermod | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87212-7 - audit_rules_privileged_commands_usermod - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83840-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_adjtimex - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_time_adjtimex | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Set architecture for audit tasks set_fact: audit_arch: b64 when: - audit_rules_time_adjtimex | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83840-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_adjtimex - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Perform remediation of Audit rules for adjtimex for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - adjtimex syscall_grouping: - adjtimex - settimeofday - stime - name: Check existence of adjtimex in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/audit_time_rules.rules set_fact: audit_file="/etc/audit/rules.d/audit_time_rules.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_time_rules create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - adjtimex syscall_grouping: - adjtimex - settimeofday - stime - name: Check existence of adjtimex in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_time_rules create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_time_adjtimex | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83840-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_adjtimex - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Perform remediation of Audit rules for adjtimex for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - adjtimex syscall_grouping: - adjtimex - settimeofday - name: Check existence of adjtimex in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/audit_time_rules.rules set_fact: audit_file="/etc/audit/rules.d/audit_time_rules.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=audit_time_rules create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - adjtimex syscall_grouping: - adjtimex - settimeofday - stime - name: Check existence of adjtimex in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=audit_time_rules create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_time_adjtimex | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83840-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_adjtimex - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83837-5 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_clock_settime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_time_clock_settime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Set architecture for audit tasks set_fact: audit_arch: b64 when: - audit_rules_time_clock_settime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83837-5 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_clock_settime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Perform remediation of Audit rules for clock_settime for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - clock_settime syscall_grouping: [] - name: Check existence of clock_settime in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F a0=0x0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/time-change.rules set_fact: audit_file="/etc/audit/rules.d/time-change.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F a0=0x0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F a0=0x0 -F key=time-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - clock_settime syscall_grouping: [] - name: Check existence of clock_settime in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F a0=0x0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F a0=0x0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F a0=0x0 -F key=time-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_time_clock_settime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83837-5 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_clock_settime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Perform remediation of Audit rules for clock_settime for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - clock_settime syscall_grouping: [] - name: Check existence of clock_settime in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F a0=0x0 (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/time-change.rules set_fact: audit_file="/etc/audit/rules.d/time-change.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( -F a0=0x0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F a0=0x0 -F key=time-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - clock_settime syscall_grouping: [] - name: Check existence of clock_settime in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* -F a0=0x0 (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( -F a0=0x0 (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F a0=0x0 -F key=time-change create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_time_clock_settime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83837-5 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_clock_settime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83836-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_settimeofday - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_time_settimeofday | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Set architecture for audit tasks set_fact: audit_arch: b64 when: - audit_rules_time_settimeofday | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CCE-83836-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_settimeofday - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Perform remediation of Audit rules for settimeofday for 32bit platform block: - name: Declare list of syscalls set_fact: syscalls: - settimeofday syscall_grouping: - adjtimex - settimeofday - stime - name: Check existence of settimeofday in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/audit_time_rules.rules set_fact: audit_file="/etc/audit/rules.d/audit_time_rules.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_time_rules create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - settimeofday syscall_grouping: - adjtimex - settimeofday - stime - name: Check existence of settimeofday in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_time_rules create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_time_settimeofday | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83836-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_settimeofday - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Perform remediation of Audit rules for settimeofday for 64bit platform block: - name: Declare list of syscalls set_fact: syscalls: - settimeofday syscall_grouping: - adjtimex - settimeofday - stime - name: Check existence of settimeofday in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/audit_time_rules.rules set_fact: audit_file="/etc/audit/rules.d/audit_time_rules.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=audit_time_rules create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - settimeofday syscall_grouping: - adjtimex - settimeofday - stime - name: Check existence of settimeofday in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=audit_time_rules create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_time_settimeofday | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - audit_arch == "b64" tags: - CCE-83836-7 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_settimeofday - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83835-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_stime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_time_stime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Perform remediation of Audit rules for stime syscall for x86 platform block: - name: Declare list of syscalls set_fact: syscalls: - stime syscall_grouping: - adjtimex - settimeofday - stime - name: Check existence of stime in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: '*.rules' register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Reset syscalls found per file set_fact: syscalls_per_file: {} found_paths_dict: {} - name: Declare syscalls found per file set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}" loop: '{{ find_command.results | selectattr(''matched'') | list }}' - name: Declare files where syscalls were found set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten | map(attribute='path') | list }}" - name: Count occurrences of syscalls in paths set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item, 0) }) }}" loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'') | list }}' - name: Get path with most syscalls set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value') | last).key }}" when: found_paths | length >= 1 - name: No file with syscall found, set path to /etc/audit/rules.d/audit_time_rules.rules set_fact: audit_file="/etc/audit/rules.d/audit_time_rules.rules" when: found_paths | length == 0 - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file] | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_time_rules create: true mode: o-rwx state: present when: syscalls_found | length == 0 - name: Declare list of syscalls set_fact: syscalls: - stime syscall_grouping: - adjtimex - settimeofday - stime - name: Check existence of stime in /etc/audit/audit.rules find: paths: /etc/audit contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$ patterns: audit.rules register: find_command loop: '{{ (syscall_grouping + syscalls) | unique }}' - name: Set path to /etc/audit/audit.rules set_fact: audit_file="/etc/audit/audit.rules" - name: Declare found syscalls set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item') | list }}" - name: Declare missing syscalls set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}" - name: Replace the audit rule in {{ audit_file }} lineinfile: path: '{{ audit_file }}' regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+) line: \1\2\3{{ missing_syscalls | join("\3") }}\4 backrefs: true state: present when: syscalls_found | length > 0 and missing_syscalls | length > 0 - name: Add the audit rule to {{ audit_file }} lineinfile: path: '{{ audit_file }}' line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_time_rules create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - audit_rules_time_stime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83835-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - audit_rules_time_stime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83839-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - PCI-DSSv4-10.6.3 - audit_rules_time_watch_localtime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - audit_rules_time_watch_localtime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Check if watch rule for /etc/localtime already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/localtime\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - audit_rules_time_watch_localtime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83839-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - PCI-DSSv4-10.6.3 - audit_rules_time_watch_localtime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Search /etc/audit/rules.d for other rules with specified key audit_time_rules find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)audit_time_rules$ patterns: '*.rules' register: find_watch_key when: - audit_rules_time_watch_localtime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83839-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - PCI-DSSv4-10.6.3 - audit_rules_time_watch_localtime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use /etc/audit/rules.d/audit_time_rules.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/audit_time_rules.rules when: - audit_rules_time_watch_localtime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83839-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - PCI-DSSv4-10.6.3 - audit_rules_time_watch_localtime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use matched file as the recipient for the rule set_fact: all_files: - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' when: - audit_rules_time_watch_localtime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83839-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - PCI-DSSv4-10.6.3 - audit_rules_time_watch_localtime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/localtime in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/localtime -p wa -k audit_time_rules create: true mode: '0640' when: - audit_rules_time_watch_localtime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CCE-83839-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - PCI-DSSv4-10.6.3 - audit_rules_time_watch_localtime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/localtime already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/localtime\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - audit_rules_time_watch_localtime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83839-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - PCI-DSSv4-10.6.3 - audit_rules_time_watch_localtime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/localtime in /etc/audit/audit.rules lineinfile: line: -w /etc/localtime -p wa -k audit_time_rules state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - audit_rules_time_watch_localtime | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CCE-83839-1 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.2.b - PCI-DSSv4-10.6.3 - PCI-DSSv4-10.6.3 - audit_rules_time_watch_localtime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83698-1 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AU-5(2) - NIST-800-53-AU-5(a) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1) - PCI-DSS-Req-10.7.a - PCI-DSSv4-10.5.1 - auditd_data_retention_action_mail_acct - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - auditd_data_retention_action_mail_acct | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Configure auditd mail_acct Action on Low Disk Space lineinfile: dest: /etc/audit/auditd.conf line: action_mail_acct = {{ var_auditd_action_mail_acct }} state: present create: true when: - auditd_data_retention_action_mail_acct | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83698-1 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AU-5(2) - NIST-800-53-AU-5(a) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1) - PCI-DSS-Req-10.7.a - PCI-DSSv4-10.5.1 - auditd_data_retention_action_mail_acct - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83700-5 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AU-5(1) - NIST-800-53-AU-5(2) - NIST-800-53-AU-5(4) - NIST-800-53-AU-5(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.7 - PCI-DSSv4-10.5.1 - auditd_data_retention_admin_space_left_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - auditd_data_retention_admin_space_left_action | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Configure auditd admin_space_left Action on Low Disk Space lineinfile: dest: /etc/audit/auditd.conf line: admin_space_left_action = {{ var_auditd_admin_space_left_action }} regexp: ^\s*admin_space_left_action\s*=\s*.*$ state: present create: true when: - auditd_data_retention_admin_space_left_action | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83700-5 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AU-5(1) - NIST-800-53-AU-5(2) - NIST-800-53-AU-5(4) - NIST-800-53-AU-5(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.7 - PCI-DSSv4-10.5.1 - auditd_data_retention_admin_space_left_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83683-3 - CJIS-5.4.1.1 - NIST-800-53-AU-11 - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.7 - PCI-DSSv4-10.5.1 - auditd_data_retention_max_log_file - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - auditd_data_retention_max_log_file | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Configure auditd Max Log File Size lineinfile: dest: /etc/audit/auditd.conf regexp: ^\s*max_log_file\s*=\s*.*$ line: max_log_file = {{ var_auditd_max_log_file }} state: present create: true when: - auditd_data_retention_max_log_file | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83683-3 - CJIS-5.4.1.1 - NIST-800-53-AU-11 - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.7 - PCI-DSSv4-10.5.1 - auditd_data_retention_max_log_file - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83701-3 - CJIS-5.4.1.1 - NIST-800-53-AU-5(1) - NIST-800-53-AU-5(2) - NIST-800-53-AU-5(4) - NIST-800-53-AU-5(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.7 - PCI-DSSv4-10.5.1 - auditd_data_retention_max_log_file_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - auditd_data_retention_max_log_file_action | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Configure auditd max_log_file_action Upon Reaching Maximum Log Size lineinfile: dest: /etc/audit/auditd.conf line: max_log_file_action = {{ var_auditd_max_log_file_action }} regexp: ^\s*max_log_file_action\s*=\s*.*$ state: present create: true when: - auditd_data_retention_max_log_file_action | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83701-3 - CJIS-5.4.1.1 - NIST-800-53-AU-5(1) - NIST-800-53-AU-5(2) - NIST-800-53-AU-5(4) - NIST-800-53-AU-5(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.7 - PCI-DSSv4-10.5.1 - auditd_data_retention_max_log_file_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83703-9 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AU-5(1) - NIST-800-53-AU-5(2) - NIST-800-53-AU-5(4) - NIST-800-53-AU-5(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.7 - PCI-DSSv4-10.5.1 - auditd_data_retention_space_left_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - auditd_data_retention_space_left_action | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Configure auditd space_left Action on Low Disk Space lineinfile: dest: /etc/audit/auditd.conf line: space_left_action = {{ var_auditd_space_left_action }} regexp: ^\s*space_left_action\s*=\s*.*$ state: present create: true when: - auditd_data_retention_space_left_action | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83703-9 - CJIS-5.4.1.1 - NIST-800-171-3.3.1 - NIST-800-53-AU-5(1) - NIST-800-53-AU-5(2) - NIST-800-53-AU-5(4) - NIST-800-53-AU-5(b) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.7 - PCI-DSSv4-10.5.1 - auditd_data_retention_space_left_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83848-2 - CJIS-5.5.2.2 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-7.1 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_grub2_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Test for existence /boot/grub2/grub.cfg stat: path: /boot/grub2/grub.cfg register: file_exists when: - configure_strategy | bool - file_groupowner_grub2_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83848-2 - CJIS-5.5.2.2 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-7.1 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /boot/grub2/grub.cfg file: path: /boot/grub2/grub.cfg group: '0' when: - configure_strategy | bool - file_groupowner_grub2_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83848-2 - CJIS-5.5.2.2 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-7.1 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-86010-6 - CJIS-5.5.2.2 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-7.1 - configure_strategy - file_groupowner_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_user_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Test for existence /boot/grub2/user.cfg stat: path: /boot/grub2/user.cfg register: file_exists when: - configure_strategy | bool - file_groupowner_user_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86010-6 - CJIS-5.5.2.2 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-7.1 - configure_strategy - file_groupowner_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /boot/grub2/user.cfg file: path: /boot/grub2/user.cfg group: '0' when: - configure_strategy | bool - file_groupowner_user_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86010-6 - CJIS-5.5.2.2 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-7.1 - configure_strategy - file_groupowner_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-83845-8 - CJIS-5.5.2.2 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-7.1 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_grub2_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Test for existence /boot/grub2/grub.cfg stat: path: /boot/grub2/grub.cfg register: file_exists when: - configure_strategy | bool - file_owner_grub2_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83845-8 - CJIS-5.5.2.2 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-7.1 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /boot/grub2/grub.cfg file: path: /boot/grub2/grub.cfg owner: '0' when: - configure_strategy | bool - file_owner_grub2_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83845-8 - CJIS-5.5.2.2 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-7.1 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-86016-3 - CJIS-5.5.2.2 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-7.1 - configure_strategy - file_owner_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_user_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Test for existence /boot/grub2/user.cfg stat: path: /boot/grub2/user.cfg register: file_exists when: - configure_strategy | bool - file_owner_user_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86016-3 - CJIS-5.5.2.2 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-7.1 - configure_strategy - file_owner_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /boot/grub2/user.cfg file: path: /boot/grub2/user.cfg owner: '0' when: - configure_strategy | bool - file_owner_user_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86016-3 - CJIS-5.5.2.2 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-7.1 - configure_strategy - file_owner_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-83846-6 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_grub2_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Test for existence /boot/grub2/grub.cfg stat: path: /boot/grub2/grub.cfg register: file_exists when: - configure_strategy | bool - file_permissions_grub2_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83846-6 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xwrs,o-xwrt on /boot/grub2/grub.cfg file: path: /boot/grub2/grub.cfg mode: u-xs,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_grub2_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83846-6 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-86025-4 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_user_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Test for existence /boot/grub2/user.cfg stat: path: /boot/grub2/user.cfg register: file_exists when: - configure_strategy | bool - file_permissions_user_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86025-4 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xwrs,o-xwrt on /boot/grub2/user.cfg file: path: /boot/grub2/user.cfg mode: u-xs,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_user_cfg | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86025-4 - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure rsyslog is installed package: name: rsyslog state: present when: - enable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - package_rsyslog_installed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84063-7 - NIST-800-53-CM-6(a) - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_rsyslog_installed - name: Enable service rsyslog block: - name: Gather the package facts package_facts: manager: auto - name: Enable service rsyslog systemd: name: rsyslog enabled: 'yes' state: started masked: 'no' when: - '"rsyslog" in ansible_facts.packages' when: - enable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - service_rsyslog_enabled | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83989-4 - NIST-800-53-AU-4(1) - NIST-800-53-CM-6(a) - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_rsyslog_enabled - name: Ensure rsyslog Default File Permissions Configured - Search for $FileCreateMode Parameter in rsyslog Main Config File ansible.builtin.find: paths: /etc pattern: rsyslog.conf contains: ^\s*\$FileCreateMode\s*\d+ register: rsyslog_main_file_with_filecreatemode when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_filecreatemode | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88322-3 - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_filecreatemode - name: Ensure rsyslog Default File Permissions Configured - Search for $FileCreateMode Parameter in rsyslog Include Files ansible.builtin.find: paths: /etc/rsyslog.d/ pattern: '*.conf' contains: ^\s*\$FileCreateMode\s*\d+ register: rsyslog_includes_with_filecreatemode when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_filecreatemode | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88322-3 - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_filecreatemode - name: Ensure rsyslog Default File Permissions Configured - Assemble List of rsyslog Configuration Files with $FileCreateMode Parameter ansible.builtin.set_fact: rsyslog_filecreatemode_files: '{{ rsyslog_main_file_with_filecreatemode.files | map(attribute=''path'') | list + rsyslog_includes_with_filecreatemode.files | map(attribute=''path'') | list }}' when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_filecreatemode | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88322-3 - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_filecreatemode - name: Ensure rsyslog Default File Permissions Configured - Remove $FileCreateMode Parameter from Multiple Files to Avoid Conflicts ansible.builtin.lineinfile: path: '{{ item }}' regexp: \$FileCreateMode.* state: absent register: result_rsyslog_filecreatemode_removed loop: '{{ rsyslog_filecreatemode_files }}' when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_filecreatemode | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - rsyslog_filecreatemode_files | length > 1 tags: - CCE-88322-3 - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_filecreatemode - name: Ensure rsyslog Default File Permissions Configured - Add $FileCreateMode Parameter and Expected Value ansible.builtin.lineinfile: path: /etc/rsyslog.d/99-rsyslog_filecreatemode.conf line: $FileCreateMode 0640 mode: 416 create: true when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_filecreatemode | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - rsyslog_filecreatemode_files | length == 0 or result_rsyslog_filecreatemode_removed is not skipped tags: - CCE-88322-3 - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_filecreatemode - name: Ensure rsyslog Default File Permissions Configured - Ensure Correct Value of Existing $FileCreateMode Parameter ansible.builtin.lineinfile: path: '{{ item }}' regexp: ^\$FileCreateMode line: $FileCreateMode 0640 loop: '{{ rsyslog_filecreatemode_files }}' when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_filecreatemode | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - rsyslog_filecreatemode_files | length == 1 tags: - CCE-88322-3 - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_filecreatemode - name: Ensure Log Files Are Owned By Appropriate Group - Set rsyslog logfile configuration facts ansible.builtin.set_fact: rsyslog_etc_config: /etc/rsyslog.conf when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_groupownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83834-2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_groupownership - name: Ensure Log Files Are Owned By Appropriate Group - Get IncludeConfig directive ansible.builtin.shell: 'set -o pipefail grep -e ''$IncludeConfig'' {{ rsyslog_etc_config }} | cut -d '' '' -f 2 || true ' register: rsyslog_old_inc changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_groupownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83834-2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_groupownership - name: Ensure Log Files Are Owned By Appropriate Group - Get include files directives ansible.builtin.shell: 'set -o pipefail awk ''/)/{f=0} /include\(/{f=1} f{nf=gensub("^(include\\(|\\s*)file=\"(\\S+)\".*","\\2",1); if($0!=nf){print nf}}'' {{ rsyslog_etc_config }} || true ' register: rsyslog_new_inc changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_groupownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83834-2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_groupownership - name: Ensure Log Files Are Owned By Appropriate Group - Aggregate rsyslog includes ansible.builtin.set_fact: include_config_output: '{{ rsyslog_old_inc.stdout_lines + rsyslog_new_inc.stdout_lines }}' when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_groupownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83834-2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_groupownership - name: Ensure Log Files Are Owned By Appropriate Group - List all config files ansible.builtin.find: paths: '{{ item | dirname }}' patterns: '{{ item | basename }}' hidden: false follow: true loop: '{{ include_config_output | list + [rsyslog_etc_config] }}' register: rsyslog_config_files failed_when: false changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_groupownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83834-2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_groupownership - name: Ensure Log Files Are Owned By Appropriate Group - Extract log files old format ansible.builtin.shell: 'set -o pipefail grep -oP ''^[^(\s|#|\$)]+[\s]+.*[\s]+-?(/+[^:;\s]+);*\.*$'' {{ item.1.path }} | \ awk ''{print $NF}'' | \ sed -e ''s/^-//'' || true ' loop: '{{ rsyslog_config_files.results | subelements(''files'') }}' register: log_files_old changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_groupownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83834-2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_groupownership - name: Ensure Log Files Are Owned By Appropriate Group - Extract log files new format ansible.builtin.shell: 'set -o pipefail grep -ozP "action\s*\(\s*type\s*=\s*\"omfile\"[^\)]*\)" {{ item.1.path }} | \ grep -aoP "File\s*=\s*\"([/[:alnum:][:punct:]]*)\"\s*\)" | \ grep -oE "\"([/[:alnum:][:punct:]]*)\"" | \ tr -d "\""|| true ' loop: '{{ rsyslog_config_files.results | subelements(''files'') }}' register: log_files_new changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_groupownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83834-2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_groupownership - name: Ensure Log Files Are Owned By Appropriate Group - Sum all log files found ansible.builtin.set_fact: log_files: '{{ log_files_new.results | map(attribute=''stdout_lines'') | list | flatten | unique + log_files_old.results | map(attribute=''stdout_lines'') | list | flatten | unique }}' when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_groupownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83834-2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_groupownership - name: Ensure Log Files Are Owned By Appropriate Group -Setup log files attribute ansible.builtin.file: path: '{{ item }}' group: '0' state: file loop: '{{ log_files | list | flatten | unique }}' failed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_groupownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83834-2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_groupownership - name: Ensure Log Files Are Owned By Appropriate User - Set rsyslog logfile configuration facts ansible.builtin.set_fact: rsyslog_etc_config: /etc/rsyslog.conf when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_ownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83946-4 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_ownership - name: Ensure Log Files Are Owned By Appropriate User - Get IncludeConfig directive ansible.builtin.shell: 'set -o pipefail grep -e ''$IncludeConfig'' {{ rsyslog_etc_config }} | cut -d '' '' -f 2 || true ' register: rsyslog_old_inc changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_ownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83946-4 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_ownership - name: Ensure Log Files Are Owned By Appropriate User - Get include files directives ansible.builtin.shell: 'set -o pipefail awk ''/)/{f=0} /include\(/{f=1} f{nf=gensub("^(include\\(|\\s*)file=\"(\\S+)\".*","\\2",1); if($0!=nf){print nf}}'' {{ rsyslog_etc_config }} || true ' register: rsyslog_new_inc changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_ownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83946-4 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_ownership - name: Ensure Log Files Are Owned By Appropriate User - Aggregate rsyslog includes ansible.builtin.set_fact: include_config_output: '{{ rsyslog_old_inc.stdout_lines + rsyslog_new_inc.stdout_lines }}' when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_ownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83946-4 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_ownership - name: Ensure Log Files Are Owned By Appropriate User - List all config files ansible.builtin.find: paths: '{{ item | dirname }}' patterns: '{{ item | basename }}' hidden: false follow: true loop: '{{ include_config_output | list + [rsyslog_etc_config] }}' register: rsyslog_config_files failed_when: false changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_ownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83946-4 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_ownership - name: Ensure Log Files Are Owned By Appropriate User - Extract log files old format ansible.builtin.shell: 'set -o pipefail grep -oP ''^[^(\s|#|\$)]+[\s]+.*[\s]+-?(/+[^:;\s]+);*\.*$'' {{ item.1.path }} | \ awk ''{print $NF}'' | \ sed -e ''s/^-//'' || true ' loop: '{{ rsyslog_config_files.results | subelements(''files'') }}' register: log_files_old changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_ownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83946-4 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_ownership - name: Ensure Log Files Are Owned By Appropriate User - Extract log files new format ansible.builtin.shell: 'set -o pipefail grep -ozP "action\s*\(\s*type\s*=\s*\"omfile\"[^\)]*\)" {{ item.1.path }} | \ grep -aoP "File\s*=\s*\"([/[:alnum:][:punct:]]*)\"\s*\)" | \ grep -oE "\"([/[:alnum:][:punct:]]*)\"" | \ tr -d "\""|| true ' loop: '{{ rsyslog_config_files.results | subelements(''files'') }}' register: log_files_new changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_ownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83946-4 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_ownership - name: Ensure Log Files Are Owned By Appropriate User - Sum all log files found ansible.builtin.set_fact: log_files: '{{ log_files_new.results | map(attribute=''stdout_lines'') | list | flatten | unique + log_files_old.results | map(attribute=''stdout_lines'') | list | flatten | unique }}' when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_ownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83946-4 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_ownership - name: Ensure Log Files Are Owned By Appropriate User -Setup log files attribute ansible.builtin.file: path: '{{ item }}' owner: '0' state: file loop: '{{ log_files | list | flatten | unique }}' failed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_ownership | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83946-4 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_ownership - name: Ensure System Log Files Have Correct Permissions - Set rsyslog logfile configuration facts ansible.builtin.set_fact: rsyslog_etc_config: /etc/rsyslog.conf when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_permissions | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83689-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_permissions - name: Ensure System Log Files Have Correct Permissions - Get IncludeConfig directive ansible.builtin.shell: 'set -o pipefail grep -e ''$IncludeConfig'' {{ rsyslog_etc_config }} | cut -d '' '' -f 2 || true ' register: rsyslog_old_inc changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_permissions | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83689-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_permissions - name: Ensure System Log Files Have Correct Permissions - Get include files directives ansible.builtin.shell: 'set -o pipefail awk ''/)/{f=0} /include\(/{f=1} f{nf=gensub("^(include\\(|\\s*)file=\"(\\S+)\".*","\\2",1); if($0!=nf){print nf}}'' {{ rsyslog_etc_config }} || true ' register: rsyslog_new_inc changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_permissions | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83689-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_permissions - name: Ensure System Log Files Have Correct Permissions - Aggregate rsyslog includes ansible.builtin.set_fact: include_config_output: '{{ rsyslog_old_inc.stdout_lines + rsyslog_new_inc.stdout_lines }}' when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_permissions | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83689-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_permissions - name: Ensure System Log Files Have Correct Permissions - List all config files ansible.builtin.find: paths: '{{ item | dirname }}' patterns: '{{ item | basename }}' hidden: false follow: true loop: '{{ include_config_output | list + [rsyslog_etc_config] }}' register: rsyslog_config_files failed_when: false changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_permissions | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83689-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_permissions - name: Ensure System Log Files Have Correct Permissions - Extract log files old format ansible.builtin.shell: 'set -o pipefail grep -oP ''^[^(\s|#|\$)]+[\s]+.*[\s]+-?(/+[^:;\s]+);*\.*$'' {{ item.1.path }} | \ awk ''{print $NF}'' | \ sed -e ''s/^-//'' || true ' loop: '{{ rsyslog_config_files.results | subelements(''files'') }}' register: log_files_old changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_permissions | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83689-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_permissions - name: Ensure System Log Files Have Correct Permissions - Extract log files new format ansible.builtin.shell: 'set -o pipefail grep -ozP "action\s*\(\s*type\s*=\s*\"omfile\"[^\)]*\)" {{ item.1.path }} | \ grep -aoP "File\s*=\s*\"([/[:alnum:][:punct:]]*)\"\s*\)" | \ grep -oE "\"([/[:alnum:][:punct:]]*)\"" | \ tr -d "\""|| true ' loop: '{{ rsyslog_config_files.results | subelements(''files'') }}' register: log_files_new changed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_permissions | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83689-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_permissions - name: Ensure System Log Files Have Correct Permissions - Sum all log files found ansible.builtin.set_fact: log_files: '{{ log_files_new.results | map(attribute=''stdout_lines'') | list | flatten | unique + log_files_old.results | map(attribute=''stdout_lines'') | list | flatten | unique }}' when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_permissions | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83689-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_permissions - name: Ensure System Log Files Have Correct Permissions -Setup log files attribute ansible.builtin.file: path: '{{ item }}' mode: '0640' state: file loop: '{{ log_files | list | flatten | unique }}' failed_when: false when: - configure_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_files_permissions | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83689-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.5.1 - PCI-DSS-Req-10.5.2 - PCI-DSSv4-10.3.1 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_permissions - name: Enable service systemd-journald block: - name: Gather the package facts package_facts: manager: auto - name: Enable service systemd-journald systemd: name: systemd-journald enabled: 'yes' state: started masked: 'no' when: - '"systemd" in ansible_facts.packages' when: - enable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - service_systemd_journald_enabled | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-85941-3 - NIST-800-53-SC-24 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_systemd-journald_enabled - name: Setting unquoted shell-style assignment of 'Compress' to 'yes' in '/etc/systemd/journald.conf' block: - name: Check for duplicate values lineinfile: path: /etc/systemd/journald.conf create: false regexp: ^\s*Compress= state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/systemd/journald.conf lineinfile: path: /etc/systemd/journald.conf create: false regexp: ^\s*Compress= state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/systemd/journald.conf lineinfile: path: /etc/systemd/journald.conf create: true regexp: ^\s*Compress= line: Compress=yes state: present insertbefore: ^# Compress validate: /usr/bin/bash -n %s when: - journald_compress | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-85931-4 - journald_compress - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Setting unquoted shell-style assignment of 'ForwardToSyslog' to 'yes' in '/etc/systemd/journald.conf' block: - name: Check for duplicate values lineinfile: path: /etc/systemd/journald.conf create: false regexp: ^\s*ForwardToSyslog= state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/systemd/journald.conf lineinfile: path: /etc/systemd/journald.conf create: false regexp: ^\s*ForwardToSyslog= state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/systemd/journald.conf lineinfile: path: /etc/systemd/journald.conf create: true regexp: ^\s*ForwardToSyslog= line: ForwardToSyslog=yes state: present insertbefore: ^# ForwardToSyslog validate: /usr/bin/bash -n %s when: - journald_forward_to_syslog | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-85996-7 - journald_forward_to_syslog - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Setting unquoted shell-style assignment of 'Storage' to 'persistent' in '/etc/systemd/journald.conf' block: - name: Check for duplicate values lineinfile: path: /etc/systemd/journald.conf create: false regexp: ^\s*Storage= state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/systemd/journald.conf lineinfile: path: /etc/systemd/journald.conf create: false regexp: ^\s*Storage= state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/systemd/journald.conf lineinfile: path: /etc/systemd/journald.conf create: true regexp: ^\s*Storage= line: Storage=persistent state: present insertbefore: ^# Storage validate: /usr/bin/bash -n %s when: - journald_storage | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86046-0 - journald_storage - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Disable systemd-journal-remote Socket - Collect systemd Socket Units Present in the System ansible.builtin.command: cmd: systemctl -q list-unit-files --type socket register: result_systemd_unit_files changed_when: false when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87606-0 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - socket_systemd-journal-remote_disabled - name: Disable systemd-journal-remote Socket - Ensure systemd-journal-remote.socket is Masked ansible.builtin.systemd: name: systemd-journal-remote.socket state: stopped enabled: false masked: true when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - result_systemd_unit_files.stdout_lines is search("systemd-journal-remote.socket") tags: - CCE-87606-0 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - socket_systemd-journal-remote_disabled - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server - Define Rsyslog Config Lines Regex in Legacy Syntax ansible.builtin.set_fact: rsyslog_listen_legacy_regex: ^\s*\$(((Input(TCP|RELP)|UDP)ServerRun)|ModLoad\s+(imtcp|imudp|imrelp)) when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_nolisten | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83995-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_nolisten - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server - Search for Legacy Config Lines in Rsyslog Main Config File ansible.builtin.find: paths: /etc pattern: rsyslog.conf contains: '{{ rsyslog_listen_legacy_regex }}' register: rsyslog_listen_legacy_main_file when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_nolisten | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83995-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_nolisten - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server - Search for Legacy Config Lines in Rsyslog Include Files ansible.builtin.find: paths: /etc/rsyslog.d/ pattern: '*.conf' contains: '{{ rsyslog_listen_legacy_regex }}' register: rsyslog_listen_legacy_include_files when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_nolisten | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83995-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_nolisten - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server - Assemble List of Config Files With Listen Lines in Legacy Syntax ansible.builtin.set_fact: rsyslog_legacy_remote_listen_files: '{{ rsyslog_listen_legacy_main_file.files | map(attribute=''path'') | list + rsyslog_listen_legacy_include_files.files | map(attribute=''path'') | list }}' when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_nolisten | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83995-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_nolisten - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server - Comment Listen Config Lines Wherever Defined Using Legacy Syntax ansible.builtin.replace: path: '{{ item }}' regexp: '{{ rsyslog_listen_legacy_regex }}' replace: '# \1' loop: '{{ rsyslog_legacy_remote_listen_files }}' register: rsyslog_listen_legacy_comment when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_nolisten | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - rsyslog_legacy_remote_listen_files | length > 0 tags: - CCE-83995-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_nolisten - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server - Define Rsyslog Config Lines Regex in RainerScript Syntax ansible.builtin.set_fact: rsyslog_listen_rainer_regex: ^\s*(module|input)\((load|type)="(imtcp|imudp)".*$ when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_nolisten | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83995-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_nolisten - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server - Search for RainerScript Config Lines in Rsyslog Main Config File ansible.builtin.find: paths: /etc pattern: rsyslog.conf contains: '{{ rsyslog_listen_rainer_regex }}' register: rsyslog_rainer_remote_main_file when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_nolisten | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83995-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_nolisten - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server - Search for RainerScript Config Lines in Rsyslog Include Files ansible.builtin.find: paths: /etc/rsyslog.d/ pattern: '*.conf' contains: '{{ rsyslog_listen_rainer_regex }}' register: rsyslog_rainer_remote_include_files when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_nolisten | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83995-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_nolisten - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server - Assemble List of Config Files With Listen Lines in RainerScript ansible.builtin.set_fact: rsyslog_rainer_remote_listen_files: '{{ rsyslog_rainer_remote_main_file.files | map(attribute=''path'') | list + rsyslog_rainer_remote_include_files.files | map(attribute=''path'') | list }}' when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_nolisten | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83995-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_nolisten - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server - Comment Listen Config Lines Wherever Defined Using RainerScript ansible.builtin.replace: path: '{{ item }}' regexp: '{{ rsyslog_listen_rainer_regex }}' replace: '# \1' loop: '{{ rsyslog_rainer_remote_listen_files }}' register: rsyslog_listen_rainer_comment when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_nolisten | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - rsyslog_rainer_remote_listen_files | length > 0 tags: - CCE-83995-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_nolisten - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server - Restart Rsyslog if Any Line Were Commented Out ansible.builtin.service: name: rsyslog state: restarted when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - rsyslog_nolisten | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - rsyslog_listen_legacy_comment is changed or rsyslog_listen_rainer_comment is changed tags: - CCE-83995-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_nolisten - name: Gather the package facts package_facts: manager: auto tags: - CCE-90833-5 - NIST-800-171-3.1.3 - NIST-800-171-3.4.7 - NIST-800-53-AC-4 - NIST-800-53-CA-3(5) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(21) - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_firewalld_enabled when: - enable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - service_firewalld_enabled | bool - name: Enable service firewalld block: - name: Gather the package facts package_facts: manager: auto - name: Enable service firewalld systemd: name: firewalld enabled: 'yes' state: started masked: 'no' when: - '"firewalld" in ansible_facts.packages' when: - enable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - service_firewalld_enabled | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"firewalld" in ansible_facts.packages' tags: - CCE-90833-5 - NIST-800-171-3.1.3 - NIST-800-171-3.4.7 - NIST-800-53-AC-4 - NIST-800-53-CA-3(5) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(21) - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_firewalld_enabled - name: Configure Firewalld to Restrict Loopback Traffic - Ensure firewalld Package is Installed ansible.builtin.package: name: '{{ item }}' state: present with_items: - firewalld when: - configure_strategy | bool - firewalld_loopback_traffic_restricted | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86137-7 - configure_strategy - firewalld_loopback_traffic_restricted - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure Firewalld to Restrict Loopback Traffic - Collect Facts About System Services ansible.builtin.service_facts: null register: result_services_states when: - configure_strategy | bool - firewalld_loopback_traffic_restricted | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86137-7 - configure_strategy - firewalld_loopback_traffic_restricted - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure Firewalld to Restrict Loopback Traffic - Remediation is Applicable if firewalld Service is Running block: - name: Configure Firewalld to Restrict Loopback Traffic - Ensure firewalld trusted Zone Restricts IPv4 Loopback Traffic ansible.builtin.command: cmd: firewall-cmd --permanent --zone=trusted --add-rich-rule='rule family=ipv4 source address="127.0.0.1" destination not address="127.0.0.1" drop' register: result_trusted_ipv4_restriction changed_when: - '''ALREADY_ENABLED'' not in result_trusted_ipv4_restriction.stderr' - name: Configure Firewalld to Restrict Loopback Traffic - Ensure firewalld trusted Zone Restricts IPv6 Loopback Traffic ansible.builtin.command: cmd: firewall-cmd --permanent --zone=trusted --add-rich-rule='rule family=ipv6 source address="::1" destination not address="::1" drop' register: result_trusted_ipv6_restriction changed_when: - '''ALREADY_ENABLED'' not in result_trusted_ipv6_restriction.stderr' - name: Configure Firewalld to Restrict Loopback Traffic - Ensure firewalld Changes are Applied ansible.builtin.service: name: firewalld state: reloaded when: - result_trusted_ipv4_restriction is changed or result_trusted_ipv6_restriction is changed when: - configure_strategy | bool - firewalld_loopback_traffic_restricted | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_facts.services['firewalld.service'].state == 'running' tags: - CCE-86137-7 - configure_strategy - firewalld_loopback_traffic_restricted - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure Firewalld to Restrict Loopback Traffic - Informative Message Based on Service State ansible.builtin.assert: that: - ansible_facts.services['firewalld.service'].state == 'running' fail_msg: - firewalld service is not active. Remediation aborted! - This remediation could not be applied because it depends on firewalld service running. - The service is not started by this remediation in order to prevent connection issues. success_msg: - Configure Firewalld to Restrict Loopback Traffic remediation successfully executed when: - configure_strategy | bool - firewalld_loopback_traffic_restricted | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86137-7 - configure_strategy - firewalld_loopback_traffic_restricted - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure Firewalld to Trust Loopback Traffic - Ensure firewalld Package is Installed ansible.builtin.package: name: '{{ item }}' state: present with_items: - firewalld when: - configure_strategy | bool - firewalld_loopback_traffic_trusted | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86116-1 - configure_strategy - firewalld_loopback_traffic_trusted - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure Firewalld to Trust Loopback Traffic - Collect Facts About System Services ansible.builtin.service_facts: null register: result_services_states when: - configure_strategy | bool - firewalld_loopback_traffic_trusted | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86116-1 - configure_strategy - firewalld_loopback_traffic_trusted - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure Firewalld to Trust Loopback Traffic - Remediation is Applicable if firewalld Service is Running block: - name: Configure Firewalld to Trust Loopback Traffic - Ensure firewalld trusted Zone Includes lo Interface ansible.builtin.command: cmd: firewall-cmd --permanent --zone=trusted --add-interface=lo register: result_lo_interface_assignment changed_when: - '''ALREADY_ENABLED'' not in result_lo_interface_assignment.stderr' - name: Configure Firewalld to Trust Loopback Traffic - Ensure firewalld Changes are Applied ansible.builtin.service: name: firewalld state: reloaded when: - result_lo_interface_assignment is changed when: - configure_strategy | bool - firewalld_loopback_traffic_trusted | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_facts.services['firewalld.service'].state == 'running' tags: - CCE-86116-1 - configure_strategy - firewalld_loopback_traffic_trusted - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure Firewalld to Trust Loopback Traffic - Informative Message Based on Service State ansible.builtin.assert: that: - ansible_facts.services['firewalld.service'].state == 'running' fail_msg: - firewalld service is not active. Remediation aborted! - This remediation could not be applied because it depends on firewalld service running. - The service is not started by this remediation in order to prevent connection issues. success_msg: - Configure Firewalld to Trust Loopback Traffic remediation successfully executed when: - configure_strategy | bool - firewalld_loopback_traffic_trusted | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86116-1 - configure_strategy - firewalld_loopback_traffic_trusted - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.all.accept_ra.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_all_accept_ra | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84120-5 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_all_accept_ra - name: Comment out any occurrences of net.ipv6.conf.all.accept_ra from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv6.conf.all.accept_ra replace: '#net.ipv6.conf.all.accept_ra' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_all_accept_ra | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84120-5 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_all_accept_ra - name: Ensure sysctl net.ipv6.conf.all.accept_ra is set sysctl: name: net.ipv6.conf.all.accept_ra value: '{{ sysctl_net_ipv6_conf_all_accept_ra_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_all_accept_ra | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84120-5 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_all_accept_ra - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.all.accept_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_all_accept_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84125-4 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_all_accept_redirects - name: Comment out any occurrences of net.ipv6.conf.all.accept_redirects from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv6.conf.all.accept_redirects replace: '#net.ipv6.conf.all.accept_redirects' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_all_accept_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84125-4 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_all_accept_redirects - name: Ensure sysctl net.ipv6.conf.all.accept_redirects is set sysctl: name: net.ipv6.conf.all.accept_redirects value: '{{ sysctl_net_ipv6_conf_all_accept_redirects_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_all_accept_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84125-4 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_all_accept_redirects - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.all.accept_source_route.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_all_accept_source_route | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84131-2 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_all_accept_source_route - name: Comment out any occurrences of net.ipv6.conf.all.accept_source_route from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv6.conf.all.accept_source_route replace: '#net.ipv6.conf.all.accept_source_route' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_all_accept_source_route | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84131-2 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_all_accept_source_route - name: Ensure sysctl net.ipv6.conf.all.accept_source_route is set sysctl: name: net.ipv6.conf.all.accept_source_route value: '{{ sysctl_net_ipv6_conf_all_accept_source_route_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_all_accept_source_route | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84131-2 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_all_accept_source_route - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.all.forwarding.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_all_forwarding | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84114-8 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_all_forwarding - name: Comment out any occurrences of net.ipv6.conf.all.forwarding from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv6.conf.all.forwarding replace: '#net.ipv6.conf.all.forwarding' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_all_forwarding | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84114-8 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_all_forwarding - name: Ensure sysctl net.ipv6.conf.all.forwarding is set sysctl: name: net.ipv6.conf.all.forwarding value: '{{ sysctl_net_ipv6_conf_all_forwarding_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_all_forwarding | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84114-8 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_all_forwarding - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.default.accept_ra.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_default_accept_ra | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84124-7 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_default_accept_ra - name: Comment out any occurrences of net.ipv6.conf.default.accept_ra from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv6.conf.default.accept_ra replace: '#net.ipv6.conf.default.accept_ra' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_default_accept_ra | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84124-7 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_default_accept_ra - name: Ensure sysctl net.ipv6.conf.default.accept_ra is set sysctl: name: net.ipv6.conf.default.accept_ra value: '{{ sysctl_net_ipv6_conf_default_accept_ra_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_default_accept_ra | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84124-7 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_default_accept_ra - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.default.accept_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_default_accept_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84113-0 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_default_accept_redirects - name: Comment out any occurrences of net.ipv6.conf.default.accept_redirects from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv6.conf.default.accept_redirects replace: '#net.ipv6.conf.default.accept_redirects' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_default_accept_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84113-0 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_default_accept_redirects - name: Ensure sysctl net.ipv6.conf.default.accept_redirects is set sysctl: name: net.ipv6.conf.default.accept_redirects value: '{{ sysctl_net_ipv6_conf_default_accept_redirects_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_default_accept_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84113-0 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_default_accept_redirects - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.default.accept_source_route.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_default_accept_source_route | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84130-4 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_default_accept_source_route - name: Comment out any occurrences of net.ipv6.conf.default.accept_source_route from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv6.conf.default.accept_source_route replace: '#net.ipv6.conf.default.accept_source_route' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_default_accept_source_route | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84130-4 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_default_accept_source_route - name: Ensure sysctl net.ipv6.conf.default.accept_source_route is set sysctl: name: net.ipv6.conf.default.accept_source_route value: '{{ sysctl_net_ipv6_conf_default_accept_source_route_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv6_conf_default_accept_source_route | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84130-4 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_default_accept_source_route - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.all.accept_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_accept_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84011-6 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_accept_redirects - name: Comment out any occurrences of net.ipv4.conf.all.accept_redirects from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.conf.all.accept_redirects replace: '#net.ipv4.conf.all.accept_redirects' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_accept_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84011-6 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_accept_redirects - name: Ensure sysctl net.ipv4.conf.all.accept_redirects is set sysctl: name: net.ipv4.conf.all.accept_redirects value: '{{ sysctl_net_ipv4_conf_all_accept_redirects_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_accept_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84011-6 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_accept_redirects - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.all.accept_source_route.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_accept_source_route | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84001-7 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_accept_source_route - name: Comment out any occurrences of net.ipv4.conf.all.accept_source_route from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.conf.all.accept_source_route replace: '#net.ipv4.conf.all.accept_source_route' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_accept_source_route | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84001-7 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_accept_source_route - name: Ensure sysctl net.ipv4.conf.all.accept_source_route is set sysctl: name: net.ipv4.conf.all.accept_source_route value: '{{ sysctl_net_ipv4_conf_all_accept_source_route_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_accept_source_route | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84001-7 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_accept_source_route - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.all.log_martians.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_log_martians | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84000-9 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5(3)(a) - disable_strategy - low_complexity - medium_disruption - reboot_required - sysctl_net_ipv4_conf_all_log_martians - unknown_severity - name: Comment out any occurrences of net.ipv4.conf.all.log_martians from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.conf.all.log_martians replace: '#net.ipv4.conf.all.log_martians' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_log_martians | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84000-9 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5(3)(a) - disable_strategy - low_complexity - medium_disruption - reboot_required - sysctl_net_ipv4_conf_all_log_martians - unknown_severity - name: Ensure sysctl net.ipv4.conf.all.log_martians is set sysctl: name: net.ipv4.conf.all.log_martians value: '{{ sysctl_net_ipv4_conf_all_log_martians_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_log_martians | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84000-9 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5(3)(a) - disable_strategy - low_complexity - medium_disruption - reboot_required - sysctl_net_ipv4_conf_all_log_martians - unknown_severity - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.all.rp_filter.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_rp_filter | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84008-2 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_rp_filter - name: Comment out any occurrences of net.ipv4.conf.all.rp_filter from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.conf.all.rp_filter replace: '#net.ipv4.conf.all.rp_filter' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_rp_filter | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84008-2 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_rp_filter - name: Ensure sysctl net.ipv4.conf.all.rp_filter is set sysctl: name: net.ipv4.conf.all.rp_filter value: '{{ sysctl_net_ipv4_conf_all_rp_filter_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_rp_filter | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84008-2 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_rp_filter - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.all.secure_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_secure_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84016-5 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_secure_redirects - name: Comment out any occurrences of net.ipv4.conf.all.secure_redirects from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.conf.all.secure_redirects replace: '#net.ipv4.conf.all.secure_redirects' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_secure_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84016-5 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_secure_redirects - name: Ensure sysctl net.ipv4.conf.all.secure_redirects is set sysctl: name: net.ipv4.conf.all.secure_redirects value: '{{ sysctl_net_ipv4_conf_all_secure_redirects_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_secure_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84016-5 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_secure_redirects - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.default.accept_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_accept_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84003-3 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_accept_redirects - name: Comment out any occurrences of net.ipv4.conf.default.accept_redirects from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.conf.default.accept_redirects replace: '#net.ipv4.conf.default.accept_redirects' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_accept_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84003-3 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_accept_redirects - name: Ensure sysctl net.ipv4.conf.default.accept_redirects is set sysctl: name: net.ipv4.conf.default.accept_redirects value: '{{ sysctl_net_ipv4_conf_default_accept_redirects_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_accept_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84003-3 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_accept_redirects - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.default.accept_source_route.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_accept_source_route | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84007-4 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_accept_source_route - name: Comment out any occurrences of net.ipv4.conf.default.accept_source_route from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.conf.default.accept_source_route replace: '#net.ipv4.conf.default.accept_source_route' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_accept_source_route | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84007-4 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_accept_source_route - name: Ensure sysctl net.ipv4.conf.default.accept_source_route is set sysctl: name: net.ipv4.conf.default.accept_source_route value: '{{ sysctl_net_ipv4_conf_default_accept_source_route_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_accept_source_route | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84007-4 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_accept_source_route - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.default.log_martians.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_log_martians | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84014-0 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5(3)(a) - disable_strategy - low_complexity - medium_disruption - reboot_required - sysctl_net_ipv4_conf_default_log_martians - unknown_severity - name: Comment out any occurrences of net.ipv4.conf.default.log_martians from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.conf.default.log_martians replace: '#net.ipv4.conf.default.log_martians' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_log_martians | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84014-0 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5(3)(a) - disable_strategy - low_complexity - medium_disruption - reboot_required - sysctl_net_ipv4_conf_default_log_martians - unknown_severity - name: Ensure sysctl net.ipv4.conf.default.log_martians is set sysctl: name: net.ipv4.conf.default.log_martians value: '{{ sysctl_net_ipv4_conf_default_log_martians_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_log_martians | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84014-0 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5(3)(a) - disable_strategy - low_complexity - medium_disruption - reboot_required - sysctl_net_ipv4_conf_default_log_martians - unknown_severity - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.default.rp_filter.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_rp_filter | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84009-0 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_rp_filter - name: Comment out any occurrences of net.ipv4.conf.default.rp_filter from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.conf.default.rp_filter replace: '#net.ipv4.conf.default.rp_filter' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_rp_filter | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84009-0 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_rp_filter - name: Ensure sysctl net.ipv4.conf.default.rp_filter is set sysctl: name: net.ipv4.conf.default.rp_filter value: '{{ sysctl_net_ipv4_conf_default_rp_filter_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_rp_filter | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84009-0 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_rp_filter - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.default.secure_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_secure_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84019-9 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_secure_redirects - name: Comment out any occurrences of net.ipv4.conf.default.secure_redirects from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.conf.default.secure_redirects replace: '#net.ipv4.conf.default.secure_redirects' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_secure_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84019-9 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_secure_redirects - name: Ensure sysctl net.ipv4.conf.default.secure_redirects is set sysctl: name: net.ipv4.conf.default.secure_redirects value: '{{ sysctl_net_ipv4_conf_default_secure_redirects_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_secure_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84019-9 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_secure_redirects - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.icmp_echo_ignore_broadcasts.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_icmp_echo_ignore_broadcasts | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84004-1 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_icmp_echo_ignore_broadcasts - name: Comment out any occurrences of net.ipv4.icmp_echo_ignore_broadcasts from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.icmp_echo_ignore_broadcasts replace: '#net.ipv4.icmp_echo_ignore_broadcasts' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_icmp_echo_ignore_broadcasts | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84004-1 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_icmp_echo_ignore_broadcasts - name: Ensure sysctl net.ipv4.icmp_echo_ignore_broadcasts is set sysctl: name: net.ipv4.icmp_echo_ignore_broadcasts value: '{{ sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_icmp_echo_ignore_broadcasts | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84004-1 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_icmp_echo_ignore_broadcasts - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.icmp_ignore_bogus_error_responses.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - reboot_required | bool - sysctl_net_ipv4_icmp_ignore_bogus_error_responses | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84015-7 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - reboot_required - sysctl_net_ipv4_icmp_ignore_bogus_error_responses - unknown_severity - name: Comment out any occurrences of net.ipv4.icmp_ignore_bogus_error_responses from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.icmp_ignore_bogus_error_responses replace: '#net.ipv4.icmp_ignore_bogus_error_responses' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - reboot_required | bool - sysctl_net_ipv4_icmp_ignore_bogus_error_responses | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84015-7 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - reboot_required - sysctl_net_ipv4_icmp_ignore_bogus_error_responses - unknown_severity - name: Ensure sysctl net.ipv4.icmp_ignore_bogus_error_responses is set sysctl: name: net.ipv4.icmp_ignore_bogus_error_responses value: '{{ sysctl_net_ipv4_icmp_ignore_bogus_error_responses_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - reboot_required | bool - sysctl_net_ipv4_icmp_ignore_bogus_error_responses | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84015-7 - NIST-800-171-3.1.20 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - PCI-DSS-Req-1.4.3 - disable_strategy - low_complexity - medium_disruption - reboot_required - sysctl_net_ipv4_icmp_ignore_bogus_error_responses - unknown_severity - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.tcp_syncookies.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_tcp_syncookies | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84006-6 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5(1) - NIST-800-53-SC-5(2) - NIST-800-53-SC-5(3)(a) - PCI-DSS-Req-1.4.1 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_tcp_syncookies - name: Comment out any occurrences of net.ipv4.tcp_syncookies from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.tcp_syncookies replace: '#net.ipv4.tcp_syncookies' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_tcp_syncookies | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84006-6 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5(1) - NIST-800-53-SC-5(2) - NIST-800-53-SC-5(3)(a) - PCI-DSS-Req-1.4.1 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_tcp_syncookies - name: Ensure sysctl net.ipv4.tcp_syncookies is set sysctl: name: net.ipv4.tcp_syncookies value: '{{ sysctl_net_ipv4_tcp_syncookies_value }}' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_tcp_syncookies | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84006-6 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5(1) - NIST-800-53-SC-5(2) - NIST-800-53-SC-5(3)(a) - PCI-DSS-Req-1.4.1 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_tcp_syncookies - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.all.send_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_send_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83997-7 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - PCI-DSSv4-1.4.2 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_send_redirects - name: Comment out any occurrences of net.ipv4.conf.all.send_redirects from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.conf.all.send_redirects replace: '#net.ipv4.conf.all.send_redirects' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_send_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83997-7 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - PCI-DSSv4-1.4.2 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_send_redirects - name: Ensure sysctl net.ipv4.conf.all.send_redirects is set to 0 sysctl: name: net.ipv4.conf.all.send_redirects value: '0' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_all_send_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83997-7 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - PCI-DSSv4-1.4.2 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_send_redirects - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.default.send_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_send_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83999-3 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_send_redirects - name: Comment out any occurrences of net.ipv4.conf.default.send_redirects from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.conf.default.send_redirects replace: '#net.ipv4.conf.default.send_redirects' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_send_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83999-3 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_send_redirects - name: Ensure sysctl net.ipv4.conf.default.send_redirects is set to 0 sysctl: name: net.ipv4.conf.default.send_redirects value: '0' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_conf_default_send_redirects | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83999-3 - CJIS-5.10.1.1 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_send_redirects - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*net.ipv4.ip_forward.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_ip_forward | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83998-5 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - PCI-DSS-Req-1.3.1 - PCI-DSS-Req-1.3.2 - PCI-DSSv4-1.4.2 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_ip_forward - name: Comment out any occurrences of net.ipv4.ip_forward from config files replace: path: '{{ item.path }}' regexp: ^[\s]*net.ipv4.ip_forward replace: '#net.ipv4.ip_forward' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_ip_forward | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83998-5 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - PCI-DSS-Req-1.3.1 - PCI-DSS-Req-1.3.2 - PCI-DSSv4-1.4.2 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_ip_forward - name: Ensure sysctl net.ipv4.ip_forward is set to 0 sysctl: name: net.ipv4.ip_forward value: '0' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_net_ipv4_ip_forward | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83998-5 - NIST-800-171-3.1.20 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-SC-5 - NIST-800-53-SC-7(a) - PCI-DSS-Req-1.3.1 - PCI-DSS-Req-1.3.2 - PCI-DSSv4-1.4.2 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_ip_forward - name: Ensure nftables is installed package: name: nftables state: present when: - enable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - package_nftables_installed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86378-7 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_nftables_installed - name: Block Disable service nftables block: - name: Disable service nftables block: - name: Disable service nftables systemd: name: nftables.service enabled: 'no' state: stopped masked: 'yes' rescue: - name: Intentionally ignored previous 'Disable service nftables' failure, service was already disabled meta: noop when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - service_nftables_disabled | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88429-6 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_nftables_disabled - name: Unit Socket Exists - nftables.socket command: systemctl -q list-unit-files nftables.socket register: socket_file_exists changed_when: false failed_when: socket_file_exists.rc not in [0, 1] check_mode: false when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - service_nftables_disabled | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-88429-6 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_nftables_disabled - name: Disable socket nftables systemd: name: nftables.socket enabled: 'no' state: stopped masked: 'yes' when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - service_nftables_disabled | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - socket_file_exists.stdout_lines is search("nftables.socket",multiline=True) tags: - CCE-88429-6 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_nftables_disabled - name: Gather the package facts package_facts: manager: auto tags: - CCE-86163-3 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - set_nftables_table when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - set_nftables_table | bool - name: Collect Existing Nftables ansible.builtin.command: nft list tables register: existing_nftables when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - set_nftables_table | bool - '"nftables" in ansible_facts.packages' tags: - CCE-86163-3 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - set_nftables_table - name: Set Nftable Table ansible.builtin.command: nft create table {{ var_nftables_family }} {{ var_nftables_table }} when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - set_nftables_table | bool - '"nftables" in ansible_facts.packages' - existing_nftables.stdout_lines | length == 0 tags: - CCE-86163-3 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - set_nftables_table - name: Ensure kernel module 'tipc' is disabled lineinfile: create: true dest: /etc/modprobe.d/tipc.conf regexp: install\s+tipc line: install tipc /bin/true when: - disable_strategy | bool - kernel_module_tipc_disabled | bool - low_complexity | bool - low_severity | bool - medium_disruption | bool - reboot_required | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84065-2 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - kernel_module_tipc_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Ensure kernel module 'tipc' is blacklisted lineinfile: create: true dest: /etc/modprobe.d/tipc.conf regexp: ^blacklist tipc$ line: blacklist tipc when: - disable_strategy | bool - kernel_module_tipc_disabled | bool - low_complexity | bool - low_severity | bool - medium_disruption | bool - reboot_required | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84065-2 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - kernel_module_tipc_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Gather the package facts package_facts: manager: auto tags: - CCE-84066-0 - NIST-800-171-3.1.16 - NIST-800-53-AC-18(3) - NIST-800-53-AC-18(a) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - PCI-DSS-Req-1.3.3 - PCI-DSSv4-1.4.3 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - wireless_disable_interfaces when: - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - wireless_disable_interfaces | bool - name: Ensure NetworkManager is installed ansible.builtin.package: name: '{{ item }}' state: present with_items: - NetworkManager tags: - CCE-84066-0 - NIST-800-171-3.1.16 - NIST-800-53-AC-18(3) - NIST-800-53-AC-18(a) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - PCI-DSS-Req-1.3.3 - PCI-DSSv4-1.4.3 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - wireless_disable_interfaces when: - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - wireless_disable_interfaces | bool - name: Deactivate Wireless Network Interfaces command: nmcli radio wifi off when: - low_complexity | bool - medium_disruption | bool - medium_severity | bool - no_reboot_needed | bool - unknown_strategy | bool - wireless_disable_interfaces | bool - '''NetworkManager'' in ansible_facts.packages' tags: - CCE-84066-0 - NIST-800-171-3.1.16 - NIST-800-53-AC-18(3) - NIST-800-53-AC-18(a) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - PCI-DSS-Req-1.3.3 - PCI-DSSv4-1.4.3 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - wireless_disable_interfaces - name: Get all world-writable directories with no sticky bits set shell: 'set -o pipefail df --local -P | awk ''{if (NR!=1) print $6}'' | xargs -I ''{}'' find ''{}'' -xdev -type d \( -perm -0002 -a ! -perm -1000 \) 2>/dev/null ' register: dir_output tags: - CCE-83895-3 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - dir_perms_world_writable_sticky_bits - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - dir_perms_world_writable_sticky_bits | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Ensure sticky bit is set file: path: '{{ item }}' mode: a+t with_items: - '{{ dir_output.stdout_lines }}' tags: - CCE-83895-3 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - dir_perms_world_writable_sticky_bits - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - dir_perms_world_writable_sticky_bits | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Test for existence /etc/group- stat: path: /etc/group- register: file_exists tags: - CCE-83928-2 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_backup_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_backup_etc_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /etc/group- file: path: /etc/group- group: '0' when: - configure_strategy | bool - file_groupowner_backup_etc_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83928-2 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_backup_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/gshadow- stat: path: /etc/gshadow- register: file_exists tags: - CCE-83951-4 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_backup_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_backup_etc_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /etc/gshadow- file: path: /etc/gshadow- group: '0' when: - configure_strategy | bool - file_groupowner_backup_etc_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83951-4 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_backup_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/passwd- stat: path: /etc/passwd- register: file_exists tags: - CCE-83933-2 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_backup_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_backup_etc_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /etc/passwd- file: path: /etc/passwd- group: '0' when: - configure_strategy | bool - file_groupowner_backup_etc_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83933-2 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_backup_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/shadow- stat: path: /etc/shadow- register: file_exists tags: - CCE-83938-1 - PCI-DSS-Req-8.7 - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_backup_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_backup_etc_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /etc/shadow- file: path: /etc/shadow- group: '0' when: - configure_strategy | bool - file_groupowner_backup_etc_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83938-1 - PCI-DSS-Req-8.7 - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_backup_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/group stat: path: /etc/group register: file_exists tags: - CCE-83945-6 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_etc_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /etc/group file: path: /etc/group group: '0' when: - configure_strategy | bool - file_groupowner_etc_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83945-6 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/gshadow stat: path: /etc/gshadow register: file_exists tags: - CCE-83948-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_groupowner_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_etc_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /etc/gshadow file: path: /etc/gshadow group: '0' when: - configure_strategy | bool - file_groupowner_etc_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83948-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_groupowner_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/passwd stat: path: /etc/passwd register: file_exists tags: - CCE-83950-6 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_etc_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /etc/passwd file: path: /etc/passwd group: '0' when: - configure_strategy | bool - file_groupowner_etc_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83950-6 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/shadow stat: path: /etc/shadow register: file_exists tags: - CCE-83930-8 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupowner_etc_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /etc/shadow file: path: /etc/shadow group: '0' when: - configure_strategy | bool - file_groupowner_etc_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83930-8 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_groupowner_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/group- stat: path: /etc/group- register: file_exists tags: - CCE-83944-9 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_backup_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_backup_etc_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /etc/group- file: path: /etc/group- owner: '0' when: - configure_strategy | bool - file_owner_backup_etc_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83944-9 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_backup_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/gshadow- stat: path: /etc/gshadow- register: file_exists tags: - CCE-83929-0 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_backup_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_backup_etc_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /etc/gshadow- file: path: /etc/gshadow- owner: '0' when: - configure_strategy | bool - file_owner_backup_etc_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83929-0 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_backup_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/passwd- stat: path: /etc/passwd- register: file_exists tags: - CCE-83947-2 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_backup_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_backup_etc_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /etc/passwd- file: path: /etc/passwd- owner: '0' when: - configure_strategy | bool - file_owner_backup_etc_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83947-2 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_backup_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/shadow- stat: path: /etc/shadow- register: file_exists tags: - CCE-83949-8 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_backup_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_backup_etc_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /etc/shadow- file: path: /etc/shadow- owner: '0' when: - configure_strategy | bool - file_owner_backup_etc_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83949-8 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_backup_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/group stat: path: /etc/group register: file_exists tags: - CCE-83925-8 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_etc_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /etc/group file: path: /etc/group owner: '0' when: - configure_strategy | bool - file_owner_etc_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83925-8 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/gshadow stat: path: /etc/gshadow register: file_exists tags: - CCE-83924-1 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_owner_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_etc_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /etc/gshadow file: path: /etc/gshadow owner: '0' when: - configure_strategy | bool - file_owner_etc_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83924-1 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_owner_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/passwd stat: path: /etc/passwd register: file_exists tags: - CCE-83943-1 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_etc_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /etc/passwd file: path: /etc/passwd owner: '0' when: - configure_strategy | bool - file_owner_etc_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83943-1 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/shadow stat: path: /etc/shadow register: file_exists tags: - CCE-83926-6 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_owner_etc_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /etc/shadow file: path: /etc/shadow owner: '0' when: - configure_strategy | bool - file_owner_etc_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83926-6 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_owner_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/group- stat: path: /etc/group- register: file_exists tags: - CCE-83939-9 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_permissions_backup_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_backup_etc_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-xs,g-xws,o-xwt on /etc/group- file: path: /etc/group- mode: u-xs,g-xws,o-xwt when: - configure_strategy | bool - file_permissions_backup_etc_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83939-9 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_permissions_backup_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/gshadow- stat: path: /etc/gshadow- register: file_exists tags: - CCE-83942-3 - NIST-800-53-AC-6 (1) - configure_strategy - file_permissions_backup_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_backup_etc_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/gshadow- file: path: /etc/gshadow- mode: u-xwrs,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_backup_etc_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83942-3 - NIST-800-53-AC-6 (1) - configure_strategy - file_permissions_backup_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/passwd- stat: path: /etc/passwd- register: file_exists tags: - CCE-83940-7 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_permissions_backup_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_backup_etc_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-xs,g-xws,o-xwt on /etc/passwd- file: path: /etc/passwd- mode: u-xs,g-xws,o-xwt when: - configure_strategy | bool - file_permissions_backup_etc_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83940-7 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_permissions_backup_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/shadow- stat: path: /etc/shadow- register: file_exists tags: - CCE-83935-7 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_permissions_backup_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_backup_etc_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/shadow- file: path: /etc/shadow- mode: u-xwrs,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_backup_etc_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83935-7 - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_permissions_backup_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/group stat: path: /etc/group register: file_exists tags: - CCE-83934-0 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_permissions_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_etc_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-xs,g-xws,o-xwt on /etc/group file: path: /etc/group mode: u-xs,g-xws,o-xwt when: - configure_strategy | bool - file_permissions_etc_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83934-0 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_permissions_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/gshadow stat: path: /etc/gshadow register: file_exists tags: - CCE-83921-7 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_etc_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/gshadow file: path: /etc/gshadow mode: u-xwrs,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_etc_gshadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83921-7 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/passwd stat: path: /etc/passwd register: file_exists tags: - CCE-83931-6 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_permissions_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_etc_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-xs,g-xws,o-xwt on /etc/passwd file: path: /etc/passwd mode: u-xs,g-xws,o-xwt when: - configure_strategy | bool - file_permissions_etc_passwd | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83931-6 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_permissions_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/shadow stat: path: /etc/shadow register: file_exists tags: - CCE-83941-5 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_permissions_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_etc_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/shadow file: path: /etc/shadow mode: u-xwrs,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_etc_shadow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-83941-5 - CJIS-5.5.2.2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.7.c - PCI-DSSv4-7.2.6 - configure_strategy - file_permissions_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/auditctl stat: path: /sbin/auditctl register: file_exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /sbin/auditctl file: path: /sbin/auditctl group: '0' when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/aureport stat: path: /sbin/aureport register: file_exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /sbin/aureport file: path: /sbin/aureport group: '0' when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/ausearch stat: path: /sbin/ausearch register: file_exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /sbin/ausearch file: path: /sbin/ausearch group: '0' when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/autrace stat: path: /sbin/autrace register: file_exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /sbin/autrace file: path: /sbin/autrace group: '0' when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/auditd stat: path: /sbin/auditd register: file_exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /sbin/auditd file: path: /sbin/auditd group: '0' when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/audispd stat: path: /sbin/audispd register: file_exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /sbin/audispd file: path: /sbin/audispd group: '0' when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/augenrules stat: path: /sbin/augenrules register: file_exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure group owner 0 on /sbin/augenrules file: path: /sbin/augenrules group: '0' when: - configure_strategy | bool - file_groupownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86457-9 - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/auditctl stat: path: /sbin/auditctl register: file_exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /sbin/auditctl file: path: /sbin/auditctl owner: '0' when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/aureport stat: path: /sbin/aureport register: file_exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /sbin/aureport file: path: /sbin/aureport owner: '0' when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/ausearch stat: path: /sbin/ausearch register: file_exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /sbin/ausearch file: path: /sbin/ausearch owner: '0' when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/autrace stat: path: /sbin/autrace register: file_exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /sbin/autrace file: path: /sbin/autrace owner: '0' when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/auditd stat: path: /sbin/auditd register: file_exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /sbin/auditd file: path: /sbin/auditd owner: '0' when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/audispd stat: path: /sbin/audispd register: file_exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /sbin/audispd file: path: /sbin/audispd owner: '0' when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/augenrules stat: path: /sbin/augenrules register: file_exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure owner 0 on /sbin/augenrules file: path: /sbin/augenrules owner: '0' when: - configure_strategy | bool - file_ownership_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86454-6 - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/auditctl stat: path: /sbin/auditctl register: file_exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-s,g-ws,o-wt on /sbin/auditctl file: path: /sbin/auditctl mode: u-s,g-ws,o-wt when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/aureport stat: path: /sbin/aureport register: file_exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-s,g-ws,o-wt on /sbin/aureport file: path: /sbin/aureport mode: u-s,g-ws,o-wt when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/ausearch stat: path: /sbin/ausearch register: file_exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-s,g-ws,o-wt on /sbin/ausearch file: path: /sbin/ausearch mode: u-s,g-ws,o-wt when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/autrace stat: path: /sbin/autrace register: file_exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-s,g-ws,o-wt on /sbin/autrace file: path: /sbin/autrace mode: u-s,g-ws,o-wt when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/auditd stat: path: /sbin/auditd register: file_exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-s,g-ws,o-wt on /sbin/auditd file: path: /sbin/auditd mode: u-s,g-ws,o-wt when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/audispd stat: path: /sbin/audispd register: file_exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-s,g-ws,o-wt on /sbin/audispd file: path: /sbin/audispd mode: u-s,g-ws,o-wt when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/augenrules stat: path: /sbin/augenrules register: file_exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Ensure permission u-s,g-ws,o-wt on /sbin/augenrules file: path: /sbin/augenrules mode: u-s,g-ws,o-wt when: - configure_strategy | bool - file_permissions_audit_binaries | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86448-8 - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure kernel module 'squashfs' is disabled lineinfile: create: true dest: /etc/modprobe.d/squashfs.conf regexp: install\s+squashfs line: install squashfs /bin/true when: - disable_strategy | bool - kernel_module_squashfs_disabled | bool - low_complexity | bool - low_severity | bool - medium_disruption | bool - reboot_required | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83855-7 - NIST-800-171-3.4.6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - kernel_module_squashfs_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Ensure kernel module 'squashfs' is blacklisted lineinfile: create: true dest: /etc/modprobe.d/squashfs.conf regexp: ^blacklist squashfs$ line: blacklist squashfs when: - disable_strategy | bool - kernel_module_squashfs_disabled | bool - low_complexity | bool - low_severity | bool - medium_disruption | bool - reboot_required | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83855-7 - NIST-800-171-3.4.6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - kernel_module_squashfs_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Ensure kernel module 'udf' is disabled lineinfile: create: true dest: /etc/modprobe.d/udf.conf regexp: install\s+udf line: install udf /bin/true when: - disable_strategy | bool - kernel_module_udf_disabled | bool - low_complexity | bool - low_severity | bool - medium_disruption | bool - reboot_required | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83852-4 - NIST-800-171-3.4.6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - kernel_module_udf_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Ensure kernel module 'udf' is blacklisted lineinfile: create: true dest: /etc/modprobe.d/udf.conf regexp: ^blacklist udf$ line: blacklist udf when: - disable_strategy | bool - kernel_module_udf_disabled | bool - low_complexity | bool - low_severity | bool - medium_disruption | bool - reboot_required | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83852-4 - NIST-800-171-3.4.6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - kernel_module_udf_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Ensure kernel module 'usb-storage' is disabled lineinfile: create: true dest: /etc/modprobe.d/usb-storage.conf regexp: install\s+usb-storage line: install usb-storage /bin/true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83851-6 - NIST-800-171-3.1.21 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - disable_strategy - kernel_module_usb-storage_disabled - low_complexity - medium_disruption - medium_severity - reboot_required - name: Ensure kernel module 'usb-storage' is blacklisted lineinfile: create: true dest: /etc/modprobe.d/usb-storage.conf regexp: ^blacklist usb-storage$ line: blacklist usb-storage when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83851-6 - NIST-800-171-3.1.21 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - disable_strategy - kernel_module_usb-storage_disabled - low_complexity - medium_disruption - medium_severity - reboot_required - name: 'Add nodev Option to /dev/shm: Check information associated to mountpoint' command: findmnt '/dev/shm' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_nodev | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83881-3 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_nodev - no_reboot_needed - name: 'Add nodev Option to /dev/shm: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_nodev | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83881-3 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_nodev - no_reboot_needed - name: 'Add nodev Option to /dev/shm: If /dev/shm not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /dev/shm - tmpfs - tmpfs - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_nodev | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ("" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83881-3 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_nodev - no_reboot_needed - name: 'Add nodev Option to /dev/shm: Make sure nodev option is part of the to /dev/shm options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nodev'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_nodev | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - mount_info is defined and "nodev" not in mount_info.options tags: - CCE-83881-3 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_nodev - no_reboot_needed - name: 'Add nodev Option to /dev/shm: Ensure /dev/shm is mounted with nodev option' mount: path: /dev/shm src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_nodev | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("" | length == 0) tags: - CCE-83881-3 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_nodev - no_reboot_needed - name: 'Add noexec Option to /dev/shm: Check information associated to mountpoint' command: findmnt '/dev/shm' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_noexec | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83857-3 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_noexec - no_reboot_needed - name: 'Add noexec Option to /dev/shm: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_noexec | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83857-3 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_noexec - no_reboot_needed - name: 'Add noexec Option to /dev/shm: If /dev/shm not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /dev/shm - tmpfs - tmpfs - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_noexec | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ("" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83857-3 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_noexec - no_reboot_needed - name: 'Add noexec Option to /dev/shm: Make sure noexec option is part of the to /dev/shm options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',noexec'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_noexec | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - mount_info is defined and "noexec" not in mount_info.options tags: - CCE-83857-3 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_noexec - no_reboot_needed - name: 'Add noexec Option to /dev/shm: Ensure /dev/shm is mounted with noexec option' mount: path: /dev/shm src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_noexec | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("" | length == 0) tags: - CCE-83857-3 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_noexec - no_reboot_needed - name: 'Add nosuid Option to /dev/shm: Check information associated to mountpoint' command: findmnt '/dev/shm' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_nosuid | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83891-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_nosuid - no_reboot_needed - name: 'Add nosuid Option to /dev/shm: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_nosuid | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83891-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_nosuid - no_reboot_needed - name: 'Add nosuid Option to /dev/shm: If /dev/shm not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /dev/shm - tmpfs - tmpfs - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_nosuid | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ("" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83891-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_nosuid - no_reboot_needed - name: 'Add nosuid Option to /dev/shm: Make sure nosuid option is part of the to /dev/shm options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_nosuid | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - mount_info is defined and "nosuid" not in mount_info.options tags: - CCE-83891-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_nosuid - no_reboot_needed - name: 'Add nosuid Option to /dev/shm: Ensure /dev/shm is mounted with nosuid option' mount: path: /dev/shm src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_dev_shm_nosuid | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("" | length == 0) tags: - CCE-83891-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_dev_shm_nosuid - no_reboot_needed - name: 'Add nodev Option to /home: Check information associated to mountpoint' command: findmnt --fstab '/home' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - mount_option_home_nodev | bool - no_reboot_needed | bool - unknown_severity | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/home" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83871-4 - configure_strategy - high_disruption - low_complexity - mount_option_home_nodev - no_reboot_needed - unknown_severity - name: 'Add nodev Option to /home: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - mount_option_home_nodev | bool - no_reboot_needed | bool - unknown_severity | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/home" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83871-4 - configure_strategy - high_disruption - low_complexity - mount_option_home_nodev - no_reboot_needed - unknown_severity - name: 'Add nodev Option to /home: If /home not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /home - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - mount_option_home_nodev | bool - no_reboot_needed | bool - unknown_severity | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/home" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83871-4 - configure_strategy - high_disruption - low_complexity - mount_option_home_nodev - no_reboot_needed - unknown_severity - name: 'Add nodev Option to /home: Make sure nodev option is part of the to /home options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nodev'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - mount_option_home_nodev | bool - no_reboot_needed | bool - unknown_severity | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/home" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "nodev" not in mount_info.options tags: - CCE-83871-4 - configure_strategy - high_disruption - low_complexity - mount_option_home_nodev - no_reboot_needed - unknown_severity - name: 'Add nodev Option to /home: Ensure /home is mounted with nodev option' mount: path: /home src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - mount_option_home_nodev | bool - no_reboot_needed | bool - unknown_severity | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/home" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83871-4 - configure_strategy - high_disruption - low_complexity - mount_option_home_nodev - no_reboot_needed - unknown_severity - name: 'Add nosuid Option to /home: Check information associated to mountpoint' command: findmnt --fstab '/home' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_home_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/home" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83894-6 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_home_nosuid - no_reboot_needed - name: 'Add nosuid Option to /home: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_home_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/home" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83894-6 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_home_nosuid - no_reboot_needed - name: 'Add nosuid Option to /home: If /home not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /home - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_home_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/home" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83894-6 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_home_nosuid - no_reboot_needed - name: 'Add nosuid Option to /home: Make sure nosuid option is part of the to /home options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_home_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/home" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "nosuid" not in mount_info.options tags: - CCE-83894-6 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_home_nosuid - no_reboot_needed - name: 'Add nosuid Option to /home: Ensure /home is mounted with nosuid option' mount: path: /home src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_home_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/home" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83894-6 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_home_nosuid - no_reboot_needed - name: 'Add nodev Option to /tmp: Check information associated to mountpoint' command: findmnt --fstab '/tmp' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83869-8 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_nodev - no_reboot_needed - name: 'Add nodev Option to /tmp: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83869-8 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_nodev - no_reboot_needed - name: 'Add nodev Option to /tmp: If /tmp not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /tmp - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83869-8 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_nodev - no_reboot_needed - name: 'Add nodev Option to /tmp: Make sure nodev option is part of the to /tmp options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nodev'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "nodev" not in mount_info.options tags: - CCE-83869-8 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_nodev - no_reboot_needed - name: 'Add nodev Option to /tmp: Ensure /tmp is mounted with nodev option' mount: path: /tmp src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83869-8 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_nodev - no_reboot_needed - name: 'Add noexec Option to /tmp: Check information associated to mountpoint' command: findmnt --fstab '/tmp' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83885-4 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_noexec - no_reboot_needed - name: 'Add noexec Option to /tmp: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83885-4 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_noexec - no_reboot_needed - name: 'Add noexec Option to /tmp: If /tmp not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /tmp - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83885-4 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_noexec - no_reboot_needed - name: 'Add noexec Option to /tmp: Make sure noexec option is part of the to /tmp options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',noexec'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "noexec" not in mount_info.options tags: - CCE-83885-4 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_noexec - no_reboot_needed - name: 'Add noexec Option to /tmp: Ensure /tmp is mounted with noexec option' mount: path: /tmp src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83885-4 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_noexec - no_reboot_needed - name: 'Add nosuid Option to /tmp: Check information associated to mountpoint' command: findmnt --fstab '/tmp' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83872-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_nosuid - no_reboot_needed - name: 'Add nosuid Option to /tmp: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83872-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_nosuid - no_reboot_needed - name: 'Add nosuid Option to /tmp: If /tmp not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /tmp - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83872-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_nosuid - no_reboot_needed - name: 'Add nosuid Option to /tmp: Make sure nosuid option is part of the to /tmp options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "nosuid" not in mount_info.options tags: - CCE-83872-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_nosuid - no_reboot_needed - name: 'Add nosuid Option to /tmp: Ensure /tmp is mounted with nosuid option' mount: path: /tmp src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_tmp_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/tmp" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83872-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_tmp_nosuid - no_reboot_needed - name: 'Add nodev Option to /var/log/audit: Check information associated to mountpoint' command: findmnt --fstab '/var/log/audit' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83882-1 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_nodev - no_reboot_needed - name: 'Add nodev Option to /var/log/audit: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83882-1 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_nodev - no_reboot_needed - name: 'Add nodev Option to /var/log/audit: If /var/log/audit not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /var/log/audit - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83882-1 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_nodev - no_reboot_needed - name: 'Add nodev Option to /var/log/audit: Make sure nodev option is part of the to /var/log/audit options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nodev'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "nodev" not in mount_info.options tags: - CCE-83882-1 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_nodev - no_reboot_needed - name: 'Add nodev Option to /var/log/audit: Ensure /var/log/audit is mounted with nodev option' mount: path: /var/log/audit src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83882-1 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_nodev - no_reboot_needed - name: 'Add noexec Option to /var/log/audit: Check information associated to mountpoint' command: findmnt --fstab '/var/log/audit' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83878-9 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_noexec - no_reboot_needed - name: 'Add noexec Option to /var/log/audit: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83878-9 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_noexec - no_reboot_needed - name: 'Add noexec Option to /var/log/audit: If /var/log/audit not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /var/log/audit - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83878-9 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_noexec - no_reboot_needed - name: 'Add noexec Option to /var/log/audit: Make sure noexec option is part of the to /var/log/audit options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',noexec'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "noexec" not in mount_info.options tags: - CCE-83878-9 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_noexec - no_reboot_needed - name: 'Add noexec Option to /var/log/audit: Ensure /var/log/audit is mounted with noexec option' mount: path: /var/log/audit src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83878-9 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_noexec - no_reboot_needed - name: 'Add nosuid Option to /var/log/audit: Check information associated to mountpoint' command: findmnt --fstab '/var/log/audit' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83893-8 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_nosuid - no_reboot_needed - name: 'Add nosuid Option to /var/log/audit: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83893-8 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_nosuid - no_reboot_needed - name: 'Add nosuid Option to /var/log/audit: If /var/log/audit not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /var/log/audit - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83893-8 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_nosuid - no_reboot_needed - name: 'Add nosuid Option to /var/log/audit: Make sure nosuid option is part of the to /var/log/audit options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "nosuid" not in mount_info.options tags: - CCE-83893-8 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_nosuid - no_reboot_needed - name: 'Add nosuid Option to /var/log/audit: Ensure /var/log/audit is mounted with nosuid option' mount: path: /var/log/audit src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_audit_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log/audit" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83893-8 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_audit_nosuid - no_reboot_needed - name: 'Add nodev Option to /var/log: Check information associated to mountpoint' command: findmnt --fstab '/var/log' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83886-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_nodev - no_reboot_needed - name: 'Add nodev Option to /var/log: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83886-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_nodev - no_reboot_needed - name: 'Add nodev Option to /var/log: If /var/log not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /var/log - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83886-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_nodev - no_reboot_needed - name: 'Add nodev Option to /var/log: Make sure nodev option is part of the to /var/log options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nodev'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "nodev" not in mount_info.options tags: - CCE-83886-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_nodev - no_reboot_needed - name: 'Add nodev Option to /var/log: Ensure /var/log is mounted with nodev option' mount: path: /var/log src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83886-2 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_nodev - no_reboot_needed - name: 'Add noexec Option to /var/log: Check information associated to mountpoint' command: findmnt --fstab '/var/log' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83887-0 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_noexec - no_reboot_needed - name: 'Add noexec Option to /var/log: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83887-0 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_noexec - no_reboot_needed - name: 'Add noexec Option to /var/log: If /var/log not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /var/log - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83887-0 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_noexec - no_reboot_needed - name: 'Add noexec Option to /var/log: Make sure noexec option is part of the to /var/log options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',noexec'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "noexec" not in mount_info.options tags: - CCE-83887-0 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_noexec - no_reboot_needed - name: 'Add noexec Option to /var/log: Ensure /var/log is mounted with noexec option' mount: path: /var/log src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83887-0 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_noexec - no_reboot_needed - name: 'Add nosuid Option to /var/log: Check information associated to mountpoint' command: findmnt --fstab '/var/log' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83870-6 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_nosuid - no_reboot_needed - name: 'Add nosuid Option to /var/log: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83870-6 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_nosuid - no_reboot_needed - name: 'Add nosuid Option to /var/log: If /var/log not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /var/log - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83870-6 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_nosuid - no_reboot_needed - name: 'Add nosuid Option to /var/log: Make sure nosuid option is part of the to /var/log options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "nosuid" not in mount_info.options tags: - CCE-83870-6 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_nosuid - no_reboot_needed - name: 'Add nosuid Option to /var/log: Ensure /var/log is mounted with nosuid option' mount: path: /var/log src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_log_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/log" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83870-6 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_log_nosuid - no_reboot_needed - name: 'Add nodev Option to /var: Check information associated to mountpoint' command: findmnt --fstab '/var' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83868-0 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_nodev - no_reboot_needed - name: 'Add nodev Option to /var: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83868-0 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_nodev - no_reboot_needed - name: 'Add nodev Option to /var: If /var not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /var - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83868-0 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_nodev - no_reboot_needed - name: 'Add nodev Option to /var: Make sure nodev option is part of the to /var options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nodev'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "nodev" not in mount_info.options tags: - CCE-83868-0 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_nodev - no_reboot_needed - name: 'Add nodev Option to /var: Ensure /var is mounted with nodev option' mount: path: /var src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83868-0 - NIST-800-53-AC-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-MP-7 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_nodev - no_reboot_needed - name: 'Add nosuid Option to /var: Check information associated to mountpoint' command: findmnt --fstab '/var' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - mount_option_var_nosuid | bool - no_reboot_needed | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83867-2 - configure_strategy - high_disruption - low_complexity - mount_option_var_nosuid - no_reboot_needed - unknown_severity - name: 'Add nosuid Option to /var: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - mount_option_var_nosuid | bool - no_reboot_needed | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83867-2 - configure_strategy - high_disruption - low_complexity - mount_option_var_nosuid - no_reboot_needed - unknown_severity - name: 'Add nosuid Option to /var: If /var not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /var - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - mount_option_var_nosuid | bool - no_reboot_needed | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83867-2 - configure_strategy - high_disruption - low_complexity - mount_option_var_nosuid - no_reboot_needed - unknown_severity - name: 'Add nosuid Option to /var: Make sure nosuid option is part of the to /var options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - mount_option_var_nosuid | bool - no_reboot_needed | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - mount_info is defined and "nosuid" not in mount_info.options tags: - CCE-83867-2 - configure_strategy - high_disruption - low_complexity - mount_option_var_nosuid - no_reboot_needed - unknown_severity - name: 'Add nosuid Option to /var: Ensure /var is mounted with nosuid option' mount: path: /var src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - mount_option_var_nosuid | bool - no_reboot_needed | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83867-2 - configure_strategy - high_disruption - low_complexity - mount_option_var_nosuid - no_reboot_needed - unknown_severity - name: 'Add nodev Option to /var/tmp: Check information associated to mountpoint' command: findmnt --fstab '/var/tmp' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83864-9 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nodev - no_reboot_needed - name: 'Add nodev Option to /var/tmp: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83864-9 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nodev - no_reboot_needed - name: 'Add nodev Option to /var/tmp: If /var/tmp not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /var/tmp - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83864-9 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nodev - no_reboot_needed - name: 'Add nodev Option to /var/tmp: Make sure nodev option is part of the to /var/tmp options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nodev'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "nodev" not in mount_info.options tags: - CCE-83864-9 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nodev - no_reboot_needed - name: 'Add nodev Option to /var/tmp: Ensure /var/tmp is mounted with nodev option' mount: path: /var/tmp src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_nodev | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83864-9 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nodev - no_reboot_needed - name: 'Add noexec Option to /var/tmp: Check information associated to mountpoint' command: findmnt --fstab '/var/tmp' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83866-4 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_noexec - no_reboot_needed - name: 'Add noexec Option to /var/tmp: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83866-4 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_noexec - no_reboot_needed - name: 'Add noexec Option to /var/tmp: If /var/tmp not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /var/tmp - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83866-4 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_noexec - no_reboot_needed - name: 'Add noexec Option to /var/tmp: Make sure noexec option is part of the to /var/tmp options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',noexec'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "noexec" not in mount_info.options tags: - CCE-83866-4 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_noexec - no_reboot_needed - name: 'Add noexec Option to /var/tmp: Ensure /var/tmp is mounted with noexec option' mount: path: /var/tmp src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_noexec | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83866-4 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_noexec - no_reboot_needed - name: 'Add nosuid Option to /var/tmp: Check information associated to mountpoint' command: findmnt --fstab '/var/tmp' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) tags: - CCE-83863-1 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nosuid - no_reboot_needed - name: 'Add nosuid Option to /var/tmp: Create mount_info dictionary variable' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - '{{ device_name.stdout_lines[0].split() | list | lower }}' - '{{ device_name.stdout_lines[1].split() | list }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - CCE-83863-1 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nosuid - no_reboot_needed - name: 'Add nosuid Option to /var/tmp: If /var/tmp not mounted, craft mount_info manually' set_fact: mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}' with_together: - - target - source - fstype - options - - /var/tmp - '' - '' - defaults when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: - CCE-83863-1 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nosuid - no_reboot_needed - name: 'Add nosuid Option to /var/tmp: Make sure nosuid option is part of the to /var/tmp options' set_fact: mount_info: '{{ mount_info | combine( {''options'':''''~mount_info.options~'',nosuid'' }) }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) - mount_info is defined and "nosuid" not in mount_info.options tags: - CCE-83863-1 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nosuid - no_reboot_needed - name: 'Add nosuid Option to /var/tmp: Ensure /var/tmp is mounted with nosuid option' mount: path: /var/tmp src: '{{ mount_info.source }}' opts: '{{ mount_info.options }}' state: mounted fstype: '{{ mount_info.fstype }}' when: - configure_strategy | bool - high_disruption | bool - low_complexity | bool - medium_severity | bool - mount_option_var_tmp_nosuid | bool - no_reboot_needed | bool - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var/tmp" in ansible_mounts | map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83863-1 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nosuid - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CCE-83984-5 - NIST-800-53-CM-6 - PCI-DSS-Req-3.2 - PCI-DSSv4-3.3.1.1 - PCI-DSSv4-3.3.1.2 - PCI-DSSv4-3.3.1.3 - coredump_disable_backtraces - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - coredump_disable_backtraces | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Disable core dump backtraces block: - name: Check for duplicate values lineinfile: path: /etc/systemd/coredump.conf create: false regexp: ^\s*ProcessSizeMax\s*=\s* state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/systemd/coredump.conf lineinfile: path: /etc/systemd/coredump.conf create: false regexp: ^\s*ProcessSizeMax\s*=\s* state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/systemd/coredump.conf lineinfile: path: /etc/systemd/coredump.conf create: false regexp: ^\s*ProcessSizeMax\s*=\s* line: ProcessSizeMax=0 state: present when: - coredump_disable_backtraces | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"systemd" in ansible_facts.packages' tags: - CCE-83984-5 - NIST-800-53-CM-6 - PCI-DSS-Req-3.2 - PCI-DSSv4-3.3.1.1 - PCI-DSSv4-3.3.1.2 - PCI-DSSv4-3.3.1.3 - coredump_disable_backtraces - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CCE-83979-5 - NIST-800-53-CM-6 - PCI-DSS-Req-3.2 - PCI-DSSv4-3.3.1.1 - PCI-DSSv4-3.3.1.2 - PCI-DSSv4-3.3.1.3 - coredump_disable_storage - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - coredump_disable_storage | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Disable storing core dump block: - name: Check for duplicate values lineinfile: path: /etc/systemd/coredump.conf create: false regexp: ^\s*Storage\s*=\s* state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/systemd/coredump.conf lineinfile: path: /etc/systemd/coredump.conf create: false regexp: ^\s*Storage\s*=\s* state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/systemd/coredump.conf lineinfile: path: /etc/systemd/coredump.conf create: false regexp: ^\s*Storage\s*=\s* line: Storage=none state: present when: - coredump_disable_storage | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - '"systemd" in ansible_facts.packages' tags: - CCE-83979-5 - NIST-800-53-CM-6 - PCI-DSS-Req-3.2 - PCI-DSSv4-3.3.1.1 - PCI-DSSv4-3.3.1.2 - PCI-DSSv4-3.3.1.3 - coredump_disable_storage - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ contains: ^[\s]*kernel.randomize_va_space.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_kernel_randomize_va_space | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83971-2 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-SC-30 - NIST-800-53-SC-30(2) - PCI-DSS-Req-2.2.1 - PCI-DSSv4-2.2.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_kernel_randomize_va_space - name: Comment out any occurrences of kernel.randomize_va_space from config files replace: path: '{{ item.path }}' regexp: ^[\s]*kernel.randomize_va_space replace: '#kernel.randomize_va_space' loop: '{{ find_sysctl_d.files }}' when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_kernel_randomize_va_space | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83971-2 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-SC-30 - NIST-800-53-SC-30(2) - PCI-DSS-Req-2.2.1 - PCI-DSSv4-2.2.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_kernel_randomize_va_space - name: Ensure sysctl kernel.randomize_va_space is set to 2 sysctl: name: kernel.randomize_va_space value: '2' sysctl_file: /etc/sysctl.conf state: present reload: true when: - disable_strategy | bool - low_complexity | bool - medium_disruption | bool - medium_severity | bool - reboot_required | bool - sysctl_kernel_randomize_va_space | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-83971-2 - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-SC-30 - NIST-800-53-SC-30(2) - PCI-DSS-Req-2.2.1 - PCI-DSSv4-2.2.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_kernel_randomize_va_space - name: Ensure libselinux is installed package: name: libselinux state: present when: - enable_strategy | bool - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - package_libselinux_installed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84069-4 - enable_strategy - high_severity - low_complexity - low_disruption - no_reboot_needed - package_libselinux_installed - name: Ensure mcstrans is removed package: name: mcstrans state: absent when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - package_mcstrans_removed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84072-8 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_mcstrans_removed - name: Ensure setroubleshoot is removed package: name: setroubleshoot state: absent when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - package_setroubleshoot_removed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84073-6 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_setroubleshoot_removed - name: Gather the package facts package_facts: manager: auto tags: - CCE-84078-5 - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - grub2_enable_selinux - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy when: - grub2_enable_selinux | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - name: Ensure SELinux Not Disabled in /etc/default/grub - Find /etc/grub.d/ files ansible.builtin.find: paths: - /etc/grub.d/ follow: true register: result_grub_d when: - grub2_enable_selinux | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"grub2-common" in ansible_facts.packages' tags: - CCE-84078-5 - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - grub2_enable_selinux - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure SELinux Not Disabled in /etc/default/grub - Ensure SELinux Not Disabled in /etc/grub.d/ files ansible.builtin.replace: dest: '{{ item.path }}' regexp: (selinux|enforcing)=0 with_items: - '{{ result_grub_d.files }}' when: - grub2_enable_selinux | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"grub2-common" in ansible_facts.packages' tags: - CCE-84078-5 - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - grub2_enable_selinux - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure SELinux Not Disabled in /etc/default/grub - Check if /etc/grub2.cfg exists ansible.builtin.stat: path: /etc/grub2.cfg register: result_grub2_cfg_present when: - grub2_enable_selinux | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"grub2-common" in ansible_facts.packages' tags: - CCE-84078-5 - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - grub2_enable_selinux - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure SELinux Not Disabled in /etc/default/grub - Check if /etc/default/grub exists ansible.builtin.stat: path: /etc/default/grub register: result_default_grub_present when: - grub2_enable_selinux | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"grub2-common" in ansible_facts.packages' tags: - CCE-84078-5 - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - grub2_enable_selinux - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure SELinux Not Disabled in /etc/default/grub - Ensure SELinux Not Disabled in /etc/grub2.cfg ansible.builtin.replace: dest: /etc/grub2.cfg regexp: (selinux|enforcing)=0 when: - grub2_enable_selinux | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"grub2-common" in ansible_facts.packages' - result_grub2_cfg_present.stat.exists tags: - CCE-84078-5 - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - grub2_enable_selinux - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure SELinux Not Disabled in /etc/default/grub - Ensure SELinux Not Disabled in /etc/default/grub ansible.builtin.replace: dest: /etc/default/grub regexp: (selinux|enforcing)=0 when: - grub2_enable_selinux | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"grub2-common" in ansible_facts.packages' - result_default_grub_present.stat.exists tags: - CCE-84078-5 - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - grub2_enable_selinux - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure SELinux is Not Disabled block: - name: Check for duplicate values lineinfile: path: /etc/selinux/config create: false regexp: ^SELINUX= state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/selinux/config lineinfile: path: /etc/selinux/config create: false regexp: ^SELINUX= state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/selinux/config lineinfile: path: /etc/selinux/config create: true regexp: ^SELINUX= line: SELINUX=permissive state: present when: - high_severity | bool - low_complexity | bool - low_disruption | bool - reboot_required | bool - restrict_strategy | bool - selinux_not_disabled | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86152-6 - high_severity - low_complexity - low_disruption - reboot_required - restrict_strategy - selinux_not_disabled - name: Configure SELinux Policy block: - name: Check for duplicate values lineinfile: path: /etc/selinux/config create: false regexp: ^SELINUXTYPE= state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/selinux/config lineinfile: path: /etc/selinux/config create: false regexp: ^SELINUXTYPE= state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/selinux/config lineinfile: path: /etc/selinux/config create: true regexp: ^SELINUXTYPE= line: SELINUXTYPE={{ var_selinux_policy_name }} state: present when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - reboot_required | bool - restrict_strategy | bool - selinux_policytype | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84074-4 - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - NIST-800-53-AU-9 - NIST-800-53-SC-7(21) - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - selinux_policytype - name: Ensure SELinux State is Enforcing block: - name: Check for duplicate values lineinfile: path: /etc/selinux/config create: false regexp: ^SELINUX= state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/selinux/config lineinfile: path: /etc/selinux/config create: false regexp: ^SELINUX= state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/selinux/config lineinfile: path: /etc/selinux/config create: true regexp: ^SELINUX= line: SELINUX={{ var_selinux_state }} state: present when: - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - restrict_strategy | bool - selinux_state | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84079-3 - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - NIST-800-53-AU-9 - NIST-800-53-SC-7(21) - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy - selinux_state - name: Ensure avahi is removed package: name: avahi state: absent tags: - CCE-86513-9 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_avahi_removed when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - package_avahi_removed | bool - name: Enable service crond block: - name: Gather the package facts package_facts: manager: auto - name: Enable service crond systemd: name: crond enabled: 'yes' state: started masked: 'no' when: - '"cronie" in ansible_facts.packages' when: - enable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - service_crond_enabled | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84163-5 - NIST-800-53-CM-6(a) - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_crond_enabled - name: Ensure group owner on /etc/cron.d/ file: path: /etc/cron.d/ state: directory group: '0' when: - configure_strategy | bool - file_groupowner_cron_d | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84177-5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_groupowner_cron_d - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner on /etc/cron.daily/ file: path: /etc/cron.daily/ state: directory group: '0' when: - configure_strategy | bool - file_groupowner_cron_daily | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84170-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_groupowner_cron_daily - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner on /etc/cron.hourly/ file: path: /etc/cron.hourly/ state: directory group: '0' when: - configure_strategy | bool - file_groupowner_cron_hourly | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84186-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_groupowner_cron_hourly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner on /etc/cron.monthly/ file: path: /etc/cron.monthly/ state: directory group: '0' when: - configure_strategy | bool - file_groupowner_cron_monthly | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84189-0 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_groupowner_cron_monthly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner on /etc/cron.weekly/ file: path: /etc/cron.weekly/ state: directory group: '0' when: - configure_strategy | bool - file_groupowner_cron_weekly | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84174-2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_groupowner_cron_weekly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/crontab stat: path: /etc/crontab register: file_exists when: - configure_strategy | bool - file_groupowner_crontab | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84171-8 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_groupowner_crontab - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/crontab file: path: /etc/crontab group: '0' when: - configure_strategy | bool - file_groupowner_crontab | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-84171-8 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_groupowner_crontab - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner on directory /etc/cron.d/ file: path: /etc/cron.d/ state: directory owner: '0' when: - configure_strategy | bool - file_owner_cron_d | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84169-2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_owner_cron_d - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner on directory /etc/cron.daily/ file: path: /etc/cron.daily/ state: directory owner: '0' when: - configure_strategy | bool - file_owner_cron_daily | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84188-2 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_owner_cron_daily - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner on directory /etc/cron.hourly/ file: path: /etc/cron.hourly/ state: directory owner: '0' when: - configure_strategy | bool - file_owner_cron_hourly | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84168-4 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_owner_cron_hourly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner on directory /etc/cron.monthly/ file: path: /etc/cron.monthly/ state: directory owner: '0' when: - configure_strategy | bool - file_owner_cron_monthly | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84179-1 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_owner_cron_monthly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner on directory /etc/cron.weekly/ file: path: /etc/cron.weekly/ state: directory owner: '0' when: - configure_strategy | bool - file_owner_cron_weekly | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84190-8 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_owner_cron_weekly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/crontab stat: path: /etc/crontab register: file_exists when: - configure_strategy | bool - file_owner_crontab | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84167-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_owner_crontab - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/crontab file: path: /etc/crontab owner: '0' when: - configure_strategy | bool - file_owner_crontab | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-84167-6 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_owner_crontab - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set permissions for /etc/cron.d/ file: path: /etc/cron.d/ state: directory mode: u-s,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_cron_d | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84183-3 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_d - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set permissions for /etc/cron.daily/ file: path: /etc/cron.daily/ state: directory mode: u-s,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_cron_daily | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84175-9 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_daily - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set permissions for /etc/cron.hourly/ file: path: /etc/cron.hourly/ state: directory mode: u-s,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_cron_hourly | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84173-4 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_hourly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set permissions for /etc/cron.monthly/ file: path: /etc/cron.monthly/ state: directory mode: u-s,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_cron_monthly | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84181-7 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_monthly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set permissions for /etc/cron.weekly/ file: path: /etc/cron.weekly/ state: directory mode: u-s,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_cron_weekly | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84187-4 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_weekly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/crontab stat: path: /etc/crontab register: file_exists when: - configure_strategy | bool - file_permissions_crontab | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84176-7 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_crontab - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xwrs,o-xwrt on /etc/crontab file: path: /etc/crontab mode: u-xs,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_crontab | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-84176-7 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_crontab - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Remove /etc/at.deny file: path: /etc/at.deny state: absent when: - disable_strategy | bool - file_at_deny_not_exist | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86946-1 - PCI-DSSv4-2.2.6 - disable_strategy - file_at_deny_not_exist - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Remove /etc/cron.deny file: path: /etc/cron.deny state: absent when: - disable_strategy | bool - file_cron_deny_not_exist | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86850-5 - PCI-DSSv4-2.2.6 - disable_strategy - file_cron_deny_not_exist - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/at.allow stat: path: /etc/at.allow register: file_exists when: - configure_strategy | bool - file_groupowner_at_allow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87103-8 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_at_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/at.allow file: path: /etc/at.allow group: '0' when: - configure_strategy | bool - file_groupowner_at_allow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-87103-8 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_at_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/cron.allow stat: path: /etc/cron.allow register: file_exists when: - configure_strategy | bool - file_groupowner_cron_allow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86830-7 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/cron.allow file: path: /etc/cron.allow group: '0' when: - configure_strategy | bool - file_groupowner_cron_allow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86830-7 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/cron.allow stat: path: /etc/cron.allow register: file_exists when: - configure_strategy | bool - file_owner_cron_allow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86844-8 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/cron.allow file: path: /etc/cron.allow owner: '0' when: - configure_strategy | bool - file_owner_cron_allow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86844-8 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/at.allow stat: path: /etc/at.allow register: file_exists when: - configure_strategy | bool - file_permissions_at_allow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86904-0 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_at_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xwrs,o-xwrt on /etc/at.allow file: path: /etc/at.allow mode: u-xs,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_at_allow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86904-0 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_at_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/cron.allow stat: path: /etc/cron.allow register: file_exists when: - configure_strategy | bool - file_permissions_cron_allow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86877-8 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xwrs,o-xwrt on /etc/cron.allow file: path: /etc/cron.allow mode: u-xs,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_cron_allow | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-86877-8 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure dhcp-server is removed package: name: dhcp-server state: absent tags: - CCE-84240-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_dhcp_removed when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - package_dhcp_removed | bool - name: Ensure dnsmasq is removed package: name: dnsmasq state: absent tags: - CCE-86063-5 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_dnsmasq_removed when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - package_dnsmasq_removed | bool - name: Ensure bind is removed package: name: bind state: absent tags: - CCE-86505-5 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_bind_removed when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - package_bind_removed | bool - name: Ensure ftp is removed package: name: ftp state: absent tags: - CCE-86075-9 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_ftp_removed when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - package_ftp_removed | bool - name: Ensure vsftpd is removed package: name: vsftpd state: absent tags: - CCE-84159-3 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7 - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-CM-7.1(ii) - NIST-800-53-IA-5(1)(c) - NIST-800-53-IA-5(1).1(v) - PCI-DSSv4-2.2.4 - disable_strategy - high_severity - low_complexity - low_disruption - no_reboot_needed - package_vsftpd_removed when: - disable_strategy | bool - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - package_vsftpd_removed | bool - name: Ensure httpd is removed package: name: httpd state: absent tags: - CCE-85974-4 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_httpd_removed - unknown_severity when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - package_httpd_removed | bool - unknown_severity | bool - name: Ensure nginx is removed package: name: nginx state: absent tags: - CCE-88035-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_nginx_removed - unknown_severity when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - package_nginx_removed | bool - unknown_severity | bool - name: Ensure cyrus-imapd is removed package: name: cyrus-imapd state: absent tags: - CCE-88120-1 - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_cyrus-imapd_removed - unknown_severity when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - package_cyrus_imapd_removed | bool - unknown_severity | bool - name: Ensure dovecot is removed package: name: dovecot state: absent tags: - CCE-85977-7 - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_dovecot_removed - unknown_severity when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - package_dovecot_removed | bool - unknown_severity | bool - name: Ensure openldap-clients is removed package: name: openldap-clients state: absent tags: - CCE-90831-9 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_openldap-clients_removed when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - package_openldap_clients_removed | bool - name: Gather list of packages package_facts: manager: auto when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - postfix_network_listening_disabled | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '' tags: - CCE-90825-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2.4 - low_complexity - low_disruption - medium_severity - no_reboot_needed - postfix_network_listening_disabled - restrict_strategy - name: Make changes to Postfix configuration file lineinfile: path: /etc/postfix/main.cf create: false regexp: ^inet_interfaces\s*=\s.* line: inet_interfaces = {{ var_postfix_inet_interfaces }} state: present insertafter: ^inet_interfaces\s*=\s.* when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - postfix_network_listening_disabled | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"postfix" in ansible_facts.packages' - '"postfix" in ansible_facts.packages' tags: - CCE-90825-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2.4 - low_complexity - low_disruption - medium_severity - no_reboot_needed - postfix_network_listening_disabled - restrict_strategy - name: Block Disable service rpcbind block: - name: Disable service rpcbind block: - name: Disable service rpcbind systemd: name: rpcbind.service enabled: 'no' state: stopped masked: 'yes' rescue: - name: Intentionally ignored previous 'Disable service rpcbind' failure, service was already disabled meta: noop when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - service_rpcbind_disabled | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84245-0 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - service_rpcbind_disabled - name: Unit Socket Exists - rpcbind.socket command: systemctl -q list-unit-files rpcbind.socket register: socket_file_exists changed_when: false failed_when: socket_file_exists.rc not in [0, 1] check_mode: false when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - service_rpcbind_disabled | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84245-0 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - service_rpcbind_disabled - name: Disable socket rpcbind systemd: name: rpcbind.socket enabled: 'no' state: stopped masked: 'yes' when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - service_rpcbind_disabled | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - socket_file_exists.stdout_lines is search("rpcbind.socket",multiline=True) tags: - CCE-84245-0 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - service_rpcbind_disabled - name: Block Disable service nfs-server block: - name: Disable service nfs-server block: - name: Disable service nfs-server systemd: name: nfs-server.service enabled: 'no' state: stopped masked: 'yes' rescue: - name: Intentionally ignored previous 'Disable service nfs-server' failure, service was already disabled meta: noop when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - service_nfs_disabled | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90850-9 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - low_disruption - no_reboot_needed - service_nfs_disabled - unknown_severity - name: Unit Socket Exists - nfs-server.socket command: systemctl -q list-unit-files nfs-server.socket register: socket_file_exists changed_when: false failed_when: socket_file_exists.rc not in [0, 1] check_mode: false when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - service_nfs_disabled | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90850-9 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - low_disruption - no_reboot_needed - service_nfs_disabled - unknown_severity - name: Disable socket nfs-server systemd: name: nfs-server.socket enabled: 'no' state: stopped masked: 'yes' when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - service_nfs_disabled | bool - unknown_severity | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - socket_file_exists.stdout_lines is search("nfs-server.socket",multiline=True) tags: - CCE-90850-9 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - low_disruption - no_reboot_needed - service_nfs_disabled - unknown_severity - name: Gather the package facts package_facts: manager: auto tags: - CCE-84218-7 - NIST-800-53-AU-8(1)(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.3 - PCI-DSSv4-10.6.2 - chronyd_specify_remote_server - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed when: - chronyd_specify_remote_server | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - name: Detect if chrony is already configured with pools or servers find: path: /etc patterns: chrony.conf contains: ^[\s]*(?:server|pool)[\s]+[\w]+ register: chrony_servers when: - chronyd_specify_remote_server | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"chrony" in ansible_facts.packages' tags: - CCE-84218-7 - NIST-800-53-AU-8(1)(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.3 - PCI-DSSv4-10.6.2 - chronyd_specify_remote_server - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure remote time servers lineinfile: path: /etc/chrony.conf line: server {{ item }} state: present create: true loop: '{{ var_multiple_time_servers.split(",") }}' when: - chronyd_specify_remote_server | bool - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"chrony" in ansible_facts.packages' - chrony_servers.matched == 0 tags: - CCE-84218-7 - NIST-800-53-AU-8(1)(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.3 - PCI-DSSv4-10.6.2 - chronyd_specify_remote_server - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure rsync-daemon is removed package: name: rsync-daemon state: absent tags: - CCE-86336-5 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_rsync_removed when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - package_rsync_removed | bool - name: Detect .rhosts files in users home directories find: paths: - /root - /home recurse: true patterns: .rhosts hidden: true file_type: file check_mode: false register: rhosts_locations tags: - CCE-84145-2 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - high_severity - low_complexity - low_disruption - no_reboot_needed - no_rsh_trust_files - restrict_strategy when: - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - no_rsh_trust_files | bool - restrict_strategy | bool - name: Remove .rhosts files file: path: '{{ item }}' state: absent with_items: '{{ rhosts_locations.files | map(attribute=''path'') | list }}' when: - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - no_rsh_trust_files | bool - restrict_strategy | bool - rhosts_locations is success tags: - CCE-84145-2 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - high_severity - low_complexity - low_disruption - no_reboot_needed - no_rsh_trust_files - restrict_strategy - name: Remove /etc/hosts.equiv file file: path: /etc/hosts.equiv state: absent tags: - CCE-84145-2 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - high_severity - low_complexity - low_disruption - no_reboot_needed - no_rsh_trust_files - restrict_strategy when: - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - no_rsh_trust_files | bool - restrict_strategy | bool - name: Ensure telnet-server is removed package: name: telnet-server state: absent tags: - CCE-84149-4 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSS-Req-2.2.2 - PCI-DSSv4-2.2.4 - disable_strategy - high_severity - low_complexity - low_disruption - no_reboot_needed - package_telnet-server_removed when: - disable_strategy | bool - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - package_telnet_server_removed | bool - name: Ensure telnet is removed package: name: telnet state: absent tags: - CCE-84146-0 - NIST-800-171-3.1.13 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_telnet_removed when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - package_telnet_removed | bool - name: Ensure tftp-server is removed package: name: tftp-server state: absent tags: - CCE-84154-4 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - high_severity - low_complexity - low_disruption - no_reboot_needed - package_tftp-server_removed when: - disable_strategy | bool - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - package_tftp_server_removed | bool - name: Ensure tftp is removed package: name: tftp state: absent tags: - CCE-84153-6 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_tftp_removed when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - low_severity | bool - no_reboot_needed | bool - package_tftp_removed | bool - name: Ensure cups is removed package: name: cups state: absent tags: - CCE-86300-1 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_cups_removed - unknown_severity when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - package_cups_removed | bool - unknown_severity | bool - name: Ensure squid is removed package: name: squid state: absent tags: - CCE-84238-5 - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_squid_removed - unknown_severity when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - package_squid_removed | bool - unknown_severity | bool - name: Ensure samba is removed package: name: samba state: absent tags: - CCE-85979-3 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_samba_removed - unknown_severity when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - package_samba_removed | bool - unknown_severity | bool - name: Ensure net-snmp is removed package: name: net-snmp state: absent tags: - CCE-85981-9 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_net-snmp_removed - unknown_severity when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - package_net_snmp_removed | bool - unknown_severity | bool - name: Test for existence /etc/ssh/sshd_config stat: path: /etc/ssh/sshd_config register: file_exists when: - configure_strategy | bool - file_groupowner_sshd_config | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90817-8 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_groupowner_sshd_config - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/ssh/sshd_config file: path: /etc/ssh/sshd_config group: '0' when: - configure_strategy | bool - file_groupowner_sshd_config | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-90817-8 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_groupowner_sshd_config - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/ssh/ file(s) matching ^.*_key$ command: find -H /etc/ssh/ -maxdepth 1 -type f ! -group ssh_keys -regex "^.*_key$" register: files_found changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_groupownership_sshd_private_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86127-8 - configure_strategy - file_groupownership_sshd_private_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner on /etc/ssh/ file(s) matching ^.*_key$ file: path: '{{ item }}' group: ssh_keys state: file with_items: - '{{ files_found.stdout_lines }}' when: - configure_strategy | bool - file_groupownership_sshd_private_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86127-8 - configure_strategy - file_groupownership_sshd_private_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/ssh/ file(s) matching ^.*\.pub$ command: find -H /etc/ssh/ -maxdepth 1 -type f ! -group 0 -regex "^.*\.pub$" register: files_found changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_groupownership_sshd_pub_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86136-9 - configure_strategy - file_groupownership_sshd_pub_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner on /etc/ssh/ file(s) matching ^.*\.pub$ file: path: '{{ item }}' group: '0' state: file with_items: - '{{ files_found.stdout_lines }}' when: - configure_strategy | bool - file_groupownership_sshd_pub_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86136-9 - configure_strategy - file_groupownership_sshd_pub_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/ssh/sshd_config stat: path: /etc/ssh/sshd_config register: file_exists when: - configure_strategy | bool - file_owner_sshd_config | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90821-0 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_owner_sshd_config - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/ssh/sshd_config file: path: /etc/ssh/sshd_config owner: '0' when: - configure_strategy | bool - file_owner_sshd_config | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-90821-0 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_owner_sshd_config - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/ssh/ file(s) matching ^.*_key$ command: find -H /etc/ssh/ -maxdepth 1 -type f ! -uid 0 -regex "^.*_key$" register: files_found changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_ownership_sshd_private_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86119-5 - configure_strategy - file_ownership_sshd_private_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner on /etc/ssh/ file(s) matching ^.*_key$ file: path: '{{ item }}' owner: '0' state: file with_items: - '{{ files_found.stdout_lines }}' when: - configure_strategy | bool - file_ownership_sshd_private_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86119-5 - configure_strategy - file_ownership_sshd_private_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/ssh/ file(s) matching ^.*\.pub$ command: find -H /etc/ssh/ -maxdepth 1 -type f ! -uid 0 -regex "^.*\.pub$" register: files_found changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_ownership_sshd_pub_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86130-2 - configure_strategy - file_ownership_sshd_pub_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner on /etc/ssh/ file(s) matching ^.*\.pub$ file: path: '{{ item }}' owner: '0' state: file with_items: - '{{ files_found.stdout_lines }}' when: - configure_strategy | bool - file_ownership_sshd_pub_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86130-2 - configure_strategy - file_ownership_sshd_pub_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/ssh/sshd_config stat: path: /etc/ssh/sshd_config register: file_exists when: - configure_strategy | bool - file_permissions_sshd_config | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90818-6 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_config - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xwrs,o-xwrt on /etc/ssh/sshd_config file: path: /etc/ssh/sshd_config mode: u-xs,g-xwrs,o-xwrt when: - configure_strategy | bool - file_permissions_sshd_config | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - file_exists.stat is defined and file_exists.stat.exists tags: - CCE-90818-6 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_config - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find root:root-owned keys ansible.builtin.command: find -H /etc/ssh/ -maxdepth 1 -user root -regex ".*_key$" -type f -group root -perm /u+xs,g+xwrs,o+xwrt register: root_owned_keys changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_permissions_sshd_private_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90820-2 - NIST-800-171-3.1.13 - NIST-800-171-3.13.10 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-2.2.4 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_private_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set permissions for root:root-owned keys ansible.builtin.file: path: '{{ item }}' mode: u-xs,g-xwrs,o-xwrt state: file with_items: - '{{ root_owned_keys.stdout_lines }}' when: - configure_strategy | bool - file_permissions_sshd_private_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90820-2 - NIST-800-171-3.1.13 - NIST-800-171-3.13.10 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-2.2.4 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_private_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find root:ssh_keys-owned keys ansible.builtin.command: find -H /etc/ssh/ -maxdepth 1 -user root -regex ".*_key$" -type f -group ssh_keys -perm /u+xs,g+xws,o+xwrt register: dedicated_group_owned_keys changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_permissions_sshd_private_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90820-2 - NIST-800-171-3.1.13 - NIST-800-171-3.13.10 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-2.2.4 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_private_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set permissions for root:ssh_keys-owned keys ansible.builtin.file: path: '{{ item }}' mode: u-xs,g-xws,o-xwrt state: file with_items: - '{{ dedicated_group_owned_keys.stdout_lines }}' when: - configure_strategy | bool - file_permissions_sshd_private_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90820-2 - NIST-800-171-3.1.13 - NIST-800-171-3.13.10 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-2.2.4 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_private_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/ssh/ file(s) command: find -H /etc/ssh/ -maxdepth 1 -perm /u+xs,g+xws,o+xwt -type f -regex "^.*\.pub$" register: files_found changed_when: false failed_when: false check_mode: false when: - configure_strategy | bool - file_permissions_sshd_pub_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90819-4 - NIST-800-171-3.1.13 - NIST-800-171-3.13.10 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-2.2.4 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_pub_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set permissions for /etc/ssh/ file(s) file: path: '{{ item }}' mode: u-xs,g-xws,o-xwt state: file with_items: - '{{ files_found.stdout_lines }}' when: - configure_strategy | bool - file_permissions_sshd_pub_key | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90819-4 - NIST-800-171-3.1.13 - NIST-800-171-3.13.10 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSS-Req-2.2.4 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_pub_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set SSH Client Alive Count Max block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*ClientAliveCountMax\s+ state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*ClientAliveCountMax\s+ state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)^\s*ClientAliveCountMax\s+ line: ClientAliveCountMax {{ var_sshd_set_keepalive }} state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_set_keepalive | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90805-3 - CJIS-5.5.6 - NIST-800-171-3.1.11 - NIST-800-53-AC-12 - NIST-800-53-AC-17(a) - NIST-800-53-AC-2(5) - NIST-800-53-CM-6(a) - NIST-800-53-SC-10 - PCI-DSS-Req-8.1.8 - PCI-DSSv4-8.2.8 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_keepalive - name: Set SSH Client Alive Interval block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*ClientAliveInterval\s+ state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*ClientAliveInterval\s+ state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)^\s*ClientAliveInterval\s+ line: ClientAliveInterval {{ sshd_idle_timeout_value }} state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_set_idle_timeout | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - ansible_distribution == 'RedHat' and ansible_distribution_version is version('8.5', '<=') tags: - CCE-90811-1 - CJIS-5.5.6 - NIST-800-171-3.1.11 - NIST-800-53-AC-12 - NIST-800-53-AC-17(a) - NIST-800-53-AC-17(a) - NIST-800-53-AC-2(5) - NIST-800-53-CM-6(a) - NIST-800-53-CM-6(a) - NIST-800-53-SC-10 - PCI-DSS-Req-8.1.8 - PCI-DSSv4-8.2.8 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_idle_timeout - name: Disable Host-Based Authentication block: - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*{{ "HostbasedAuthentication"| regex_escape }}\s+ state: absent - name: Check if /etc/ssh/sshd_config.d exists stat: path: /etc/ssh/sshd_config.d register: _etc_ssh_sshd_config_d_exists - name: Check if the parameter HostbasedAuthentication is present in /etc/ssh/sshd_config.d find: paths: /etc/ssh/sshd_config.d recurse: 'yes' follow: 'no' contains: (?i)^\s*{{ "HostbasedAuthentication"| regex_escape }}\s+ register: _etc_ssh_sshd_config_d_has_parameter when: _etc_ssh_sshd_config_d_exists.stat.isdir is defined and _etc_ssh_sshd_config_d_exists.stat.isdir - name: Remove parameter from files in /etc/ssh/sshd_config.d lineinfile: path: '{{ item.path }}' create: false regexp: (?i)^\s*{{ "HostbasedAuthentication"| regex_escape }}\s+ state: absent with_items: '{{ _etc_ssh_sshd_config_d_has_parameter.files }}' when: _etc_ssh_sshd_config_d_has_parameter.matched - name: Insert correct line to /etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf lineinfile: path: /etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf create: true regexp: (?i)^\s*{{ "HostbasedAuthentication"| regex_escape }}\s+ line: HostbasedAuthentication no state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - disable_host_auth | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90816-0 - CJIS-5.5.6 - NIST-800-171-3.1.12 - NIST-800-53-AC-17(a) - NIST-800-53-AC-3 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-8.3.1 - disable_host_auth - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Disable SSH Access via Empty Passwords block: - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*{{ "PermitEmptyPasswords"| regex_escape }}\s+ state: absent - name: Check if /etc/ssh/sshd_config.d exists stat: path: /etc/ssh/sshd_config.d register: _etc_ssh_sshd_config_d_exists - name: Check if the parameter PermitEmptyPasswords is present in /etc/ssh/sshd_config.d find: paths: /etc/ssh/sshd_config.d recurse: 'yes' follow: 'no' contains: (?i)^\s*{{ "PermitEmptyPasswords"| regex_escape }}\s+ register: _etc_ssh_sshd_config_d_has_parameter when: _etc_ssh_sshd_config_d_exists.stat.isdir is defined and _etc_ssh_sshd_config_d_exists.stat.isdir - name: Remove parameter from files in /etc/ssh/sshd_config.d lineinfile: path: '{{ item.path }}' create: false regexp: (?i)^\s*{{ "PermitEmptyPasswords"| regex_escape }}\s+ state: absent with_items: '{{ _etc_ssh_sshd_config_d_has_parameter.files }}' when: _etc_ssh_sshd_config_d_has_parameter.matched - name: Insert correct line to /etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf lineinfile: path: /etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf create: true regexp: (?i)^\s*{{ "PermitEmptyPasswords"| regex_escape }}\s+ line: PermitEmptyPasswords no state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - high_severity | bool - low_complexity | bool - low_disruption | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_disable_empty_passwords | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90799-8 - CJIS-5.5.6 - NIST-800-171-3.1.1 - NIST-800-171-3.1.5 - NIST-800-53-AC-17(a) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSS-Req-2.2.4 - PCI-DSSv4-2.2.6 - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy - sshd_disable_empty_passwords - name: Disable SSH Support for .rhosts Files block: - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*{{ "IgnoreRhosts"| regex_escape }}\s+ state: absent - name: Check if /etc/ssh/sshd_config.d exists stat: path: /etc/ssh/sshd_config.d register: _etc_ssh_sshd_config_d_exists - name: Check if the parameter IgnoreRhosts is present in /etc/ssh/sshd_config.d find: paths: /etc/ssh/sshd_config.d recurse: 'yes' follow: 'no' contains: (?i)^\s*{{ "IgnoreRhosts"| regex_escape }}\s+ register: _etc_ssh_sshd_config_d_has_parameter when: _etc_ssh_sshd_config_d_exists.stat.isdir is defined and _etc_ssh_sshd_config_d_exists.stat.isdir - name: Remove parameter from files in /etc/ssh/sshd_config.d lineinfile: path: '{{ item.path }}' create: false regexp: (?i)^\s*{{ "IgnoreRhosts"| regex_escape }}\s+ state: absent with_items: '{{ _etc_ssh_sshd_config_d_has_parameter.files }}' when: _etc_ssh_sshd_config_d_has_parameter.matched - name: Insert correct line to /etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf lineinfile: path: /etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf create: true regexp: (?i)^\s*{{ "IgnoreRhosts"| regex_escape }}\s+ line: IgnoreRhosts yes state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_disable_rhosts | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90797-2 - CJIS-5.5.6 - NIST-800-171-3.1.12 - NIST-800-53-AC-17(a) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_disable_rhosts - name: Disable SSH Root Login block: - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*{{ "PermitRootLogin"| regex_escape }}\s+ state: absent - name: Check if /etc/ssh/sshd_config.d exists stat: path: /etc/ssh/sshd_config.d register: _etc_ssh_sshd_config_d_exists - name: Check if the parameter PermitRootLogin is present in /etc/ssh/sshd_config.d find: paths: /etc/ssh/sshd_config.d recurse: 'yes' follow: 'no' contains: (?i)^\s*{{ "PermitRootLogin"| regex_escape }}\s+ register: _etc_ssh_sshd_config_d_has_parameter when: _etc_ssh_sshd_config_d_exists.stat.isdir is defined and _etc_ssh_sshd_config_d_exists.stat.isdir - name: Remove parameter from files in /etc/ssh/sshd_config.d lineinfile: path: '{{ item.path }}' create: false regexp: (?i)^\s*{{ "PermitRootLogin"| regex_escape }}\s+ state: absent with_items: '{{ _etc_ssh_sshd_config_d_has_parameter.files }}' when: _etc_ssh_sshd_config_d_has_parameter.matched - name: Insert correct line to /etc/ssh/sshd_config.d/00-complianceascode-hardening.conf lineinfile: path: /etc/ssh/sshd_config.d/00-complianceascode-hardening.conf create: true regexp: (?i)^\s*{{ "PermitRootLogin"| regex_escape }}\s+ line: PermitRootLogin no state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_disable_root_login | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90800-4 - CJIS-5.5.6 - NIST-800-171-3.1.1 - NIST-800-171-3.1.5 - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(2) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-IA-2 - NIST-800-53-IA-2(5) - PCI-DSS-Req-2.2.4 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_disable_root_login - name: Disable SSH TCP Forwarding block: - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*{{ "AllowTcpForwarding"| regex_escape }}\s+ state: absent - name: Check if /etc/ssh/sshd_config.d exists stat: path: /etc/ssh/sshd_config.d register: _etc_ssh_sshd_config_d_exists - name: Check if the parameter AllowTcpForwarding is present in /etc/ssh/sshd_config.d find: paths: /etc/ssh/sshd_config.d recurse: 'yes' follow: 'no' contains: (?i)^\s*{{ "AllowTcpForwarding"| regex_escape }}\s+ register: _etc_ssh_sshd_config_d_has_parameter when: _etc_ssh_sshd_config_d_exists.stat.isdir is defined and _etc_ssh_sshd_config_d_exists.stat.isdir - name: Remove parameter from files in /etc/ssh/sshd_config.d lineinfile: path: '{{ item.path }}' create: false regexp: (?i)^\s*{{ "AllowTcpForwarding"| regex_escape }}\s+ state: absent with_items: '{{ _etc_ssh_sshd_config_d_has_parameter.files }}' when: _etc_ssh_sshd_config_d_has_parameter.matched - name: Insert correct line to /etc/ssh/sshd_config.d/00-complianceascode-hardening.conf lineinfile: path: /etc/ssh/sshd_config.d/00-complianceascode-hardening.conf create: true regexp: (?i)^\s*{{ "AllowTcpForwarding"| regex_escape }}\s+ line: AllowTcpForwarding no state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_disable_tcp_forwarding | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90806-1 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_disable_tcp_forwarding - name: Disable X11 Forwarding block: - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*{{ "X11Forwarding"| regex_escape }}\s+ state: absent - name: Check if /etc/ssh/sshd_config.d exists stat: path: /etc/ssh/sshd_config.d register: _etc_ssh_sshd_config_d_exists - name: Check if the parameter X11Forwarding is present in /etc/ssh/sshd_config.d find: paths: /etc/ssh/sshd_config.d recurse: 'yes' follow: 'no' contains: (?i)^\s*{{ "X11Forwarding"| regex_escape }}\s+ register: _etc_ssh_sshd_config_d_has_parameter when: _etc_ssh_sshd_config_d_exists.stat.isdir is defined and _etc_ssh_sshd_config_d_exists.stat.isdir - name: Remove parameter from files in /etc/ssh/sshd_config.d lineinfile: path: '{{ item.path }}' create: false regexp: (?i)^\s*{{ "X11Forwarding"| regex_escape }}\s+ state: absent with_items: '{{ _etc_ssh_sshd_config_d_has_parameter.files }}' when: _etc_ssh_sshd_config_d_has_parameter.matched - name: Insert correct line to /etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf lineinfile: path: /etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf create: true regexp: (?i)^\s*{{ "X11Forwarding"| regex_escape }}\s+ line: X11Forwarding no state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_disable_x11_forwarding | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90798-0 - NIST-800-53-CM-6(b) - PCI-DSSv4-2.2.4 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_disable_x11_forwarding - name: Do Not Allow SSH Environment Options block: - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*{{ "PermitUserEnvironment"| regex_escape }}\s+ state: absent - name: Check if /etc/ssh/sshd_config.d exists stat: path: /etc/ssh/sshd_config.d register: _etc_ssh_sshd_config_d_exists - name: Check if the parameter PermitUserEnvironment is present in /etc/ssh/sshd_config.d find: paths: /etc/ssh/sshd_config.d recurse: 'yes' follow: 'no' contains: (?i)^\s*{{ "PermitUserEnvironment"| regex_escape }}\s+ register: _etc_ssh_sshd_config_d_has_parameter when: _etc_ssh_sshd_config_d_exists.stat.isdir is defined and _etc_ssh_sshd_config_d_exists.stat.isdir - name: Remove parameter from files in /etc/ssh/sshd_config.d lineinfile: path: '{{ item.path }}' create: false regexp: (?i)^\s*{{ "PermitUserEnvironment"| regex_escape }}\s+ state: absent with_items: '{{ _etc_ssh_sshd_config_d_has_parameter.files }}' when: _etc_ssh_sshd_config_d_has_parameter.matched - name: Insert correct line to /etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf lineinfile: path: /etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf create: true regexp: (?i)^\s*{{ "PermitUserEnvironment"| regex_escape }}\s+ line: PermitUserEnvironment no state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_do_not_permit_user_env | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90803-8 - CJIS-5.5.6 - NIST-800-171-3.1.12 - NIST-800-53-AC-17(a) - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSS-Req-2.2.4 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_do_not_permit_user_env - name: Enable PAM block: - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*{{ "UsePAM"| regex_escape }}\s+ state: absent - name: Check if /etc/ssh/sshd_config.d exists stat: path: /etc/ssh/sshd_config.d register: _etc_ssh_sshd_config_d_exists - name: Check if the parameter UsePAM is present in /etc/ssh/sshd_config.d find: paths: /etc/ssh/sshd_config.d recurse: 'yes' follow: 'no' contains: (?i)^\s*{{ "UsePAM"| regex_escape }}\s+ register: _etc_ssh_sshd_config_d_has_parameter when: _etc_ssh_sshd_config_d_exists.stat.isdir is defined and _etc_ssh_sshd_config_d_exists.stat.isdir - name: Remove parameter from files in /etc/ssh/sshd_config.d lineinfile: path: '{{ item.path }}' create: false regexp: (?i)^\s*{{ "UsePAM"| regex_escape }}\s+ state: absent with_items: '{{ _etc_ssh_sshd_config_d_has_parameter.files }}' when: _etc_ssh_sshd_config_d_has_parameter.matched - name: Insert correct line to /etc/ssh/sshd_config.d/00-complianceascode-hardening.conf lineinfile: path: /etc/ssh/sshd_config.d/00-complianceascode-hardening.conf create: true regexp: (?i)^\s*{{ "UsePAM"| regex_escape }}\s+ line: UsePAM yes state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_enable_pam | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86722-6 - PCI-DSSv4-2.2.4 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_enable_pam - name: Enable SSH Warning Banner block: - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*{{ "Banner"| regex_escape }}\s+ state: absent - name: Check if /etc/ssh/sshd_config.d exists stat: path: /etc/ssh/sshd_config.d register: _etc_ssh_sshd_config_d_exists - name: Check if the parameter Banner is present in /etc/ssh/sshd_config.d find: paths: /etc/ssh/sshd_config.d recurse: 'yes' follow: 'no' contains: (?i)^\s*{{ "Banner"| regex_escape }}\s+ register: _etc_ssh_sshd_config_d_has_parameter when: _etc_ssh_sshd_config_d_exists.stat.isdir is defined and _etc_ssh_sshd_config_d_exists.stat.isdir - name: Remove parameter from files in /etc/ssh/sshd_config.d lineinfile: path: '{{ item.path }}' create: false regexp: (?i)^\s*{{ "Banner"| regex_escape }}\s+ state: absent with_items: '{{ _etc_ssh_sshd_config_d_has_parameter.files }}' when: _etc_ssh_sshd_config_d_has_parameter.matched - name: Insert correct line to /etc/ssh/sshd_config.d/00-complianceascode-hardening.conf lineinfile: path: /etc/ssh/sshd_config.d/00-complianceascode-hardening.conf create: true regexp: (?i)^\s*{{ "Banner"| regex_escape }}\s+ line: Banner /etc/issue.net state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_enable_warning_banner_net | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87979-1 - CJIS-5.5.6 - NIST-800-171-3.1.9 - NIST-800-53-AC-17(a) - NIST-800-53-AC-8(a) - NIST-800-53-AC-8(c) - NIST-800-53-CM-6(a) - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_enable_warning_banner_net - name: Ensure SSH LoginGraceTime is configured block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*LoginGraceTime\s+ state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*LoginGraceTime\s+ state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)^\s*LoginGraceTime\s+ line: LoginGraceTime {{ var_sshd_set_login_grace_time }} state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_set_login_grace_time | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86552-7 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_login_grace_time - name: Set SSH Daemon LogLevel to VERBOSE block: - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*{{ "LogLevel"| regex_escape }}\s+ state: absent - name: Check if /etc/ssh/sshd_config.d exists stat: path: /etc/ssh/sshd_config.d register: _etc_ssh_sshd_config_d_exists - name: Check if the parameter LogLevel is present in /etc/ssh/sshd_config.d find: paths: /etc/ssh/sshd_config.d recurse: 'yes' follow: 'no' contains: (?i)^\s*{{ "LogLevel"| regex_escape }}\s+ register: _etc_ssh_sshd_config_d_has_parameter when: _etc_ssh_sshd_config_d_exists.stat.isdir is defined and _etc_ssh_sshd_config_d_exists.stat.isdir - name: Remove parameter from files in /etc/ssh/sshd_config.d lineinfile: path: '{{ item.path }}' create: false regexp: (?i)^\s*{{ "LogLevel"| regex_escape }}\s+ state: absent with_items: '{{ _etc_ssh_sshd_config_d_has_parameter.files }}' when: _etc_ssh_sshd_config_d_has_parameter.matched - name: Insert correct line to /etc/ssh/sshd_config.d/00-complianceascode-hardening.conf lineinfile: path: /etc/ssh/sshd_config.d/00-complianceascode-hardening.conf create: true regexp: (?i)^\s*{{ "LogLevel"| regex_escape }}\s+ line: LogLevel VERBOSE state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_set_loglevel_verbose | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-86923-0 - NIST-800-53-AC-17(1) - NIST-800-53-AC-17(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-2.2.4 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_loglevel_verbose - name: Set SSH authentication attempt limit block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*MaxAuthTries\s+ state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*MaxAuthTries\s+ state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)^\s*MaxAuthTries\s+ line: MaxAuthTries {{ sshd_max_auth_tries_value }} state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_set_max_auth_tries | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-90810-3 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_max_auth_tries - name: Set SSH MaxSessions limit block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*MaxSessions\s+ state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*MaxSessions\s+ state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)^\s*MaxSessions\s+ line: MaxSessions {{ var_sshd_max_sessions }} state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - configure_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - sshd_set_max_sessions | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-84103-1 - PCI-DSSv4-2.2.6 - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - sshd_set_max_sessions - name: Ensure SSH MaxStartups is configured block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*MaxStartups\s+ state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: false regexp: (?i)^\s*MaxStartups\s+ state: absent when: dupes.found is defined and dupes.found > 1 - name: Insert correct line to /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)^\s*MaxStartups\s+ line: MaxStartups {{ var_sshd_set_maxstartups }} state: present insertbefore: ^[#\s]*Match validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool - sshd_set_maxstartups | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CCE-87872-8 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_maxstartups - name: Ensure xorg-x11-server-common is removed package: name: xorg-x11-server-common state: absent tags: - CCE-84104-9 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_xorg-x11-server-common_removed when: - disable_strategy | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - no_reboot_needed | bool - package_xorg_x11_server_common_removed | bool