Server IP : 184.154.167.98 / Your IP : 18.220.194.29 Web Server : Apache System : Linux pink.dnsnetservice.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 User : puertode ( 1767) PHP Version : 8.2.26 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/share/scap-security-guide/ansible/ |
Upload File : |
--- ############################################################################### # # Ansible Playbook for CIS AlmaLinux OS 8 Benchmark for Level 2 - Server # # Profile Description: # This profile defines a baseline that aligns to the "Level 2 - Server" # configuration from the Center for Internet Security® # AlmaLinux OS 8 Benchmark™, v3.0.0, released 2023-10-30. # This profile includes Center for Internet Security® # AlmaLinux OS 8 CIS Benchmarks™ content. # # Profile ID: xccdf_org.ssgproject.content_profile_cis # Benchmark ID: xccdf_org.ssgproject.content_benchmark_ALMALINUX-8 # Benchmark Version: 0.1.75 # XCCDF Version: 1.2 # # This file can be generated by OpenSCAP using: # $ oscap xccdf generate fix --profile xccdf_org.ssgproject.content_profile_cis --fix-type ansible ssg-almalinux8-ds.xml # # This Ansible Playbook is generated from an XCCDF profile without preliminary evaluation. # It attempts to fix every selected rule, even if the system is already compliant. # # How to apply this Ansible Playbook: # $ ansible-playbook -i "localhost," -c local playbook.yml # $ ansible-playbook -i "192.168.1.155," playbook.yml # $ ansible-playbook -i inventory.ini playbook.yml # ############################################################################### - name: Ansible Playbook for xccdf_org.ssgproject.content_profile_cis hosts: all vars: var_system_crypto_policy: !!str DEFAULT:NO-SHA1 inactivity_timeout_value: !!str 900 var_screensaver_lock_delay: !!str 5 var_sudo_logfile: !!str /var/log/sudo.log var_sudo_timestamp_timeout: !!str 5 var_authselect_profile: !!str sssd cis_banner_text: !!str Authorized users only. All activity may be monitored and reported. login_banner_text: !!str ^(Authorized[\s\n]+users[\s\n]+only\.[\s\n]+All[\s\n]+activity[\s\n]+may[\s\n]+be[\s\n]+monitored[\s\n]+and[\s\n]+reported\.|^(?!.*(\\|fedora|rhel|sle|ubuntu)).*)$ var_password_pam_remember: !!str 24 var_password_pam_remember_control_flag: !!str requisite,required var_accounts_passwords_pam_faillock_deny: !!str 5 var_accounts_passwords_pam_faillock_unlock_time: !!str 900 var_password_pam_dictcheck: !!str 1 var_password_pam_difok: !!str 2 var_password_pam_maxrepeat: !!str 3 var_password_pam_minclass: !!str 4 var_password_pam_minlen: !!str 14 var_password_hashing_algorithm_pam: !!str sha512 var_password_hashing_algorithm: !!str SHA512 var_account_disable_post_pw_expiration: !!str 30 var_accounts_maximum_age_login_defs: !!str 365 var_accounts_password_warn_age_login_defs: !!str 7 var_pam_wheel_group_for_su: !!str sugroup var_accounts_tmout: !!str 900 var_user_initialization_files_regex: !!str ^\.[\w\- ]+$ var_accounts_user_umask: !!str 027 sysctl_net_ipv6_conf_all_accept_ra_value: !!str 0 sysctl_net_ipv6_conf_all_accept_redirects_value: !!str 0 sysctl_net_ipv6_conf_all_accept_source_route_value: !!str 0 sysctl_net_ipv6_conf_all_forwarding_value: !!str 0 sysctl_net_ipv6_conf_default_accept_ra_value: !!str 0 sysctl_net_ipv6_conf_default_accept_redirects_value: !!str 0 sysctl_net_ipv6_conf_default_accept_source_route_value: !!str 0 sysctl_net_ipv4_conf_all_accept_redirects_value: !!str 0 sysctl_net_ipv4_conf_all_accept_source_route_value: !!str 0 sysctl_net_ipv4_conf_all_log_martians_value: !!str 1 sysctl_net_ipv4_conf_all_rp_filter_value: !!str 1 sysctl_net_ipv4_conf_all_secure_redirects_value: !!str 0 sysctl_net_ipv4_conf_default_accept_redirects_value: !!str 0 sysctl_net_ipv4_conf_default_accept_source_route_value: !!str 0 sysctl_net_ipv4_conf_default_log_martians_value: !!str 1 sysctl_net_ipv4_conf_default_rp_filter_value: !!str 1 sysctl_net_ipv4_conf_default_secure_redirects_value: !!str 0 sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value: !!str 1 sysctl_net_ipv4_icmp_ignore_bogus_error_responses_value: !!str 1 sysctl_net_ipv4_tcp_syncookies_value: !!str 1 var_selinux_policy_name: !!str targeted var_selinux_state: !!str enforcing var_postfix_inet_interfaces: !!str loopback-only var_multiple_time_servers: !!str 0.rhel.pool.ntp.org,1.rhel.pool.ntp.org,2.rhel.pool.ntp.org,3.rhel.pool.ntp.org var_sshd_set_keepalive: !!str 1 sshd_idle_timeout_value: !!str 300 var_sshd_set_login_grace_time: !!str 60 sshd_max_auth_tries_value: !!str 4 var_sshd_max_sessions: !!str 10 var_sshd_set_maxstartups: !!str 10:30:60 sshd_approved_ciphers: !!str -3des-cbc,aes128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se sshd_strong_kex: !!str -diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1 sshd_strong_macs: !!str -hmac-md5,hmac-md5-96,hmac-ripemd160,hmac-sha1-96,umac-64@openssh.com,hmac-md5-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-ripemd160-etm@openssh.com,hmac-sha1-96-etm@openssh.com,umac-64-etm@openssh.com var_accounts_passwords_pam_faillock_dir: !!str /var/run/faillock var_auditd_disk_error_action: !!str syslog|single|halt var_auditd_disk_full_action: !!str syslog|single|halt var_auditd_action_mail_acct: !!str root var_auditd_admin_space_left_action: !!str single|halt var_auditd_max_log_file: !!str 6 var_auditd_max_log_file_action: !!str keep_logs var_auditd_space_left_action: !!str email|exec|single|halt tasks: - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.10.1.3 - DISA-STIG-RHEL-08-010359 - 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: aide state: present when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.3 - DISA-STIG-RHEL-08-010359 - 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: Gather the package facts package_facts: manager: auto tags: - CJIS-5.10.1.3 - DISA-STIG-RHEL-08-010359 - 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 - Ensure AIDE Is Installed ansible.builtin.package: name: '{{ item }}' state: present with_items: - aide when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.3 - DISA-STIG-RHEL-08-010359 - 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 - Build and Test AIDE Database ansible.builtin.command: /usr/sbin/aide --init changed_when: true when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.3 - DISA-STIG-RHEL-08-010359 - 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 - Check Whether the Stock AIDE Database Exists ansible.builtin.stat: path: /var/lib/aide/aide.db.new.gz register: aide_database_stat when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.3 - DISA-STIG-RHEL-08-010359 - 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 - Stage AIDE Database ansible.builtin.copy: src: /var/lib/aide/aide.db.new.gz dest: /var/lib/aide/aide.db.gz backup: true remote_src: true when: - '"kernel" in ansible_facts.packages' - (aide_database_stat.stat.exists is defined and aide_database_stat.stat.exists) tags: - CJIS-5.10.1.3 - DISA-STIG-RHEL-08-010359 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-030650 - 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 Verify the Audit Tools - Gather List of Packages tags: - DISA-STIG-RHEL-08-030650 - NIST-800-53-AU-9(3) - NIST-800-53-AU-9(3).1 - aide_check_audit_tools - aide_check_audit_tools - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy ansible.builtin.package_facts: manager: auto when: '"kernel" in ansible_facts.packages' - name: Ensure aide is installed package: name: '{{ item }}' state: present with_items: - aide when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030650 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030650 - 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+selinux+xattrs+sha512' with_items: '{{ audit_tools }}' when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030650 - 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+selinux+xattrs+sha512' with_items: '{{ audit_tools }}' when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030650 - 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: Gather the package facts package_facts: manager: auto tags: - 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: Ensure AIDE is installed package: name: '{{ item }}' state: present with_items: - aide when: '"kernel" in ansible_facts.packages' tags: - 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: - '"kernel" in ansible_facts.packages' - ansible_os_family == "RedHat" or ansible_os_family == "Suse" tags: - 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: - '"kernel" in ansible_facts.packages' - ansible_os_family == "Debian" tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: - DISA-STIG-RHEL-08-010020 - 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 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.7 - configure_crypto_policy - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy - name: Verify that Crypto Policy is Set (runtime) command: /usr/bin/update-crypto-policies --set {{ var_system_crypto_policy }} tags: - DISA-STIG-RHEL-08-010020 - 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 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.7 - configure_crypto_policy - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy - name: Configure SSH to use System Crypto Policy lineinfile: dest: /etc/sysconfig/sshd state: absent regexp: (?i)^\s*CRYPTO_POLICY.*$ tags: - DISA-STIG-RHEL-08-010287 - 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 - PCI-DSSv4-2.2.7 - configure_ssh_crypto_policy - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - name: Gather the package facts package_facts: manager: auto tags: - 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: Ensure gdm is removed package: name: gdm state: absent when: '"gdm" in ansible_facts.packages' tags: - 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: - PCI-DSS-Req-6.2 - PCI-DSSv4-8.2 - PCI-DSSv4-8.2.8 - dconf_db_up_to_date - high_severity - low_complexity - medium_disruption - no_reboot_needed - unknown_strategy - name: Run dconf update ansible.builtin.command: cmd: dconf update when: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - PCI-DSS-Req-6.2 - PCI-DSSv4-8.2 - PCI-DSSv4-8.2.8 - 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: - DISA-STIG-RHEL-08-020032 - 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: Disable the GNOME3 Login User List ini_file: dest: /etc/dconf/db/gdm.d/00-security-settings section: org/gnome/login-screen option: disable-user-list value: 'true' no_extra_spaces: true create: true when: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - DISA-STIG-RHEL-08-020032 - 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/gdm.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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - DISA-STIG-RHEL-08-020032 - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - DISA-STIG-RHEL-08-020032 - 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: - gnome_gdm_disable_xdmcp - high_severity - low_complexity - medium_disruption - no_reboot_needed - unknown_strategy - name: Disable XDMCP in GDM ini_file: path: /etc/gdm/custom.conf section: xdmcp option: Enable value: 'false' create: true mode: 420 when: '"gdm" in ansible_facts.packages' tags: - 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: - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-3.4 - PCI-DSSv4-3.4.2 - dconf_gnome_disable_automount - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-3.4 - PCI-DSSv4-3.4.2 - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-3.4 - PCI-DSSv4-3.4.2 - dconf_gnome_disable_automount - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-3.4 - PCI-DSSv4-3.4.2 - 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: - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-3.4 - PCI-DSSv4-3.4.2 - dconf_gnome_disable_automount_open - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-3.4 - PCI-DSSv4-3.4.2 - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-3.4 - PCI-DSSv4-3.4.2 - dconf_gnome_disable_automount_open - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - NIST-800-171-3.1.7 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-3.4 - PCI-DSSv4-3.4.2 - 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: - 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: 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - 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: - CJIS-5.5.5 - DISA-STIG-RHEL-08-020060 - 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 - PCI-DSSv4-8.2.8 - dconf_gnome_screensaver_idle_delay - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CJIS-5.5.5 - DISA-STIG-RHEL-08-020060 - 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 - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - CJIS-5.5.5 - DISA-STIG-RHEL-08-020060 - 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 - 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: - DISA-STIG-RHEL-08-020031 - 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 - PCI-DSSv4-8.2.8 - dconf_gnome_screensaver_lock_delay - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - DISA-STIG-RHEL-08-020031 - 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 - PCI-DSSv4-8.2.8 - dconf_gnome_screensaver_lock_delay - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Dconf Update command: dconf update when: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - DISA-STIG-RHEL-08-020031 - 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 - PCI-DSSv4-8.2.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: - DISA-STIG-RHEL-08-020080 - 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: 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - DISA-STIG-RHEL-08-020080 - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - DISA-STIG-RHEL-08-020080 - 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: - DISA-STIG-RHEL-08-020081 - NIST-800-171-3.1.10 - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.8 - PCI-DSSv4-8.2 - PCI-DSSv4-8.2.8 - dconf_gnome_session_idle_user_locks - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - DISA-STIG-RHEL-08-020081 - NIST-800-171-3.1.10 - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.8 - PCI-DSSv4-8.2 - 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: - '"gdm" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - DISA-STIG-RHEL-08-020081 - NIST-800-171-3.1.10 - NIST-800-53-CM-6(a) - PCI-DSS-Req-8.1.8 - PCI-DSSv4-8.2 - PCI-DSSv4-8.2.8 - dconf_gnome_session_idle_user_locks - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_sudo_installed - name: Ensure sudo is installed package: name: sudo state: present when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_sudo_installed - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSS-Req-10.2.5 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_add_use_pty - 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: '"sudo" in ansible_facts.packages' tags: - PCI-DSS-Req-10.2.5 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - 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: - PCI-DSS-Req-10.2.5 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - low_severity - no_reboot_needed - restrict_strategy - sudo_custom_logfile - 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: '"sudo" in ansible_facts.packages' tags: - PCI-DSS-Req-10.2.5 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - 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: - '"sudo" in ansible_facts.packages' - edit_sudoers_logfile_option is defined and not edit_sudoers_logfile_option.changed tags: - PCI-DSS-Req-10.2.5 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - low_severity - no_reboot_needed - restrict_strategy - sudo_custom_logfile - name: Find /etc/sudoers.d/ files ansible.builtin.find: paths: - /etc/sudoers.d/ register: sudoers tags: - NIST-800-53-CM-6(a) - NIST-800-53-IA-11 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_authentication - name: Remove lines containing NOPASSWD from sudoers files ansible.builtin.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: - NIST-800-53-CM-6(a) - NIST-800-53-IA-11 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_authentication - name: Find /etc/sudoers.d/ files ansible.builtin.find: paths: - /etc/sudoers.d/ register: sudoers tags: - NIST-800-53-CM-6(a) - NIST-800-53-IA-11 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_authentication - name: Remove lines containing !authenticate from sudoers files ansible.builtin.replace: regexp: (^(?!#).*[\s]+\!authenticate.*$) replace: '# \g<1>' path: '{{ item.path }}' validate: /usr/sbin/visudo -cf %s with_items: - path: /etc/sudoers - '{{ sudoers.files }}' tags: - NIST-800-53-CM-6(a) - NIST-800-53-IA-11 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_authentication - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-010384 - NIST-800-53-IA-11 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_reauthentication - name: Require Re-Authentication When Using the sudo Command - Find /etc/sudoers.d/* files containing 'Defaults timestamp_timeout' ansible.builtin.find: path: /etc/sudoers.d patterns: '*' contains: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=.* register: sudoers_d_defaults_timestamp_timeout when: '"sudo" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010384 - NIST-800-53-IA-11 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_reauthentication - name: Require Re-Authentication When Using the sudo Command - Remove 'Defaults timestamp_timeout' from /etc/sudoers.d/* files ansible.builtin.lineinfile: path: '{{ item.path }}' regexp: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=.* state: absent with_items: '{{ sudoers_d_defaults_timestamp_timeout.files }}' when: '"sudo" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010384 - NIST-800-53-IA-11 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_reauthentication - name: Require Re-Authentication When Using the sudo Command - Ensure timestamp_timeout has the appropriate value in /etc/sudoers ansible.builtin.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: '"sudo" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010384 - NIST-800-53-IA-11 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_reauthentication - name: Require Re-Authentication When Using the sudo Command - Enable timestamp_timeout option with correct value in /etc/sudoers ansible.builtin.lineinfile: path: /etc/sudoers line: Defaults timestamp_timeout={{ var_sudo_timestamp_timeout }} validate: /usr/sbin/visudo -cf %s when: - '"sudo" in ansible_facts.packages' - | edit_sudoers_timestamp_timeout_option is defined and not edit_sudoers_timestamp_timeout_option.changed tags: - DISA-STIG-RHEL-08-010384 - NIST-800-53-IA-11 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_reauthentication - name: Require Re-Authentication When Using the sudo Command - Remove timestamp_timeout wrong values in /etc/sudoers ansible.builtin.lineinfile: path: /etc/sudoers regexp: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=[\s]*(?!{{ var_sudo_timestamp_timeout }}\b)[-]?\w+\b.*$ state: absent validate: /usr/sbin/visudo -cf %s when: '"sudo" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010384 - NIST-800-53-IA-11 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sudo_require_reauthentication - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.10.4.1 - DISA-STIG-RHEL-08-010370 - 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 - PCI-DSSv4-6.3.3 - configure_strategy - ensure_gpgcheck_globally_activated - high_severity - low_complexity - medium_disruption - no_reboot_needed - name: Ensure GPG check is globally activated ini_file: dest: /etc/yum.conf section: main option: gpgcheck value: 1 no_extra_spaces: true create: false when: '"yum" in ansible_facts.packages' tags: - CJIS-5.10.4.1 - DISA-STIG-RHEL-08-010370 - 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 - PCI-DSSv4-6.3.3 - configure_strategy - ensure_gpgcheck_globally_activated - high_severity - low_complexity - medium_disruption - no_reboot_needed - name: Grep for yum repo section names shell: | set -o pipefail grep -HEr '^\[.+\]' -r /etc/yum.repos.d/ register: repo_grep_results failed_when: repo_grep_results.rc not in [0, 1] changed_when: false tags: - CJIS-5.10.4.1 - DISA-STIG-RHEL-08-010370 - 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 - PCI-DSSv4-6.3.3 - enable_strategy - ensure_gpgcheck_never_disabled - high_severity - low_complexity - medium_disruption - no_reboot_needed - name: Set gpgcheck=1 for each yum repo ini_file: path: '{{ item[0] }}' section: '{{ item[1] }}' option: gpgcheck value: '1' no_extra_spaces: true loop: '{{ repo_grep_results.stdout |regex_findall( ''(.+\.repo):\[(.+)\]\n?'' ) if repo_grep_results is not skipped else [] }}' when: repo_grep_results is not skipped tags: - CJIS-5.10.4.1 - DISA-STIG-RHEL-08-010370 - 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 - PCI-DSSv4-6.3.3 - enable_strategy - ensure_gpgcheck_never_disabled - high_severity - low_complexity - medium_disruption - no_reboot_needed - name: Enable authselect - Check Current authselect Profile ansible.builtin.command: cmd: authselect current register: result_authselect_current changed_when: false failed_when: false tags: - NIST-800-53-AC-3 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.4 - configure_strategy - enable_authselect - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Enable authselect - Try to Select an authselect Profile ansible.builtin.command: cmd: authselect select "{{ var_authselect_profile }}" register: result_authselect_select changed_when: result_authselect_select.rc == 0 failed_when: false when: result_authselect_current.rc != 0 tags: - NIST-800-53-AC-3 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.4 - configure_strategy - enable_authselect - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Enable authselect - Verify If pam Has Been Altered ansible.builtin.command: cmd: rpm -qV pam register: result_altered_authselect changed_when: false failed_when: false when: - result_authselect_select is not skipped - result_authselect_select.rc != 0 tags: - NIST-800-53-AC-3 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.4 - configure_strategy - enable_authselect - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Enable authselect - Informative Message Based on authselect Integrity Check ansible.builtin.assert: that: - result_authselect_current.rc == 0 or result_altered_authselect is skipped or result_altered_authselect.rc == 0 fail_msg: - authselect is not used but files from the 'pam' package have been altered, so the authselect configuration won't be forced. tags: - NIST-800-53-AC-3 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.4 - configure_strategy - enable_authselect - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Enable authselect - Force authselect Profile Selection ansible.builtin.command: cmd: authselect select --force "{{ var_authselect_profile }}" when: - result_authselect_current.rc != 0 - result_authselect_select.rc != 0 - result_altered_authselect.rc == 0 tags: - NIST-800-53-AC-3 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.4 - configure_strategy - enable_authselect - low_complexity - medium_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - banner_etc_issue_cis - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure Local Login Warning Banner Is Configured Properly - Copy using inline content ansible.builtin.copy: content: '{{ cis_banner_text }}' dest: /etc/issue when: '"kernel" in ansible_facts.packages' tags: - banner_etc_issue_cis - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - banner_etc_issue_net_cis - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure Remote Login Warning Banner Is Configured Properly - Copy using inline content ansible.builtin.copy: content: '{{ cis_banner_text }}' dest: /etc/issue.net when: '"kernel" in ansible_facts.packages' tags: - banner_etc_issue_net_cis - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - banner_etc_motd_cis - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure Message Of The Day Is Configured Properly - Copy using inline content ansible.builtin.copy: content: '{{ cis_banner_text }}' dest: /etc/motd when: '"kernel" in ansible_facts.packages' tags: - banner_etc_motd_cis - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Test for existence /etc/issue stat: path: /etc/issue register: file_exists tags: - configure_strategy - file_groupowner_etc_issue - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/issue file: path: /etc/issue group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.8 - configure_strategy - file_groupowner_etc_issue_net - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/issue.net file: path: /etc/issue.net group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.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: - configure_strategy - file_groupowner_etc_motd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/motd file: path: /etc/motd group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_owner_etc_issue - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/issue file: path: /etc/issue owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.8 - configure_strategy - file_owner_etc_issue_net - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/issue.net file: path: /etc/issue.net owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.8 - 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: - configure_strategy - file_owner_etc_motd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/motd file: path: /etc/motd owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_permissions_etc_issue - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xws,o-xwt on /etc/issue file: path: /etc/issue mode: u-xs,g-xws,o-xwt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.8 - configure_strategy - file_permissions_etc_issue_net - low_complexity - low_disruption - medium_severity - no_reboot_needed - 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: file_exists.stat is defined and file_exists.stat.exists tags: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.8 - 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: - configure_strategy - file_permissions_etc_motd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xws,o-xwt on /etc/motd file: path: /etc/motd mode: u-xs,g-xws,o-xwt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - DISA-STIG-RHEL-08-010049 - 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: Enable GNOME3 Login Warning Banner ini_file: dest: /etc/dconf/db/gdm.d/00-security-settings section: org/gnome/login-screen option: banner-message-enable value: 'true' create: true no_extra_spaces: true when: '"gdm" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010049 - 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/gdm.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: '"gdm" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010049 - 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: '"gdm" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010049 - 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: - DISA-STIG-RHEL-08-010050 - 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/{{ item }} owner: root group: root mode: 493 state: directory with_items: - gdm.d - gdm.d/locks when: '"gdm" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010050 - 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/gdm.d/{{ item }} owner: root group: root mode: 420 state: touch with_items: - 00-security-settings - locks/00-security-settings-lock when: '"gdm" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010050 - 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/gdm.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: '"gdm" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010050 - 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/gdm.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: '"gdm" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010050 - 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: '"gdm" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010050 - 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: - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_pam_pwquality_installed - name: Ensure libpwquality is installed package: name: libpwquality state: present when: '"pam" in ansible_facts.packages' tags: - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_pam_pwquality_installed - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth File. - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present tags: - DISA-STIG-RHEL-08-020026 - NIST-800-53-AC-7 (a) - account_password_pam_faillock_password_auth - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth File. - Remediation where authselect tool is present block: - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth File. - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth File. - 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: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth File. - 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: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth File. - 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: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth File. - 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: result_authselect_present.stat.exists tags: - DISA-STIG-RHEL-08-020026 - NIST-800-53-AC-7 (a) - account_password_pam_faillock_password_auth - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth File. - Remediation where authselect tool is not present block: - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth File. - 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: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth File. - 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: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth File. - 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: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth File. - 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: not result_authselect_present.stat.exists tags: - DISA-STIG-RHEL-08-020026 - NIST-800-53-AC-7 (a) - account_password_pam_faillock_password_auth - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth File. - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present tags: - DISA-STIG-RHEL-08-020025 - NIST-800-53-AC-7 (a) - account_password_pam_faillock_system_auth - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth File. - Remediation where authselect tool is present block: - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth File. - Check integrity of authselect current profile ansible.builtin.command: cmd: authselect check register: result_authselect_check_cmd changed_when: false failed_when: false - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth File. - 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: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth File. - 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: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth File. - 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: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth File. - 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: result_authselect_present.stat.exists tags: - DISA-STIG-RHEL-08-020025 - NIST-800-53-AC-7 (a) - account_password_pam_faillock_system_auth - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth File. - Remediation where authselect tool is not present block: - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth File. - 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: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth File. - 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: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth File. - 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: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth File. - 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: not result_authselect_present.stat.exists tags: - DISA-STIG-RHEL-08-020025 - NIST-800-53-AC-7 (a) - account_password_pam_faillock_system_auth - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020220 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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 if system relies on authselect tool' ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present when: '"pam" in ansible_facts.packages' tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020220 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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 sssd register: result_authselect_available_features changed_when: false when: - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020220 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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: - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists - result_authselect_available_features.stdout is search("with-pwhistory") tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020220 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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 - Define a fact for control already filtered in case filters are used' ansible.builtin.set_fact: pam_module_control: '{{ var_password_pam_remember_control_flag.split(",")[0] }}' - 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+{{ pam_module_control | regex_escape() }}\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{{ pam_module_control }} \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 {{ pam_module_control }} 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) 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: - '"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: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020220 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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: '"pam" in ansible_facts.packages' tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020220 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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 - Define a fact for control already filtered in case filters are used' ansible.builtin.set_fact: pam_module_control: '' - 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: - '"pam" in ansible_facts.packages' - result_pwhistory_conf_check.stat.exists tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020220 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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 - Define a fact for control already filtered in case filters are used' ansible.builtin.set_fact: pam_module_control: requisite - 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+{{ pam_module_control | regex_escape() }}\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{{ pam_module_control }} \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 {{ pam_module_control }} 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) 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 - Define a fact for control already filtered in case filters are used' ansible.builtin.set_fact: pam_module_control: requisite - 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+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*\sremember\b state: absent check_mode: true changed_when: false register: result_pam_module_accounts_password_pam_pwhistory_remember_password_auth_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+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so.*) line: \1 remember={{ var_password_pam_remember }} state: present register: result_pam_accounts_password_pam_pwhistory_remember_password_auth_add when: - result_pam_module_accounts_password_pam_pwhistory_remember_password_auth_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+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s+.*)(remember)=[0-9a-zA-Z]+\s*(.*) line: \1\2={{ var_password_pam_remember }} \3 register: result_pam_accounts_password_pam_pwhistory_remember_password_auth_edit when: - result_pam_module_accounts_password_pam_pwhistory_remember_password_auth_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: - '"pam" in ansible_facts.packages' - not result_pwhistory_conf_check.stat.exists tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020220 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020221 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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 if system relies on authselect tool' ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present when: '"pam" in ansible_facts.packages' tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020221 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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 sssd register: result_authselect_available_features changed_when: false when: - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020221 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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: - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists - result_authselect_available_features.stdout is search("with-pwhistory") tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020221 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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 - Define a fact for control already filtered in case filters are used' ansible.builtin.set_fact: pam_module_control: '{{ var_password_pam_remember_control_flag.split(",")[0] }}' - 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+{{ pam_module_control | regex_escape() }}\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{{ pam_module_control }} \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 {{ pam_module_control }} 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) 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: - '"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: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020221 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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: '"pam" in ansible_facts.packages' tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020221 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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 - Define a fact for control already filtered in case filters are used' ansible.builtin.set_fact: pam_module_control: '' - 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: - '"pam" in ansible_facts.packages' - result_pwhistory_conf_check.stat.exists tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020221 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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 - Define a fact for control already filtered in case filters are used' ansible.builtin.set_fact: pam_module_control: requisite - 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+{{ pam_module_control | regex_escape() }}\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{{ pam_module_control }} \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 {{ pam_module_control }} 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) 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 - Define a fact for control already filtered in case filters are used' ansible.builtin.set_fact: pam_module_control: requisite - 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+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*\sremember\b state: absent check_mode: true changed_when: false register: result_pam_module_accounts_password_pam_pwhistory_remember_system_auth_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+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so.*) line: \1 remember={{ var_password_pam_remember }} state: present register: result_pam_accounts_password_pam_pwhistory_remember_system_auth_add when: - result_pam_module_accounts_password_pam_pwhistory_remember_system_auth_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+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s+.*)(remember)=[0-9a-zA-Z]+\s*(.*) line: \1\2={{ var_password_pam_remember }} \3 register: result_pam_accounts_password_pam_pwhistory_remember_system_auth_edit when: - result_pam_module_accounts_password_pam_pwhistory_remember_system_auth_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: - '"pam" in ansible_facts.packages' - not result_pwhistory_conf_check.stat.exists tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020221 - 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 - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.7 - 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: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020011 - 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 - 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 if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present when: '"pam" in ansible_facts.packages' tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020011 - 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 - 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: - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020011 - 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 - 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: - '"pam" in ansible_facts.packages' - not result_authselect_present.stat.exists tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020011 - 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 - 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: '"pam" in ansible_facts.packages' tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020011 - 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 - 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: - '"pam" in ansible_facts.packages' - result_faillock_conf_check.stat.exists tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020011 - 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 - 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 - Define a fact for control already filtered in case filters are used ansible.builtin.set_fact: pam_module_control: '' - 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 - Define a fact for control already filtered in case filters are used ansible.builtin.set_fact: pam_module_control: '' - 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: - '"pam" in ansible_facts.packages' - result_faillock_conf_check.stat.exists tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020011 - 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 - 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: - '"pam" in ansible_facts.packages' - not result_faillock_conf_check.stat.exists tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020011 - 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 - 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: - DISA-STIG-RHEL-08-020023 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(c) - accounts_passwords_pam_faillock_deny_root - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Configure the root Account for Failed Password Attempts - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present when: '"pam" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-020023 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(c) - accounts_passwords_pam_faillock_deny_root - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Configure the root Account for Failed Password Attempts - Remediation where authselect tool is present block: - name: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists tags: - DISA-STIG-RHEL-08-020023 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(c) - accounts_passwords_pam_faillock_deny_root - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Configure the root Account for Failed Password Attempts - Remediation where authselect tool is not present block: - name: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: - '"pam" in ansible_facts.packages' - not result_authselect_present.stat.exists tags: - DISA-STIG-RHEL-08-020023 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(c) - accounts_passwords_pam_faillock_deny_root - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Configure the root Account 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: '"pam" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-020023 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(c) - accounts_passwords_pam_faillock_deny_root - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Configure the root Account for Failed Password Attempts - Ensure the pam_faillock.so even_deny_root parameter in /etc/security/faillock.conf ansible.builtin.lineinfile: path: /etc/security/faillock.conf regexp: ^\s*even_deny_root line: even_deny_root state: present when: - '"pam" in ansible_facts.packages' - result_faillock_conf_check.stat.exists tags: - DISA-STIG-RHEL-08-020023 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(c) - accounts_passwords_pam_faillock_deny_root - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Configure the root Account for Failed Password Attempts - Ensure the pam_faillock.so even_deny_root parameter not in PAM files block: - name: Configure the root Account 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: Configure the root Account for Failed Password Attempts - Check the proper remediation for the system block: - name: Configure the root Account 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: Configure the root Account for Failed Password Attempts - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: Configure the root Account for Failed Password Attempts - Ensure authselect custom profile is used if authselect is present block: - name: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account for Failed Password Attempts - Define a fact for control already filtered in case filters are used ansible.builtin.set_fact: pam_module_control: '' - name: Configure the root Account for Failed Password Attempts - Ensure the "even_deny_root" option from "pam_faillock.so" is not present in {{ pam_file_path }} ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: (.*auth.*pam_faillock.so.*)\beven_deny_root\b=?[0-9a-zA-Z]*(.*) replace: \1\2 register: result_pam_option_removal - name: Configure the root Account 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: Configure the root Account 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: Configure the root Account for Failed Password Attempts - Check the proper remediation for the system block: - name: Configure the root Account 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: Configure the root Account for Failed Password Attempts - Check if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present - name: Configure the root Account for Failed Password Attempts - Ensure authselect custom profile is used if authselect is present block: - name: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account 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: Configure the root Account for Failed Password Attempts - Define a fact for control already filtered in case filters are used ansible.builtin.set_fact: pam_module_control: '' - name: Configure the root Account for Failed Password Attempts - Ensure the "even_deny_root" option from "pam_faillock.so" is not present in {{ pam_file_path }} ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: (.*auth.*pam_faillock.so.*)\beven_deny_root\b=?[0-9a-zA-Z]*(.*) replace: \1\2 register: result_pam_option_removal - name: Configure the root Account 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: - '"pam" in ansible_facts.packages' - result_faillock_conf_check.stat.exists tags: - DISA-STIG-RHEL-08-020023 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(c) - accounts_passwords_pam_faillock_deny_root - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Configure the root Account for Failed Password Attempts - Ensure the pam_faillock.so even_deny_root parameter in PAM files block: - name: Configure the root Account for Failed Password Attempts - Check if pam_faillock.so even_deny_root parameter is already enabled in pam files ansible.builtin.lineinfile: path: /etc/pam.d/system-auth regexp: .*auth.*pam_faillock\.so (preauth|authfail).*even_deny_root state: absent check_mode: true changed_when: false register: result_pam_faillock_even_deny_root_parameter_is_present - name: Configure the root Account for Failed Password Attempts - Ensure the inclusion of pam_faillock.so preauth even_deny_root 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 even_deny_root state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_even_deny_root_parameter_is_present.found == 0 - name: Configure the root Account for Failed Password Attempts - Ensure the inclusion of pam_faillock.so authfail even_deny_root 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 even_deny_root state: present loop: - /etc/pam.d/system-auth - /etc/pam.d/password-auth when: - result_pam_faillock_even_deny_root_parameter_is_present.found == 0 when: - '"pam" in ansible_facts.packages' - not result_faillock_conf_check.stat.exists tags: - DISA-STIG-RHEL-08-020023 - NIST-800-53-AC-7(b) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(c) - accounts_passwords_pam_faillock_deny_root - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020014 - DISA-STIG-RHEL-08-020015 - 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 - 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 if system relies on authselect tool ansible.builtin.stat: path: /usr/bin/authselect register: result_authselect_present when: '"pam" in ansible_facts.packages' tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020014 - DISA-STIG-RHEL-08-020015 - 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 - 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: - '"pam" in ansible_facts.packages' - result_authselect_present.stat.exists tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020014 - DISA-STIG-RHEL-08-020015 - 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 - 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: - '"pam" in ansible_facts.packages' - not result_authselect_present.stat.exists tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020014 - DISA-STIG-RHEL-08-020015 - 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 - 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: '"pam" in ansible_facts.packages' tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020014 - DISA-STIG-RHEL-08-020015 - 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 - 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: - '"pam" in ansible_facts.packages' - result_faillock_conf_check.stat.exists tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020014 - DISA-STIG-RHEL-08-020015 - 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 - 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 - Define a fact for control already filtered in case filters are used ansible.builtin.set_fact: pam_module_control: '' - 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 - Define a fact for control already filtered in case filters are used ansible.builtin.set_fact: pam_module_control: '' - 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: - '"pam" in ansible_facts.packages' - result_faillock_conf_check.stat.exists tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020014 - DISA-STIG-RHEL-08-020015 - 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 - 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: - '"pam" in ansible_facts.packages' - not result_faillock_conf_check.stat.exists tags: - CJIS-5.5.3 - DISA-STIG-RHEL-08-020014 - DISA-STIG-RHEL-08-020015 - 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 - 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: - DISA-STIG-RHEL-08-020300 - 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_dictcheck - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure PAM Enforces Password Requirements - Prevent the Use of Dictionary Words - Ensure PAM variable dictcheck is set accordingly ansible.builtin.lineinfile: create: true dest: /etc/security/pwquality.conf regexp: ^#?\s*dictcheck line: dictcheck = {{ var_password_pam_dictcheck }} when: '"pam" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-020300 - 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_dictcheck - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020170 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(b) - NIST-800-53-IA-5(4) - NIST-800-53-IA-5(c) - accounts_password_pam_difok - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure PAM Enforces Password Requirements - Minimum Different Characters - Ensure PAM variable difok is set accordingly ansible.builtin.lineinfile: create: true dest: /etc/security/pwquality.conf regexp: ^#?\s*difok line: difok = {{ var_password_pam_difok }} when: '"pam" in ansible_facts.packages' tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020170 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(b) - NIST-800-53-IA-5(4) - NIST-800-53-IA-5(c) - accounts_password_pam_difok - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - 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_enforce_root - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure PAM Enforces Password Requirements - Enforce for root User lineinfile: path: /etc/security/pwquality.conf create: true regexp: '' line: enforce_for_root state: present when: '"pam" in ansible_facts.packages' tags: - 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_enforce_root - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-020150 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(4) - NIST-800-53-IA-5(c) - accounts_password_pam_maxrepeat - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set Password Maximum Consecutive Repeating Characters - Ensure PAM variable maxrepeat is set accordingly ansible.builtin.lineinfile: create: true dest: /etc/security/pwquality.conf regexp: ^#?\s*maxrepeat line: maxrepeat = {{ var_password_pam_maxrepeat }} when: '"pam" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-020150 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(4) - NIST-800-53-IA-5(c) - accounts_password_pam_maxrepeat - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-020160 - 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: 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: '"pam" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-020160 - 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: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020230 - 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 - PCI-DSSv4-8.3.6 - accounts_password_pam_minlen - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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: '"pam" in ansible_facts.packages' tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020230 - 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 - PCI-DSSv4-8.3.6 - 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: - 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 - PCI-DSSv4-8.3.2 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - set_password_hashing_algorithm_libuserconf - name: Set Password Hashing Algorithm in /etc/libuser.conf - Set Password Hashing Algorithm in /etc/libuser.conf ansible.builtin.lineinfile: dest: /etc/libuser.conf insertafter: ^\s*\[defaults] regexp: ^#?crypt_style line: crypt_style = {{ var_password_hashing_algorithm_pam }} state: present create: true when: '"libuser" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-8.3.2 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - set_password_hashing_algorithm_libuserconf - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.6.2.2 - DISA-STIG-RHEL-08-010110 - 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 - PCI-DSSv4-8.3.2 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - set_password_hashing_algorithm_logindefs - 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: '"shadow-utils" in ansible_facts.packages' tags: - CJIS-5.6.2.2 - DISA-STIG-RHEL-08-010110 - 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 - 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: - CJIS-5.6.2.2 - DISA-STIG-RHEL-08-010160 - 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 if /etc/pam.d/password-auth file is present ansible.builtin.stat: path: /etc/pam.d/password-auth register: result_pam_file_present when: '"pam" in ansible_facts.packages' tags: - CJIS-5.6.2.2 - DISA-STIG-RHEL-08-010160 - 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 - Define a fact for control already filtered in case filters are used ansible.builtin.set_fact: pam_module_control: sufficient - 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+{{ pam_module_control | regex_escape() }}\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: \1{{ pam_module_control }} \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 {{ pam_module_control }} 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) 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 - Define a fact for control already filtered in case filters are used ansible.builtin.set_fact: pam_module_control: sufficient - 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+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\s{{ var_password_hashing_algorithm_pam }}\b state: absent check_mode: true changed_when: false register: result_pam_module_set_password_hashing_algorithm_passwordauth_option_present - name: Set PAM's Password Hashing Algorithm - password-auth - Ensure the "{{ var_password_hashing_algorithm_pam }}" 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+{{ pam_module_control | regex_escape() }}\s+pam_unix.so.*) line: \1 {{ var_password_hashing_algorithm_pam }} state: present register: result_pam_set_password_hashing_algorithm_passwordauth_add when: - result_pam_module_set_password_hashing_algorithm_passwordauth_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_set_password_hashing_algorithm_passwordauth_add is defined and result_pam_set_password_hashing_algorithm_passwordauth_add.changed) or (result_pam_set_password_hashing_algorithm_passwordauth_edit is defined and result_pam_set_password_hashing_algorithm_passwordauth_edit.changed) when: - '"pam" in ansible_facts.packages' - result_pam_file_present.stat.exists tags: - CJIS-5.6.2.2 - DISA-STIG-RHEL-08-010160 - 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 if /etc/pam.d/password-auth File is Present ansible.builtin.stat: path: /etc/pam.d/password-auth register: result_pam_file_present when: '"pam" in ansible_facts.packages' tags: - CJIS-5.6.2.2 - DISA-STIG-RHEL-08-010160 - 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 - Ensure That Only the Correct Hashing Algorithm Option For pam_unix.so Is Used in /etc/pam.d/password-auth ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: (^\s*password.*pam_unix\.so.*)\b{{ item }}\b\s*(.*) replace: \1\2 when: item != var_password_hashing_algorithm_pam loop: - sha512 - yescrypt - gost_yescrypt - blowfish - sha256 - md5 - bigcrypt register: result_pam_hashing_options_removal - 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_hashing_options_removal is changed when: - '"pam" in ansible_facts.packages' - result_pam_file_present.stat.exists tags: - CJIS-5.6.2.2 - DISA-STIG-RHEL-08-010160 - 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: - CJIS-5.6.2.2 - DISA-STIG-RHEL-08-010159 - 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 - 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 if /etc/pam.d/system-auth file is present ansible.builtin.stat: path: /etc/pam.d/system-auth register: result_pam_file_present when: '"pam" in ansible_facts.packages' tags: - CJIS-5.6.2.2 - DISA-STIG-RHEL-08-010159 - 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 - 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 - Define a fact for control already filtered in case filters are used ansible.builtin.set_fact: pam_module_control: sufficient - 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+{{ pam_module_control | regex_escape() }}\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: \1{{ pam_module_control }} \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 {{ pam_module_control }} 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) 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 - Define a fact for control already filtered in case filters are used ansible.builtin.set_fact: pam_module_control: sufficient - 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+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\s{{ var_password_hashing_algorithm_pam }}\b state: absent check_mode: true changed_when: false register: result_pam_module_set_password_hashing_algorithm_systemauth_option_present - name: Set PAM's Password Hashing Algorithm - Ensure the "{{ var_password_hashing_algorithm_pam }}" 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+{{ pam_module_control | regex_escape() }}\s+pam_unix.so.*) line: \1 {{ var_password_hashing_algorithm_pam }} state: present register: result_pam_set_password_hashing_algorithm_systemauth_add when: - result_pam_module_set_password_hashing_algorithm_systemauth_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_set_password_hashing_algorithm_systemauth_add is defined and result_pam_set_password_hashing_algorithm_systemauth_add.changed) or (result_pam_set_password_hashing_algorithm_systemauth_edit is defined and result_pam_set_password_hashing_algorithm_systemauth_edit.changed) when: - '"pam" in ansible_facts.packages' - result_pam_file_present.stat.exists tags: - CJIS-5.6.2.2 - DISA-STIG-RHEL-08-010159 - 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 - 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 if /etc/pam.d/system-auth File is Present ansible.builtin.stat: path: /etc/pam.d/system-auth register: result_pam_file_present when: '"pam" in ansible_facts.packages' tags: - CJIS-5.6.2.2 - DISA-STIG-RHEL-08-010159 - 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 - 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 - Ensure That Only the Correct Hashing Algorithm Option For pam_unix.so Is Used in /etc/pam.d/system-auth ansible.builtin.replace: dest: '{{ pam_file_path }}' regexp: (^\s*password.*pam_unix\.so.*)\b{{ item }}\b\s*(.*) replace: \1\2 when: item != var_password_hashing_algorithm_pam loop: - sha512 - yescrypt - gost_yescrypt - blowfish - sha256 - md5 - bigcrypt register: result_pam_hashing_options_removal - 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_hashing_options_removal is changed when: - '"pam" in ansible_facts.packages' - result_pam_file_present.stat.exists tags: - CJIS-5.6.2.2 - DISA-STIG-RHEL-08-010159 - 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 - 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: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020260 - 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 - PCI-DSSv4-8.2.6 - account_disable_post_pw_expiration - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set Account Expiration Following Inactivity lineinfile: create: true dest: /etc/default/useradd regexp: ^INACTIVE line: INACTIVE={{ var_account_disable_post_pw_expiration }} when: '"shadow-utils" in ansible_facts.packages' tags: - CJIS-5.6.2.1.1 - DISA-STIG-RHEL-08-020260 - 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 - 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: - CJIS-5.6.2.1 - DISA-STIG-RHEL-08-020200 - 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 - PCI-DSSv4-8.3.9 - accounts_maximum_age_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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: '"shadow-utils" in ansible_facts.packages' tags: - CJIS-5.6.2.1 - DISA-STIG-RHEL-08-020200 - 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 - PCI-DSSv4-8.3.9 - accounts_maximum_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: - DISA-STIG-RHEL-08-020210 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.9 - accounts_password_set_max_life_existing - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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: user_names.stdout_lines | length > 0 tags: - DISA-STIG-RHEL-08-020210 - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.9 - accounts_password_set_max_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: - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.9 - accounts_password_set_warn_age_existing - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - 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: result_pass_warn_age_user_names is not skipped and result_pass_warn_age_user_names.stdout_lines | length > 0 tags: - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(d) - NIST-800-53-IA-5(f) - PCI-DSSv4-8.3 - PCI-DSSv4-8.3.9 - 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: - 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 - PCI-DSSv4-8.3.9 - accounts_password_warn_age_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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: '"shadow-utils" in ansible_facts.packages' tags: - 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 - 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: - 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 - PCI-DSSv4-8.2.6 - accounts_set_post_pw_existing - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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: user_names is not skipped and user_names.stdout_lines | length > 0 tags: - 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 - PCI-DSSv4-8.2.6 - accounts_set_post_pw_existing - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.5.2 - DISA-STIG-RHEL-08-020331 - DISA-STIG-RHEL-08-020332 - 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 - PCI-DSSv4-8.3.1 - configure_strategy - high_severity - low_complexity - medium_disruption - no_empty_passwords - no_reboot_needed - 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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.5.2 - DISA-STIG-RHEL-08-020331 - DISA-STIG-RHEL-08-020332 - 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 - PCI-DSSv4-8.3.1 - 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: - '"kernel" in ansible_facts.packages' - result_authselect_present.stat.exists tags: - CJIS-5.5.2 - DISA-STIG-RHEL-08-020331 - DISA-STIG-RHEL-08-020332 - 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 - PCI-DSSv4-8.3.1 - 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: - '"kernel" in ansible_facts.packages' - not result_authselect_present.stat.exists tags: - CJIS-5.5.2 - DISA-STIG-RHEL-08-020331 - DISA-STIG-RHEL-08-020332 - 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 - PCI-DSSv4-8.3.1 - configure_strategy - high_severity - low_complexity - medium_disruption - no_empty_passwords - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-010121 - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.2 - high_severity - low_complexity - low_disruption - no_empty_passwords_etc_shadow - no_reboot_needed - restrict_strategy - name: Collect users with no password command: | awk -F: '!$2 {print $1}' /etc/shadow register: users_nopasswd changed_when: false when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010121 - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.2 - 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: - '"kernel" in ansible_facts.packages' - users_nopasswd is not skipped and users_nopasswd.stdout_lines | length > 0 tags: - DISA-STIG-RHEL-08-010121 - NIST-800-53-CM-6(b) - NIST-800-53-CM-6.1(iv) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.2 - 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: - DISA-STIG-RHEL-08-040200 - 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 - PCI-DSSv4-8.2.1 - accounts_no_uid_except_zero - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy - 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: item.value.1 == '0' tags: - DISA-STIG-RHEL-08-040200 - 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 - PCI-DSSv4-8.2.1 - accounts_no_uid_except_zero - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - ensure_pam_wheel_group_empty - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure the Group Used by pam_wheel.so Module Exists on System and is Empty - Ensure {{ var_pam_wheel_group_for_su }} Group Exists ansible.builtin.group: name: '{{ var_pam_wheel_group_for_su }}' state: present when: '"pam" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - ensure_pam_wheel_group_empty - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure the Group Used by pam_wheel.so Module Exists on System and is Empty - Ensure {{ var_pam_wheel_group_for_su }} Group is Empty ansible.builtin.lineinfile: path: /etc/group regexp: ^({{ var_pam_wheel_group_for_su }}:[^:]+:[0-9]+:).*$ line: \1 backrefs: true when: '"pam" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - ensure_pam_wheel_group_empty - low_complexity - low_disruption - medium_severity - 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: - NIST-800-53-AC-6 - NIST-800-53-CM-6(a) - PCI-DSSv4-8.2 - PCI-DSSv4-8.2.2 - low_complexity - medium_disruption - medium_severity - no_password_auth_for_systemaccounts - no_reboot_needed - restrict_strategy - 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: - NIST-800-53-AC-6 - NIST-800-53-CM-6(a) - PCI-DSSv4-8.2 - PCI-DSSv4-8.2.2 - low_complexity - medium_disruption - medium_severity - no_password_auth_for_systemaccounts - no_reboot_needed - restrict_strategy - name: Ensure that System Accounts Are Locked - Lock System Accounts ansible.builtin.user: name: '{{ item.key }}' password_lock: true loop: '{{ local_users }}' when: - item.value[1]|int < 1000 - item.key not in ['root', 'halt', 'sync', 'shutdown', 'nfsnobody'] tags: - NIST-800-53-AC-6 - NIST-800-53-CM-6(a) - PCI-DSSv4-8.2 - PCI-DSSv4-8.2.2 - 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: - 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.2 - PCI-DSSv4-8.2.2 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - no_shelllogin_for_systemaccounts - restrict_strategy - 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: - 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.2 - PCI-DSSv4-8.2.2 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - no_shelllogin_for_systemaccounts - restrict_strategy - 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: - item.key not in ['root'] - item.value[1]|int < 1000 - item.value[5] not in ['/sbin/shutdown', '/sbin/halt', '/bin/sync'] tags: - 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.2 - PCI-DSSv4-8.2.2 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - no_shelllogin_for_systemaccounts - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - use_pam_wheel_group_for_su - name: Enforce Usage of pam_wheel with Group Parameter for su Authentication - Add the group to the /etc/pam.d/su file ansible.builtin.lineinfile: path: /etc/pam.d/su state: present regexp: ^[\s]*#[\s]*auth[\s]+required[\s]+pam_wheel\.so[\s]+use_uid group=$ line: auth required pam_wheel.so use_uid group={{ var_pam_wheel_group_for_su }} when: '"pam" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - use_pam_wheel_group_for_su - name: Gather the package facts package_facts: manager: auto tags: - 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 - PCI-DSSv4-8.6.1 - accounts_tmout - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Correct any occurrence of TMOUT in /etc/profile replace: path: /etc/profile regexp: ^[^#].*TMOUT=.* replace: typeset -xr TMOUT={{ var_accounts_tmout }} register: profile_replaced when: '"kernel" in ansible_facts.packages' tags: - 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 - 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: typeset -xr TMOUT={{ var_accounts_tmout }} state: present when: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-8.6.1 - accounts_tmout - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure interactive local users are the group-owners of their respective initialization files ansible.builtin.command: cmd: awk -F':' '{ if ($3 >= 1000 && $3 != 65534) system("chgrp -f " $4" "$6"/.[^\.]?*") }' /etc/passwd tags: - accounts_user_dot_group_ownership - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure interactive local users are the owners of their respective initialization files ansible.builtin.command: cmd: awk -F':' '{ if ($3 >= 1000 && $3 != 65534) system("chown -f " $3" "$6"/.[^\.]?*") }' /etc/passwd tags: - accounts_user_dot_user_ownership - 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: - DISA-STIG-RHEL-08-010750 - accounts_user_interactive_home_directory_exists - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Create local_users variable from the getent output ansible.builtin.set_fact: local_users: '{{ ansible_facts.getent_passwd|dict2items }}' tags: - DISA-STIG-RHEL-08-010750 - accounts_user_interactive_home_directory_exists - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure interactive users have a home directory exists ansible.builtin.user: name: '{{ item.key }}' create_home: true loop: '{{ local_users }}' when: - item.value[2]|int >= 1000 - item.value[2]|int != 65534 tags: - DISA-STIG-RHEL-08-010750 - 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: - accounts_users_netrc_file_permissions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Create local_users variable from the getent output ansible.builtin.set_fact: local_users: '{{ ansible_facts.getent_passwd|dict2items }}' tags: - accounts_users_netrc_file_permissions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Test for existence of .netrc file in home directories to avoid creating them, but only fixing permissions ansible.builtin.stat: path: '{{ item.value[4] }}/.netrc' register: path_exists loop: '{{ local_users }}' when: - item.value[1]|int >= 1000 - item.value[1]|int != 65534 tags: - accounts_users_netrc_file_permissions - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure group and world cannot access respective .netrc files ansible.builtin.file: path: '{{ item.item.value[4] }}/.netrc' mode: '0600' state: file loop: '{{ path_exists.results }}' when: item.stat is defined and item.stat.exists tags: - accounts_users_netrc_file_permissions - 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: - file_ownership_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Create local_users variable from the getent output ansible.builtin.set_fact: local_users: '{{ ansible_facts.getent_passwd|dict2items }}' tags: - file_ownership_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Test for existence of home directories to avoid creating them, but only fixing ownership ansible.builtin.stat: path: '{{ item.value[4] }}' register: path_exists loop: '{{ local_users }}' when: - item.value[1]|int >= 1000 - item.value[1]|int != 65534 tags: - file_ownership_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure interactive local users are the owners of their respective home directories ansible.builtin.file: path: '{{ item.0.value[4] }}' owner: '{{ item.0.value[1] }}' loop: '{{ local_users|zip(path_exists.results)|list }}' when: item.1.stat is defined and item.1.stat.exists tags: - file_ownership_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure All User Initialization Files Have Mode 0740 Or Less Permissive - Gather User Info ansible.builtin.getent: database: passwd tags: - DISA-STIG-RHEL-08-010770 - file_permission_user_init_files - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure All User Initialization Files Have Mode 0740 Or Less Permissive - Find Init Files ansible.builtin.find: paths: '{{ item.value[4] }}' pattern: '{{ var_user_initialization_files_regex }}' hidden: true use_regex: true with_dict: '{{ ansible_facts.getent_passwd }}' when: - item.value[4] != "/sbin/nologin" - item.key not in ["nobody", "nfsnobody"] - item.value[1] | int >= 1000 register: found_init_files tags: - DISA-STIG-RHEL-08-010770 - file_permission_user_init_files - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure All User Initialization Files Have Mode 0740 Or Less Permissive - Fix Init Files Permissions ansible.builtin.file: path: '{{ item.1.path }}' mode: u-s,g-wxs,o= loop: '{{ q(''ansible.builtin.subelements'', found_init_files.results, ''files'', {''skip_missing'': True}) }}' tags: - DISA-STIG-RHEL-08-010770 - file_permission_user_init_files - 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: - DISA-STIG-RHEL-08-010730 - file_permissions_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Create local_users variable from the getent output ansible.builtin.set_fact: local_users: '{{ ansible_facts.getent_passwd|dict2items }}' tags: - DISA-STIG-RHEL-08-010730 - file_permissions_home_directories - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Test for existence home directories to avoid creating them. ansible.builtin.stat: path: '{{ item.value[4] }}' register: path_exists loop: '{{ local_users }}' when: - item.value[1]|int >= 1000 - item.value[1]|int != 65534 - item.value[4] != "/" tags: - DISA-STIG-RHEL-08-010730 - 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: item.1.stat is defined and item.1.stat.exists tags: - DISA-STIG-RHEL-08-010730 - 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: - 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: Disable writability to root directories file: path: '{{ item.item }}' mode: g-w,o-w with_items: '{{ root_paths.results }}' when: - root_paths.results is defined - item.stat.exists - not item.stat.islnk tags: - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-020353 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - accounts_umask_etc_bashrc - low_complexity - low_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: ^[^#]*\bumask\s+\d+$ state: absent check_mode: true changed_when: false register: umask_replace when: '"bash" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-020353 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - accounts_umask_etc_bashrc - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Replace user umask in /etc/bashrc ansible.builtin.replace: path: /etc/bashrc regexp: ^([^#]*\b)umask\s+\d+$ replace: \g<1>umask {{ var_accounts_user_umask }} when: - '"bash" in ansible_facts.packages' - umask_replace.found > 0 tags: - DISA-STIG-RHEL-08-020353 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - 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: - '"bash" in ansible_facts.packages' - umask_replace.found == 0 tags: - DISA-STIG-RHEL-08-020353 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - 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: - DISA-STIG-RHEL-08-020351 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - accounts_umask_etc_login_defs - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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: '"shadow-utils" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-020351 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - 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: - '"shadow-utils" in ansible_facts.packages' - result_umask_is_set.found > 0 tags: - DISA-STIG-RHEL-08-020351 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - 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: - '"shadow-utils" in ansible_facts.packages' - result_umask_is_set.found == 0 tags: - DISA-STIG-RHEL-08-020351 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - 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: - DISA-STIG-RHEL-08-020353 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - 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 - 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: result_profile_d_files.matched tags: - DISA-STIG-RHEL-08-020353 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - 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: not result_profile_d_files.matched tags: - DISA-STIG-RHEL-08-020353 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - 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: - DISA-STIG-RHEL-08-020353 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - accounts_umask_etc_profile - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - 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 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /boot/grub2/grub.cfg stat: path: /boot/grub2/grub.cfg register: file_exists when: - '"/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: - 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 - 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: - '"/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: - 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 - 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: - 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 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /boot/grub2/user.cfg stat: path: /boot/grub2/user.cfg register: file_exists when: - '"/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: - 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 - PCI-DSSv4-2.2.6 - 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: - '"/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: - 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 - PCI-DSSv4-2.2.6 - 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: - 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 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /boot/grub2/grub.cfg stat: path: /boot/grub2/grub.cfg register: file_exists when: - '"/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: - 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 - 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: - '"/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: - 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 - 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: - 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 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /boot/grub2/user.cfg stat: path: /boot/grub2/user.cfg register: file_exists when: - '"/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: - 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 - PCI-DSSv4-2.2.6 - 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: - '"/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: - 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 - PCI-DSSv4-2.2.6 - 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: - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /boot/grub2/grub.cfg stat: path: /boot/grub2/grub.cfg register: file_exists when: - '"/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: - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - 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: - '"/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: - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - 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: - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /boot/grub2/user.cfg stat: path: /boot/grub2/user.cfg register: file_exists when: - '"/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: - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - 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: - '"/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: - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - 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_efi_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /boot/efi/EFI/redhat/grub.cfg stat: path: /boot/efi/EFI/redhat/grub.cfg register: file_exists when: - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - 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_efi_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /boot/efi/EFI/redhat/grub.cfg file: path: /boot/efi/EFI/redhat/grub.cfg group: '0' when: - '"/boot/efi" 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: - 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_efi_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - 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_efi_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /boot/efi/EFI/redhat/user.cfg stat: path: /boot/efi/EFI/redhat/user.cfg register: file_exists when: - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - 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_efi_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /boot/efi/EFI/redhat/user.cfg file: path: /boot/efi/EFI/redhat/user.cfg group: '0' when: - '"/boot/efi" 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: - 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_efi_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - 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_efi_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /boot/efi/EFI/redhat/grub.cfg stat: path: /boot/efi/EFI/redhat/grub.cfg register: file_exists when: - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - 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_efi_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /boot/efi/EFI/redhat/grub.cfg file: path: /boot/efi/EFI/redhat/grub.cfg owner: '0' when: - '"/boot/efi" 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: - 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_efi_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - 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_efi_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /boot/efi/EFI/redhat/user.cfg stat: path: /boot/efi/EFI/redhat/user.cfg register: file_exists when: - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - 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_efi_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /boot/efi/EFI/redhat/user.cfg file: path: /boot/efi/EFI/redhat/user.cfg owner: '0' when: - '"/boot/efi" 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: - 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_efi_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_efi_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /boot/efi/EFI/redhat/grub.cfg stat: path: /boot/efi/EFI/redhat/grub.cfg register: file_exists when: - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_efi_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-s,g-xwrs,o-xwrt on /boot/efi/EFI/redhat/grub.cfg file: path: /boot/efi/EFI/redhat/grub.cfg mode: u-s,g-xwrs,o-xwrt when: - '"/boot/efi" 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: - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_efi_grub2_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_efi_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /boot/efi/EFI/redhat/user.cfg stat: path: /boot/efi/EFI/redhat/user.cfg register: file_exists when: - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list' - '"grub2-common" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] tags: - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_efi_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-s,g-xwrs,o-xwrt on /boot/efi/EFI/redhat/user.cfg file: path: /boot/efi/EFI/redhat/user.cfg mode: u-s,g-xwrs,o-xwrt when: - '"/boot/efi" 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: - NIST-800-171-3.4.5 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - configure_strategy - file_permissions_efi_user_cfg - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-030670 - NIST-800-53-CM-6(a) - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_rsyslog_installed - name: Ensure rsyslog is installed package: name: rsyslog state: present when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030670 - NIST-800-53-CM-6(a) - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_rsyslog_installed - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-010561 - 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: Enable rsyslog Service - Enable service rsyslog block: - name: Gather the package facts package_facts: manager: auto - name: Enable rsyslog Service - Enable Service rsyslog ansible.builtin.systemd: name: rsyslog enabled: true state: started masked: false when: - '"rsyslog" in ansible_facts.packages' when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010561 - 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: Gather the package facts package_facts: manager: auto tags: - 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 Main Config File ansible.builtin.find: paths: /etc pattern: rsyslog.conf contains: ^\s*\$FileCreateMode\s*\d+ register: rsyslog_main_file_with_filecreatemode when: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: - '"kernel" in ansible_facts.packages' - rsyslog_filecreatemode_files | length > 1 tags: - 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: - '"kernel" in ansible_facts.packages' - rsyslog_filecreatemode_files | length == 0 or result_rsyslog_filecreatemode_removed is not skipped tags: - 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: - '"kernel" in ansible_facts.packages' - rsyslog_filecreatemode_files | length == 1 tags: - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - rsyslog_filecreatemode - name: Gather the package facts package_facts: manager: auto tags: - 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 - 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 - Set rsyslog logfile configuration facts ansible.builtin.set_fact: rsyslog_etc_config: /etc/rsyslog.conf when: '"kernel" in ansible_facts.packages' tags: - 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 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - 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: - '"kernel" in ansible_facts.packages' - rsyslog_old_inc is not skipped and rsyslog_new_inc is not skipped tags: - 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 - 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] }}' when: - '"kernel" in ansible_facts.packages' - include_config_output is defined register: rsyslog_config_files failed_when: false changed_when: false tags: - 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 - 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 | default([]) | subelements(''files'') }}' register: log_files_old changed_when: false when: - '"kernel" in ansible_facts.packages' - rsyslog_config_files is not skipped tags: - 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 - 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 "\bFile\s*=\s*\"([/[:alnum:][:punct:]]*)\"\s*\)" | \ grep -oE "\"([/[:alnum:][:punct:]]*)\"" | \ tr -d "\""|| true loop: '{{ rsyslog_config_files.results | default([]) | subelements(''files'') }}' register: log_files_new changed_when: false when: - '"kernel" in ansible_facts.packages' - rsyslog_config_files is not skipped tags: - 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 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - 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: root state: file loop: '{{ log_files | list | flatten | unique }}' failed_when: false when: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_groupownership - name: Gather the package facts package_facts: manager: auto tags: - 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 - 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 - Set rsyslog logfile configuration facts ansible.builtin.set_fact: rsyslog_etc_config: /etc/rsyslog.conf when: '"kernel" in ansible_facts.packages' tags: - 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 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - 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: - '"kernel" in ansible_facts.packages' - rsyslog_old_inc is not skipped and rsyslog_new_inc is not skipped tags: - 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 - 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] }}' when: - '"kernel" in ansible_facts.packages' - include_config_output is defined register: rsyslog_config_files failed_when: false changed_when: false tags: - 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 - 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 | default([]) | subelements(''files'') }}' register: log_files_old changed_when: false when: - '"kernel" in ansible_facts.packages' - rsyslog_config_files is not skipped tags: - 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 - 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 "\bFile\s*=\s*\"([/[:alnum:][:punct:]]*)\"\s*\)" | \ grep -oE "\"([/[:alnum:][:punct:]]*)\"" | \ tr -d "\""|| true loop: '{{ rsyslog_config_files.results | default([]) | subelements(''files'') }}' register: log_files_new changed_when: false when: - '"kernel" in ansible_facts.packages' - rsyslog_config_files is not skipped tags: - 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 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - 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: root state: file loop: '{{ log_files | list | flatten | unique }}' failed_when: false when: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.3.2 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_ownership - name: Gather the package facts package_facts: manager: auto tags: - 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 - PCI-DSSv4-10.3.1 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_permissions - name: Ensure System Log Files Have Correct Permissions - Set rsyslog logfile configuration facts ansible.builtin.set_fact: rsyslog_etc_config: /etc/rsyslog.conf when: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.3.1 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.3.1 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.3.1 - 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: - '"kernel" in ansible_facts.packages' - rsyslog_old_inc is not skipped and rsyslog_new_inc is not skipped tags: - 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 - PCI-DSSv4-10.3.1 - 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] }}' when: - '"kernel" in ansible_facts.packages' - include_config_output is defined register: rsyslog_config_files failed_when: false changed_when: false tags: - 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 - PCI-DSSv4-10.3.1 - 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 | default([]) | subelements(''files'') }}' register: log_files_old changed_when: false when: - '"kernel" in ansible_facts.packages' - rsyslog_config_files is not skipped tags: - 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 - PCI-DSSv4-10.3.1 - 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 "\bFile\s*=\s*\"([/[:alnum:][:punct:]]*)\"\s*\)" | \ grep -oE "\"([/[:alnum:][:punct:]]*)\"" | \ tr -d "\""|| true loop: '{{ rsyslog_config_files.results | default([]) | subelements(''files'') }}' register: log_files_new changed_when: false when: - '"kernel" in ansible_facts.packages' - rsyslog_config_files is not skipped tags: - 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 - PCI-DSSv4-10.3.1 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.3.1 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.3.1 - configure_strategy - low_complexity - medium_disruption - medium_severity - no_reboot_needed - rsyslog_files_permissions - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-SC-24 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_systemd-journald_enabled - name: Enable systemd-journald Service - Enable service systemd-journald block: - name: Gather the package facts package_facts: manager: auto - name: Enable systemd-journald Service - Enable Service systemd-journald ansible.builtin.systemd: name: systemd-journald enabled: true state: started masked: false when: - '"systemd" in ansible_facts.packages' when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-SC-24 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_systemd-journald_enabled - name: Gather the package facts package_facts: manager: auto tags: - journald_compress - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure journald is configured to compress large log files - Search for a section in files ansible.builtin.find: paths: '{{item.path}}' patterns: '{{item.pattern}}' contains: ^\s*\[Journal\] read_whole_file: true use_regex: true register: systemd_dropin_files_with_section loop: - path: '{{ ''/etc/systemd/journald.conf'' | dirname }}' pattern: '{{ ''/etc/systemd/journald.conf'' | basename | regex_escape }}' - path: /etc/systemd/journald.conf.d pattern: .*\.conf when: '"kernel" in ansible_facts.packages' tags: - journald_compress - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure journald is configured to compress large log files - Count number of files which contain the correct section ansible.builtin.set_fact: count_of_systemd_dropin_files_with_section: '{{systemd_dropin_files_with_section.results | map(attribute=''matched'') | list | map(''int'') | sum}}' when: '"kernel" in ansible_facts.packages' tags: - journald_compress - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure journald is configured to compress large log files - Add missing configuration to correct section ini_file: path: '{{item}}' section: Journal option: Compress value: 'yes' state: present no_extra_spaces: true when: - '"kernel" in ansible_facts.packages' - count_of_systemd_dropin_files_with_section | int > 0 loop: '{{systemd_dropin_files_with_section.results | sum(attribute=''files'', start=[]) | map(attribute=''path'') | list }}' tags: - journald_compress - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure journald is configured to compress large log files - Add configuration to new remediation file ini_file: path: /etc/systemd/journald.conf.d/complianceascode_hardening.conf section: Journal option: Compress value: 'yes' state: present no_extra_spaces: true create: true when: - '"kernel" in ansible_facts.packages' - count_of_systemd_dropin_files_with_section | int == 0 tags: - journald_compress - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - journald_forward_to_syslog - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure journald is configured to send logs to rsyslog - Search for a section in files ansible.builtin.find: paths: '{{item.path}}' patterns: '{{item.pattern}}' contains: ^\s*\[Journal\] read_whole_file: true use_regex: true register: systemd_dropin_files_with_section loop: - path: '{{ ''/etc/systemd/journald.conf'' | dirname }}' pattern: '{{ ''/etc/systemd/journald.conf'' | basename | regex_escape }}' - path: /etc/systemd/journald.conf.d pattern: .*\.conf when: '"kernel" in ansible_facts.packages' tags: - journald_forward_to_syslog - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure journald is configured to send logs to rsyslog - Count number of files which contain the correct section ansible.builtin.set_fact: count_of_systemd_dropin_files_with_section: '{{systemd_dropin_files_with_section.results | map(attribute=''matched'') | list | map(''int'') | sum}}' when: '"kernel" in ansible_facts.packages' tags: - journald_forward_to_syslog - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure journald is configured to send logs to rsyslog - Add missing configuration to correct section ini_file: path: '{{item}}' section: Journal option: ForwardToSyslog value: 'yes' state: present no_extra_spaces: true when: - '"kernel" in ansible_facts.packages' - count_of_systemd_dropin_files_with_section | int > 0 loop: '{{systemd_dropin_files_with_section.results | sum(attribute=''files'', start=[]) | map(attribute=''path'') | list }}' tags: - journald_forward_to_syslog - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure journald is configured to send logs to rsyslog - Add configuration to new remediation file ini_file: path: /etc/systemd/journald.conf.d/complianceascode_hardening.conf section: Journal option: ForwardToSyslog value: 'yes' state: present no_extra_spaces: true create: true when: - '"kernel" in ansible_facts.packages' - count_of_systemd_dropin_files_with_section | int == 0 tags: - journald_forward_to_syslog - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - journald_storage - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure journald is configured to write log files to persistent disk - Search for a section in files ansible.builtin.find: paths: '{{item.path}}' patterns: '{{item.pattern}}' contains: ^\s*\[Journal\] read_whole_file: true use_regex: true register: systemd_dropin_files_with_section loop: - path: '{{ ''/etc/systemd/journald.conf'' | dirname }}' pattern: '{{ ''/etc/systemd/journald.conf'' | basename | regex_escape }}' - path: /etc/systemd/journald.conf.d pattern: .*\.conf when: '"kernel" in ansible_facts.packages' tags: - journald_storage - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure journald is configured to write log files to persistent disk - Count number of files which contain the correct section ansible.builtin.set_fact: count_of_systemd_dropin_files_with_section: '{{systemd_dropin_files_with_section.results | map(attribute=''matched'') | list | map(''int'') | sum}}' when: '"kernel" in ansible_facts.packages' tags: - journald_storage - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure journald is configured to write log files to persistent disk - Add missing configuration to correct section ini_file: path: '{{item}}' section: Journal option: Storage value: persistent state: present no_extra_spaces: true when: - '"kernel" in ansible_facts.packages' - count_of_systemd_dropin_files_with_section | int > 0 loop: '{{systemd_dropin_files_with_section.results | sum(attribute=''files'', start=[]) | map(attribute=''path'') | list }}' tags: - journald_storage - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Ensure journald is configured to write log files to persistent disk - Add configuration to new remediation file ini_file: path: /etc/systemd/journald.conf.d/complianceascode_hardening.conf section: Journal option: Storage value: persistent state: present no_extra_spaces: true create: true when: - '"kernel" in ansible_facts.packages' - count_of_systemd_dropin_files_with_section | int == 0 tags: - journald_storage - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - socket_systemd-journal-remote_disabled - 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: '"kernel" in ansible_facts.packages' tags: - 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: - '"kernel" in ansible_facts.packages' - result_systemd_unit_files.stdout_lines is search("systemd-journal-remote.socket") tags: - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - socket_systemd-journal-remote_disabled - name: Gather the package facts package_facts: manager: auto tags: - 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 Legacy Syntax ansible.builtin.set_fact: rsyslog_listen_legacy_regex: ^\s*\$(((Input(TCP|RELP)|UDP)ServerRun)|ModLoad\s+(imtcp|imudp|imrelp)) when: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: - '"kernel" in ansible_facts.packages' - rsyslog_legacy_remote_listen_files | length > 0 tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: - '"kernel" in ansible_facts.packages' - rsyslog_rainer_remote_listen_files | length > 0 tags: - 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: - '"kernel" in ansible_facts.packages' - rsyslog_listen_legacy_comment is changed or rsyslog_listen_rainer_comment is changed tags: - 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: - DISA-STIG-RHEL-08-040100 - NIST-800-53-CM-6(a) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_firewalld_installed - name: Ensure firewalld is installed package: name: firewalld state: present when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040100 - NIST-800-53-CM-6(a) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_firewalld_installed - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040101 - 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) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_firewalld_enabled - name: Verify firewalld Enabled - Enable service firewalld block: - name: Gather the package facts package_facts: manager: auto - name: Verify firewalld Enabled - Enable Service firewalld ansible.builtin.systemd: name: firewalld enabled: true state: started masked: false when: - '"firewalld" in ansible_facts.packages' when: - '"kernel" in ansible_facts.packages' - '"firewalld" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040101 - 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) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_firewalld_enabled - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.1 - configure_strategy - firewalld_loopback_traffic_restricted - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Configure Firewalld to Restrict Loopback Traffic - Ensure firewalld Package is Installed ansible.builtin.package: name: '{{ item }}' state: present with_items: - firewalld when: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.1 - 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: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.1 - 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: - '"kernel" in ansible_facts.packages' - ansible_facts.services['firewalld.service'].state == 'running' tags: - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.1 - 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: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.1 - configure_strategy - firewalld_loopback_traffic_restricted - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.1 - configure_strategy - firewalld_loopback_traffic_trusted - 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: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.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: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.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: - '"kernel" in ansible_facts.packages' - ansible_facts.services['firewalld.service'].state == 'running' tags: - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.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: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.1 - configure_strategy - firewalld_loopback_traffic_trusted - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040261 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.all.accept_ra.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040261 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040261 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040261 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040280 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.all.accept_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040280 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040280 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040280 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040240 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.all.accept_source_route.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040240 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040240 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040240 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040260 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.all.forwarding.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040260 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040260 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040260 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040262 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.default.accept_ra.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040262 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040262 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040262 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040210 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.default.accept_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040210 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040210 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040210 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040250 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv6.conf.default.accept_source_route.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040250 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040250 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040250 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv6_conf_default_accept_source_route - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040279 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.all.accept_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040279 - 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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040279 - 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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040279 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040239 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.all.accept_source_route.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040239 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040239 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040239 - 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: Gather the package facts package_facts: manager: auto tags: - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.all.log_martians.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040285 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.all.rp_filter.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040285 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040285 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040285 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_rp_filter - name: Gather the package facts package_facts: manager: auto tags: - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.all.secure_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-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: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-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: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_secure_redirects - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040209 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.default.accept_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040209 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040209 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040209 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_accept_redirects - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040249 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.default.accept_source_route.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040249 - 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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040249 - 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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040249 - 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: Gather the package facts package_facts: manager: auto tags: - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.default.log_martians.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: Gather the package facts package_facts: manager: auto tags: - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.default.rp_filter.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: Gather the package facts package_facts: manager: auto tags: - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.default.secure_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - 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: Gather the package facts package_facts: manager: auto tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040230 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.icmp_echo_ignore_broadcasts.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040230 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - 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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040230 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - 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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040230 - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_icmp_echo_ignore_broadcasts - name: Gather the package facts package_facts: manager: auto tags: - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.icmp_ignore_bogus_error_responses.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - disable_strategy - low_complexity - medium_disruption - reboot_required - sysctl_net_ipv4_icmp_ignore_bogus_error_responses - unknown_severity - name: Gather the package facts package_facts: manager: auto tags: - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.3 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.tcp_syncookies.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.3 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.3 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_tcp_syncookies - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040220 - 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 - PCI-DSSv4-1.4.5 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.all.send_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040220 - 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 - PCI-DSSv4-1.4.5 - 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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040220 - 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 - PCI-DSSv4-1.4.5 - 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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040220 - 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 - PCI-DSSv4-1.4.5 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_all_send_redirects - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040270 - 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 - PCI-DSSv4-1.4.5 - 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/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.conf.default.send_redirects.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040270 - 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 - PCI-DSSv4-1.4.5 - 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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040270 - 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 - PCI-DSSv4-1.4.5 - 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: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1.1 - DISA-STIG-RHEL-08-040270 - 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 - PCI-DSSv4-1.4.5 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_conf_default_send_redirects - name: Gather the package facts package_facts: manager: auto tags: - 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 - PCI-DSSv4-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_ip_forward - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ - /usr/lib/sysctl.d/ contains: ^[\s]*net.ipv4.ip_forward.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-1.4.3 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-1.4.3 - 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: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-1.4.3 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_net_ipv4_ip_forward - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_nftables_installed - name: Ensure nftables is installed package: name: nftables state: present when: ( "kernel" in ansible_facts.packages ) tags: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_nftables_installed - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.1 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_nftables_disabled - name: Verify nftables Service is Disabled - Collect systemd Services Present in the System ansible.builtin.command: systemctl -q list-unit-files --type service register: service_exists changed_when: false failed_when: service_exists.rc not in [0, 1] check_mode: false when: ( "firewalld" in ansible_facts.packages and "nftables" in ansible_facts.packages and "kernel" in ansible_facts.packages ) tags: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.1 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_nftables_disabled - name: Verify nftables Service is Disabled - Ensure nftables.service is Masked ansible.builtin.systemd: name: nftables.service state: stopped enabled: false masked: true when: - ( "firewalld" in ansible_facts.packages and "nftables" in ansible_facts.packages and "kernel" in ansible_facts.packages ) - service_exists.stdout_lines is search("nftables.service", multiline=True) tags: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.1 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_nftables_disabled - name: Unit Socket Exists - nftables.socket ansible.builtin.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: ( "firewalld" in ansible_facts.packages and "nftables" in ansible_facts.packages and "kernel" in ansible_facts.packages ) tags: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.1 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_nftables_disabled - name: Verify nftables Service is Disabled - Disable Socket nftables ansible.builtin.systemd: name: nftables.socket enabled: false state: stopped masked: true when: - ( "firewalld" in ansible_facts.packages and "nftables" in ansible_facts.packages and "kernel" in ansible_facts.packages ) - socket_file_exists.stdout_lines is search("nftables.socket", multiline=True) tags: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.1 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_nftables_disabled - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.10.1 - NIST-800-171-3.4.6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSS-Req-1.4.2 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - disable_strategy - kernel_module_dccp_disabled - low_complexity - medium_disruption - medium_severity - reboot_required - name: Ensure kernel module 'dccp' is disabled lineinfile: create: true dest: /etc/modprobe.d/dccp.conf regexp: install\s+dccp line: install dccp /bin/false when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1 - NIST-800-171-3.4.6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSS-Req-1.4.2 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - disable_strategy - kernel_module_dccp_disabled - low_complexity - medium_disruption - medium_severity - reboot_required - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - kernel_module_rds_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Ensure kernel module 'rds' is disabled lineinfile: create: true dest: /etc/modprobe.d/rds.conf regexp: install\s+rds line: install rds /bin/false when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - kernel_module_rds_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.10.1 - DISA-STIG-RHEL-08-040023 - NIST-800-171-3.4.6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSS-Req-1.4.2 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - disable_strategy - kernel_module_sctp_disabled - low_complexity - medium_disruption - medium_severity - reboot_required - name: Ensure kernel module 'sctp' is disabled lineinfile: create: true dest: /etc/modprobe.d/sctp.conf regexp: install\s+sctp line: install sctp /bin/false when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.10.1 - DISA-STIG-RHEL-08-040023 - NIST-800-171-3.4.6 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSS-Req-1.4.2 - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - disable_strategy - kernel_module_sctp_disabled - low_complexity - medium_disruption - medium_severity - reboot_required - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040024 - 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 disabled lineinfile: create: true dest: /etc/modprobe.d/tipc.conf regexp: install\s+tipc line: install tipc /bin/false when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040024 - 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: - 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 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_bluetooth_disabled - name: Disable Bluetooth Service - Collect systemd Services Present in the System ansible.builtin.command: systemctl -q list-unit-files --type service register: service_exists changed_when: false failed_when: service_exists.rc not in [0, 1] check_mode: false when: '"kernel" in ansible_facts.packages' tags: - 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 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_bluetooth_disabled - name: Disable Bluetooth Service - Ensure bluetooth.service is Masked ansible.builtin.systemd: name: bluetooth.service state: stopped enabled: false masked: true when: - '"kernel" in ansible_facts.packages' - service_exists.stdout_lines is search("bluetooth.service", multiline=True) tags: - 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 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_bluetooth_disabled - name: Unit Socket Exists - bluetooth.socket ansible.builtin.command: systemctl -q list-unit-files bluetooth.socket register: socket_file_exists changed_when: false failed_when: socket_file_exists.rc not in [0, 1] check_mode: false when: '"kernel" in ansible_facts.packages' tags: - 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 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_bluetooth_disabled - name: Disable Bluetooth Service - Disable Socket bluetooth ansible.builtin.systemd: name: bluetooth.socket enabled: false state: stopped masked: true when: - '"kernel" in ansible_facts.packages' - socket_file_exists.stdout_lines is search("bluetooth.socket", multiline=True) tags: - 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 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_bluetooth_disabled - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040110 - 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.3 - PCI-DSSv4-1.3.3 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - wireless_disable_interfaces - name: Service facts ansible.builtin.service_facts: null tags: - DISA-STIG-RHEL-08-040110 - 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.3 - PCI-DSSv4-1.3.3 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - wireless_disable_interfaces - name: Ensure NetworkManager is installed ansible.builtin.package: name: '{{ item }}' state: present with_items: - NetworkManager tags: - DISA-STIG-RHEL-08-040110 - 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.3 - PCI-DSSv4-1.3.3 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - wireless_disable_interfaces - name: NetworkManager Deactivate Wireless Network Interfaces command: nmcli radio wifi off when: - '''NetworkManager'' in ansible_facts.packages' - ansible_facts.services['NetworkManager.service'].state == 'running' tags: - DISA-STIG-RHEL-08-040110 - 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.3 - PCI-DSSv4-1.3.3 - low_complexity - medium_disruption - medium_severity - no_reboot_needed - unknown_strategy - wireless_disable_interfaces - name: Verify that All World-Writable Directories Have Sticky Bits Set - Define Excluded (Non-Local) File Systems and Paths ansible.builtin.set_fact: excluded_fstypes: - afs - ceph - cifs - smb3 - smbfs - sshfs - ncpfs - ncp - nfs - nfs4 - gfs - gfs2 - glusterfs - gpfs - pvfs2 - ocfs2 - lustre - davfs - fuse.sshfs excluded_paths: - dev - proc - run - sys search_paths: [] tags: - DISA-STIG-RHEL-08-010190 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - dir_perms_world_writable_sticky_bits - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Verify that All World-Writable Directories Have Sticky Bits Set - Find Relevant Root Directories Ignoring Pre-Defined Excluded Paths ansible.builtin.find: paths: / file_type: directory excludes: '{{ excluded_paths }}' hidden: true recurse: false register: result_relevant_root_dirs tags: - DISA-STIG-RHEL-08-010190 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - dir_perms_world_writable_sticky_bits - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Verify that All World-Writable Directories Have Sticky Bits Set - Include Relevant Root Directories in a List of Paths to be Searched ansible.builtin.set_fact: search_paths: '{{ search_paths | union([item.path]) }}' loop: '{{ result_relevant_root_dirs.files }}' tags: - DISA-STIG-RHEL-08-010190 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - dir_perms_world_writable_sticky_bits - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Verify that All World-Writable Directories Have Sticky Bits Set - Increment Search Paths List with Local Partitions Mount Points ansible.builtin.set_fact: search_paths: '{{ search_paths | union([item.mount]) }}' loop: '{{ ansible_mounts }}' when: - item.fstype not in excluded_fstypes - item.mount != '/' tags: - DISA-STIG-RHEL-08-010190 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - dir_perms_world_writable_sticky_bits - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Verify that All World-Writable Directories Have Sticky Bits Set - Increment Search Paths List with Local NFS File System Targets ansible.builtin.set_fact: search_paths: '{{ search_paths | union([item.device.split('':'')[1]]) }}' loop: '{{ ansible_mounts }}' when: item.device is search("localhost:") tags: - DISA-STIG-RHEL-08-010190 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - dir_perms_world_writable_sticky_bits - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Verify that All World-Writable Directories Have Sticky Bits Set - Define Rule Specific Facts ansible.builtin.set_fact: world_writable_dirs: [] tags: - DISA-STIG-RHEL-08-010190 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - dir_perms_world_writable_sticky_bits - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Verify that All World-Writable Directories Have Sticky Bits Set - Find All Uncompliant Directories in Local File Systems ansible.builtin.command: cmd: find {{ item }} -xdev -type d ( -perm -0002 -a ! -perm -1000 ) loop: '{{ search_paths }}' changed_when: false register: result_found_dirs tags: - DISA-STIG-RHEL-08-010190 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - dir_perms_world_writable_sticky_bits - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Verify that All World-Writable Directories Have Sticky Bits Set - Create List of World Writable Directories Without Sticky Bit ansible.builtin.set_fact: world_writable_dirs: '{{ world_writable_dirs | union(item.stdout_lines) | list }}' loop: '{{ result_found_dirs.results }}' when: result_found_dirs is not skipped and item is not skipped tags: - DISA-STIG-RHEL-08-010190 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - dir_perms_world_writable_sticky_bits - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Verify that All World-Writable Directories Have Sticky Bits Set - Ensure Sticky Bit is Set on Local World Writable Directories ansible.builtin.file: path: '{{ item }}' mode: a+t loop: '{{ world_writable_dirs }}' tags: - DISA-STIG-RHEL-08-010190 - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - dir_perms_world_writable_sticky_bits - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Test for existence /etc/group- stat: path: /etc/group- register: file_exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_backup_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/group- file: path: /etc/group- group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - PCI-DSSv4-2.2 - PCI-DSSv4-2.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: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - configure_strategy - file_groupowner_backup_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/gshadow- file: path: /etc/gshadow- group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - 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: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_backup_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/passwd- file: path: /etc/passwd- group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - PCI-DSSv4-2.2 - PCI-DSSv4-2.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: - PCI-DSS-Req-8.7 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_backup_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/shadow- file: path: /etc/shadow- group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - PCI-DSS-Req-8.7 - PCI-DSSv4-2.2 - PCI-DSSv4-2.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: - 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-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/group file: path: /etc/group group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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-2.2 - PCI-DSSv4-2.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: - 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: Ensure group owner 0 on /etc/gshadow file: path: /etc/gshadow group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - 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-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/passwd file: path: /etc/passwd group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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-2.2 - PCI-DSSv4-2.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: - 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-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/shadow file: path: /etc/shadow group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/shells stat: path: /etc/shells register: file_exists tags: - NIST-800-53-AC-3 - NIST-800-53-MP-2 - configure_strategy - file_groupowner_etc_shells - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /etc/shells file: path: /etc/shells group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-3 - NIST-800-53-MP-2 - configure_strategy - file_groupowner_etc_shells - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/group- stat: path: /etc/group- register: file_exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_backup_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/group- file: path: /etc/group- owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-2.2 - PCI-DSSv4-2.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: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - configure_strategy - file_owner_backup_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/gshadow- file: path: /etc/gshadow- owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7 - 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: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_backup_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/passwd- file: path: /etc/passwd- owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-2.2 - PCI-DSSv4-2.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: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_backup_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/shadow- file: path: /etc/shadow- owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-2.2 - PCI-DSSv4-2.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: - 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-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/group file: path: /etc/group owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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-2.2 - PCI-DSSv4-2.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: - 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: Ensure owner 0 on /etc/gshadow file: path: /etc/gshadow owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - 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-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/passwd file: path: /etc/passwd owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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-2.2 - PCI-DSSv4-2.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: - 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-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/shadow file: path: /etc/shadow owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/shells stat: path: /etc/shells register: file_exists tags: - NIST-800-53-AC-3 - NIST-800-53-MP-2 - configure_strategy - file_owner_etc_shells - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /etc/shells file: path: /etc/shells owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-3 - NIST-800-53-MP-2 - configure_strategy - file_owner_etc_shells - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/group- stat: path: /etc/group- register: file_exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_backup_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xws,o-xwt on /etc/group- file: path: /etc/group- mode: u-xs,g-xws,o-xwt when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-2.2 - PCI-DSSv4-2.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: - NIST-800-53-AC-6 (1) - configure_strategy - file_permissions_backup_etc_gshadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/gshadow- file: path: /etc/gshadow- mode: u-xwrs,g-xwrs,o-xwrt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_backup_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xws,o-xwt on /etc/passwd- file: path: /etc/passwd- mode: u-xs,g-xws,o-xwt when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-2.2 - PCI-DSSv4-2.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: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_backup_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/shadow- file: path: /etc/shadow- mode: u-xwrs,g-xwrs,o-xwrt when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6 (1) - PCI-DSS-Req-8.7.c - PCI-DSSv4-2.2 - PCI-DSSv4-2.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: - 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-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_etc_group - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xws,o-xwt on /etc/group file: path: /etc/group mode: u-xs,g-xws,o-xwt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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-2.2 - PCI-DSSv4-2.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: - 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: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/gshadow file: path: /etc/gshadow mode: u-xwrs,g-xwrs,o-xwrt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - 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-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_etc_passwd - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xws,o-xwt on /etc/passwd file: path: /etc/passwd mode: u-xs,g-xws,o-xwt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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-2.2 - PCI-DSSv4-2.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: - 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-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/shadow file: path: /etc/shadow mode: u-xwrs,g-xwrs,o-xwrt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_etc_shadow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/shells stat: path: /etc/shells register: file_exists tags: - NIST-800-53-AC-3 - NIST-800-53-MP-2 - configure_strategy - file_permissions_etc_shells - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-xs,g-xws,o-xwt on /etc/shells file: path: /etc/shells mode: u-xs,g-xws,o-xwt when: file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-3 - NIST-800-53-MP-2 - configure_strategy - file_permissions_etc_shells - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /sbin/auditctl stat: path: /sbin/auditctl register: file_exists tags: - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /sbin/auditctl file: path: /sbin/auditctl group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /sbin/aureport file: path: /sbin/aureport group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /sbin/ausearch file: path: /sbin/ausearch group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /sbin/autrace file: path: /sbin/autrace group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /sbin/auditd file: path: /sbin/auditd group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /sbin/audispd file: path: /sbin/audispd group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_groupownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner 0 on /sbin/augenrules file: path: /sbin/augenrules group: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /sbin/auditctl file: path: /sbin/auditctl owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /sbin/aureport file: path: /sbin/aureport owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /sbin/ausearch file: path: /sbin/ausearch owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /sbin/autrace file: path: /sbin/autrace owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /sbin/auditd file: path: /sbin/auditd owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /sbin/audispd file: path: /sbin/audispd owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_ownership_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure owner 0 on /sbin/augenrules file: path: /sbin/augenrules owner: '0' when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-s,g-ws,o-wt on /sbin/auditctl file: path: /sbin/auditctl mode: u-s,g-ws,o-wt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-s,g-ws,o-wt on /sbin/aureport file: path: /sbin/aureport mode: u-s,g-ws,o-wt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-s,g-ws,o-wt on /sbin/ausearch file: path: /sbin/ausearch mode: u-s,g-ws,o-wt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-s,g-ws,o-wt on /sbin/autrace file: path: /sbin/autrace mode: u-s,g-ws,o-wt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-s,g-ws,o-wt on /sbin/auditd file: path: /sbin/auditd mode: u-s,g-ws,o-wt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-s,g-ws,o-wt on /sbin/audispd file: path: /sbin/audispd mode: u-s,g-ws,o-wt when: file_exists.stat is defined and file_exists.stat.exists tags: - 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: - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure permission u-s,g-ws,o-wt on /sbin/augenrules file: path: /sbin/augenrules mode: u-s,g-ws,o-wt when: file_exists.stat is defined and file_exists.stat.exists tags: - configure_strategy - file_permissions_audit_binaries - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040070 - NIST-800-171-3.4.6 - 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 - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_autofs_disabled - name: Disable the Automounter - Collect systemd Services Present in the System ansible.builtin.command: systemctl -q list-unit-files --type service register: service_exists changed_when: false failed_when: service_exists.rc not in [0, 1] check_mode: false when: ( "autofs" in ansible_facts.packages and "kernel" in ansible_facts.packages ) tags: - DISA-STIG-RHEL-08-040070 - NIST-800-171-3.4.6 - 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 - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_autofs_disabled - name: Disable the Automounter - Ensure autofs.service is Masked ansible.builtin.systemd: name: autofs.service state: stopped enabled: false masked: true when: - ( "autofs" in ansible_facts.packages and "kernel" in ansible_facts.packages ) - service_exists.stdout_lines is search("autofs.service", multiline=True) tags: - DISA-STIG-RHEL-08-040070 - NIST-800-171-3.4.6 - 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 - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_autofs_disabled - name: Unit Socket Exists - autofs.socket ansible.builtin.command: systemctl -q list-unit-files autofs.socket register: socket_file_exists changed_when: false failed_when: socket_file_exists.rc not in [0, 1] check_mode: false when: ( "autofs" in ansible_facts.packages and "kernel" in ansible_facts.packages ) tags: - DISA-STIG-RHEL-08-040070 - NIST-800-171-3.4.6 - 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 - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_autofs_disabled - name: Disable the Automounter - Disable Socket autofs ansible.builtin.systemd: name: autofs.socket enabled: false state: stopped masked: true when: - ( "autofs" in ansible_facts.packages and "kernel" in ansible_facts.packages ) - socket_file_exists.stdout_lines is search("autofs.socket", multiline=True) tags: - DISA-STIG-RHEL-08-040070 - NIST-800-171-3.4.6 - 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 - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_autofs_disabled - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040025 - 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_cramfs_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Ensure kernel module 'cramfs' is disabled lineinfile: create: true dest: /etc/modprobe.d/cramfs.conf regexp: install\s+cramfs line: install cramfs /bin/false when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040025 - 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_cramfs_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Gather the package facts package_facts: manager: auto tags: - 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_freevxfs_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Ensure kernel module 'freevxfs' is disabled lineinfile: create: true dest: /etc/modprobe.d/freevxfs.conf regexp: install\s+freevxfs line: install freevxfs /bin/false when: '"kernel" in ansible_facts.packages' tags: - 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_freevxfs_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Gather the package facts package_facts: manager: auto tags: - 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_hfs_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Ensure kernel module 'hfs' is disabled lineinfile: create: true dest: /etc/modprobe.d/hfs.conf regexp: install\s+hfs line: install hfs /bin/false when: '"kernel" in ansible_facts.packages' tags: - 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_hfs_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Gather the package facts package_facts: manager: auto tags: - 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_hfsplus_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Ensure kernel module 'hfsplus' is disabled lineinfile: create: true dest: /etc/modprobe.d/hfsplus.conf regexp: install\s+hfsplus line: install hfsplus /bin/false when: '"kernel" in ansible_facts.packages' tags: - 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_hfsplus_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Gather the package facts package_facts: manager: auto tags: - 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_jffs2_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Ensure kernel module 'jffs2' is disabled lineinfile: create: true dest: /etc/modprobe.d/jffs2.conf regexp: install\s+jffs2 line: install jffs2 /bin/false when: '"kernel" in ansible_facts.packages' tags: - 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_jffs2_disabled - low_complexity - low_severity - medium_disruption - reboot_required - name: Gather the package facts package_facts: manager: auto tags: - 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 disabled lineinfile: create: true dest: /etc/modprobe.d/squashfs.conf regexp: install\s+squashfs line: install squashfs /bin/false when: '"kernel" in ansible_facts.packages' tags: - 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: Gather the package facts package_facts: manager: auto tags: - 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 disabled lineinfile: create: true dest: /etc/modprobe.d/udf.conf regexp: install\s+udf line: install udf /bin/false when: '"kernel" in ansible_facts.packages' tags: - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040080 - 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 - PCI-DSSv4-3.4 - PCI-DSSv4-3.4.2 - disable_strategy - kernel_module_usb-storage_disabled - low_complexity - medium_disruption - medium_severity - 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/false when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040080 - 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 - PCI-DSSv4-3.4 - PCI-DSSv4-3.4.2 - disable_strategy - kernel_module_usb-storage_disabled - low_complexity - medium_disruption - medium_severity - reboot_required - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040120 - 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: Check information associated to mountpoint' command: findmnt '/dev/shm' register: device_name failed_when: device_name.rc > 1 changed_when: false when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) tags: - DISA-STIG-RHEL-08-040120 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - DISA-STIG-RHEL-08-040120 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - ("" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040120 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - mount_info is defined and "nodev" not in mount_info.options tags: - DISA-STIG-RHEL-08-040120 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("" | length == 0) tags: - DISA-STIG-RHEL-08-040120 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040122 - 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: Check information associated to mountpoint' command: findmnt '/dev/shm' register: device_name failed_when: device_name.rc > 1 changed_when: false when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) tags: - DISA-STIG-RHEL-08-040122 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - DISA-STIG-RHEL-08-040122 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - ("" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040122 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - mount_info is defined and "noexec" not in mount_info.options tags: - DISA-STIG-RHEL-08-040122 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("" | length == 0) tags: - DISA-STIG-RHEL-08-040122 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040121 - 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: Check information associated to mountpoint' command: findmnt '/dev/shm' register: device_name failed_when: device_name.rc > 1 changed_when: false when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) tags: - DISA-STIG-RHEL-08-040121 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: - DISA-STIG-RHEL-08-040121 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - ("" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040121 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - mount_info is defined and "nosuid" not in mount_info.options tags: - DISA-STIG-RHEL-08-040121 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("" | length == 0) tags: - DISA-STIG-RHEL-08-040121 - 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: Gather the package facts package_facts: manager: auto tags: - configure_strategy - high_disruption - low_complexity - mount_option_home_nodev - no_reboot_needed - unknown_severity - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/home" in ansible_mounts | map(attribute="mount") | list' tags: - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/home" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/home" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "nodev" not in mount_info.options tags: - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/home" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - configure_strategy - high_disruption - low_complexity - mount_option_home_nodev - no_reboot_needed - unknown_severity - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-010570 - 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: Check information associated to mountpoint' command: findmnt --fstab '/home' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/home" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-010570 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-010570 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/home" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-010570 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/home" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "nosuid" not in mount_info.options tags: - DISA-STIG-RHEL-08-010570 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/home" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-010570 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040123 - 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: Check information associated to mountpoint' command: findmnt --fstab '/tmp' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/tmp" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-040123 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-040123 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/tmp" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040123 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/tmp" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "nodev" not in mount_info.options tags: - DISA-STIG-RHEL-08-040123 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/tmp" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-040123 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040125 - 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: Check information associated to mountpoint' command: findmnt --fstab '/tmp' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/tmp" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-040125 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-040125 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/tmp" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040125 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/tmp" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "noexec" not in mount_info.options tags: - DISA-STIG-RHEL-08-040125 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/tmp" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-040125 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040124 - 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: Check information associated to mountpoint' command: findmnt --fstab '/tmp' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/tmp" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-040124 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-040124 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/tmp" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040124 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/tmp" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "nosuid" not in mount_info.options tags: - DISA-STIG-RHEL-08-040124 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/tmp" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-040124 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040129 - 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: Check information associated to mountpoint' command: findmnt --fstab '/var/log/audit' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-040129 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-040129 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040129 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "nodev" not in mount_info.options tags: - DISA-STIG-RHEL-08-040129 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-040129 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040131 - 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: Check information associated to mountpoint' command: findmnt --fstab '/var/log/audit' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-040131 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-040131 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040131 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "noexec" not in mount_info.options tags: - DISA-STIG-RHEL-08-040131 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-040131 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040130 - 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: Check information associated to mountpoint' command: findmnt --fstab '/var/log/audit' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-040130 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-040130 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040130 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "nosuid" not in mount_info.options tags: - DISA-STIG-RHEL-08-040130 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-040130 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040126 - 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: Check information associated to mountpoint' command: findmnt --fstab '/var/log' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-040126 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-040126 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040126 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "nodev" not in mount_info.options tags: - DISA-STIG-RHEL-08-040126 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-040126 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040128 - 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: Check information associated to mountpoint' command: findmnt --fstab '/var/log' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-040128 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-040128 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040128 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "noexec" not in mount_info.options tags: - DISA-STIG-RHEL-08-040128 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-040128 - 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: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040127 - 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: Check information associated to mountpoint' command: findmnt --fstab '/var/log' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-040127 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-040127 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040127 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "nosuid" not in mount_info.options tags: - DISA-STIG-RHEL-08-040127 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/log" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-040127 - 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: Gather the package facts package_facts: manager: auto tags: - 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: Check information associated to mountpoint' command: findmnt --fstab '/var' register: device_name failed_when: device_name.rc > 1 changed_when: false when: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var" in ansible_mounts | map(attribute="mount") | list' tags: - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "nodev" not in mount_info.options tags: - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - 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: Gather the package facts package_facts: manager: auto tags: - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_nosuid - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var" in ansible_mounts | map(attribute="mount") | list' tags: - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_nosuid - no_reboot_needed - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_nosuid - no_reboot_needed - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_nosuid - no_reboot_needed - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "nosuid" not in mount_info.options tags: - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_nosuid - no_reboot_needed - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_nosuid - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040132 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nodev - no_reboot_needed - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-040132 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-040132 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040132 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "nodev" not in mount_info.options tags: - DISA-STIG-RHEL-08-040132 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-040132 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nodev - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040134 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_noexec - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-040134 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-040134 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040134 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "noexec" not in mount_info.options tags: - DISA-STIG-RHEL-08-040134 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-040134 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_noexec - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040133 - configure_strategy - high_disruption - low_complexity - medium_severity - mount_option_var_tmp_nosuid - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list' tags: - DISA-STIG-RHEL-08-040133 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/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: - DISA-STIG-RHEL-08-040133 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list' - ("--fstab" | length == 0) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length == 0) tags: - DISA-STIG-RHEL-08-040133 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined and "nosuid" not in mount_info.options tags: - DISA-STIG-RHEL-08-040133 - 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: - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages and "bootc" in ansible_facts.packages ) and not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] ) ) - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list' - mount_info is defined - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - DISA-STIG-RHEL-08-040133 - 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: - DISA-STIG-RHEL-08-040282 - NIST-800-53-SC-7(10) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_kernel_yama_ptrace_scope - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ - /usr/lib/sysctl.d/ contains: ^[\s]*kernel.yama.ptrace_scope.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040282 - NIST-800-53-SC-7(10) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_kernel_yama_ptrace_scope - name: Comment out any occurrences of kernel.yama.ptrace_scope from config files replace: path: '{{ item.path }}' regexp: ^[\s]*kernel.yama.ptrace_scope replace: '#kernel.yama.ptrace_scope' loop: '{{ find_sysctl_d.files }}' when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040282 - NIST-800-53-SC-7(10) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_kernel_yama_ptrace_scope - name: Ensure sysctl kernel.yama.ptrace_scope is set to 1 sysctl: name: kernel.yama.ptrace_scope value: '1' sysctl_file: /etc/sysctl.conf state: present reload: true when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040282 - NIST-800-53-SC-7(10) - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_kernel_yama_ptrace_scope - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-010675 - NIST-800-53-CM-6 - PCI-DSS-Req-3.2 - PCI-DSSv4-3.3 - PCI-DSSv4-3.3.1 - PCI-DSSv4-3.3.1.1 - coredump_disable_backtraces - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set 'ProcessSizeMax' to '0' in the [Coredump] section of '/etc/systemd/coredump.conf' ini_file: path: /etc/systemd/coredump.conf section: Coredump option: ProcessSizeMax value: '0' create: true mode: 420 when: '"systemd" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010675 - NIST-800-53-CM-6 - PCI-DSS-Req-3.2 - PCI-DSSv4-3.3 - PCI-DSSv4-3.3.1 - PCI-DSSv4-3.3.1.1 - coredump_disable_backtraces - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-010674 - NIST-800-53-CM-6 - PCI-DSS-Req-3.2 - PCI-DSSv4-3.3 - PCI-DSSv4-3.3.1 - PCI-DSSv4-3.3.1.1 - coredump_disable_storage - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set 'Storage' to 'none' in the [Coredump] section of '/etc/systemd/coredump.conf' ini_file: path: /etc/systemd/coredump.conf section: Coredump option: Storage value: none create: true mode: 420 when: '"systemd" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010674 - NIST-800-53-CM-6 - PCI-DSS-Req-3.2 - PCI-DSSv4-3.3 - PCI-DSSv4-3.3.1 - PCI-DSSv4-3.3.1.1 - coredump_disable_storage - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-010430 - 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-3.3 - PCI-DSSv4-3.3.1 - PCI-DSSv4-3.3.1.1 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_kernel_randomize_va_space - name: List /etc/sysctl.d/*.conf files find: paths: - /etc/sysctl.d/ - /run/sysctl.d/ - /usr/local/lib/sysctl.d/ - /usr/lib/sysctl.d/ contains: ^[\s]*kernel.randomize_va_space.*$ patterns: '*.conf' file_type: any register: find_sysctl_d when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010430 - 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-3.3 - PCI-DSSv4-3.3.1 - PCI-DSSv4-3.3.1.1 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010430 - 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-3.3 - PCI-DSSv4-3.3.1 - PCI-DSSv4-3.3.1.1 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010430 - 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-3.3 - PCI-DSSv4-3.3.1 - PCI-DSSv4-3.3.1.1 - disable_strategy - low_complexity - medium_disruption - medium_severity - reboot_required - sysctl_kernel_randomize_va_space - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - enable_strategy - high_severity - low_complexity - low_disruption - no_reboot_needed - package_libselinux_installed - name: Ensure libselinux is installed package: name: libselinux state: present when: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - enable_strategy - high_severity - low_complexity - low_disruption - no_reboot_needed - package_libselinux_installed - name: Gather the package facts package_facts: manager: auto tags: - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_mcstrans_removed - name: Ensure mcstrans is removed package: name: mcstrans state: absent when: '"kernel" in ansible_facts.packages' tags: - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_mcstrans_removed - name: Gather the package facts package_facts: manager: auto tags: - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_setroubleshoot_removed - name: Ensure setroubleshoot is removed package: name: setroubleshoot state: absent when: '"kernel" in ansible_facts.packages' tags: - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_setroubleshoot_removed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - grub2_enable_selinux - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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: - '"kernel" in ansible_facts.packages' - '"grub2-common" in ansible_facts.packages' tags: - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - 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: - '"kernel" in ansible_facts.packages' - '"grub2-common" in ansible_facts.packages' tags: - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - 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: - '"kernel" in ansible_facts.packages' - '"grub2-common" in ansible_facts.packages' tags: - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - 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: - '"kernel" in ansible_facts.packages' - '"grub2-common" in ansible_facts.packages' tags: - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - 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: - '"kernel" in ansible_facts.packages' - '"grub2-common" in ansible_facts.packages' - result_grub2_cfg_present.stat.exists tags: - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - 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: - '"kernel" in ansible_facts.packages' - '"grub2-common" in ansible_facts.packages' - result_default_grub_present.stat.exists tags: - NIST-800-171-3.1.2 - NIST-800-171-3.7.2 - NIST-800-53-AC-3 - NIST-800-53-AC-3(3)(a) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - grub2_enable_selinux - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - high_severity - low_complexity - low_disruption - reboot_required - restrict_strategy - selinux_not_disabled - name: Ensure SELinux is Not Disabled block: - name: Check for duplicate values lineinfile: path: /etc/selinux/config create: true regexp: (?i)^SELINUX= state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/selinux/config lineinfile: path: /etc/selinux/config create: true regexp: (?i)^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: (?i)^SELINUX= line: SELINUX=permissive state: present when: '"kernel" in ansible_facts.packages' tags: - high_severity - low_complexity - low_disruption - reboot_required - restrict_strategy - selinux_not_disabled - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-010450 - 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) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - selinux_policytype - name: Configure SELinux Policy block: - name: Check for duplicate values lineinfile: path: /etc/selinux/config create: true regexp: (?i)^SELINUXTYPE= state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/selinux/config lineinfile: path: /etc/selinux/config create: true regexp: (?i)^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: (?i)^SELINUXTYPE= line: SELINUXTYPE={{ var_selinux_policy_name }} state: present when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010450 - 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) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - selinux_policytype - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-010170 - 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) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy - selinux_state - name: Ensure SELinux State is Enforcing block: - name: Check for duplicate values lineinfile: path: /etc/selinux/config create: true regexp: (?i)^SELINUX= state: absent check_mode: true changed_when: false register: dupes - name: Deduplicate values from /etc/selinux/config lineinfile: path: /etc/selinux/config create: true regexp: (?i)^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: (?i)^SELINUX= line: SELINUX={{ var_selinux_state }} state: present when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010170 - 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) - PCI-DSSv4-1.2 - PCI-DSSv4-1.2.6 - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy - selinux_state - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_avahi-daemon_disabled - name: Disable Avahi Server Software - Collect systemd Services Present in the System ansible.builtin.command: systemctl -q list-unit-files --type service register: service_exists changed_when: false failed_when: service_exists.rc not in [0, 1] check_mode: false when: ( "avahi" in ansible_facts.packages and "kernel" in ansible_facts.packages ) tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_avahi-daemon_disabled - name: Disable Avahi Server Software - Ensure avahi-daemon.service is Masked ansible.builtin.systemd: name: avahi-daemon.service state: stopped enabled: false masked: true when: - ( "avahi" in ansible_facts.packages and "kernel" in ansible_facts.packages ) - service_exists.stdout_lines is search("avahi-daemon.service", multiline=True) tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_avahi-daemon_disabled - name: Unit Socket Exists - avahi-daemon.socket ansible.builtin.command: systemctl -q list-unit-files avahi-daemon.socket register: socket_file_exists changed_when: false failed_when: socket_file_exists.rc not in [0, 1] check_mode: false when: ( "avahi" in ansible_facts.packages and "kernel" in ansible_facts.packages ) tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_avahi-daemon_disabled - name: Disable Avahi Server Software - Disable Socket avahi-daemon ansible.builtin.systemd: name: avahi-daemon.socket enabled: false state: stopped masked: true when: - ( "avahi" in ansible_facts.packages and "kernel" in ansible_facts.packages ) - socket_file_exists.stdout_lines is search("avahi-daemon.socket", multiline=True) tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_avahi-daemon_disabled - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-CM-6(a) - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_crond_enabled - name: Enable cron Service - Enable service crond block: - name: Gather the package facts package_facts: manager: auto - name: Enable cron Service - Enable Service crond ansible.builtin.systemd: name: crond enabled: true state: started masked: false when: - '"cronie" in ansible_facts.packages' when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-CM-6(a) - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_crond_enabled - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_d - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure group owner on /etc/cron.d/ file: path: /etc/cron.d/ state: directory group: '0' when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_d - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_daily - 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: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_daily - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_hourly - 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: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_hourly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_monthly - 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: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_monthly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_weekly - 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: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_weekly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_crontab - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/crontab stat: path: /etc/crontab register: file_exists when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - 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: - '"kernel" in ansible_facts.packages' - file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_crontab - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_d - 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: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_d - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_daily - 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: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_daily - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_hourly - 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: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_hourly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_monthly - 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: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_monthly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_weekly - 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: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_weekly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_crontab - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/crontab stat: path: /etc/crontab register: file_exists when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - 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: - '"kernel" in ansible_facts.packages' - file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_crontab - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_d - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/cron.d/ file(s) command: 'find -H /etc/cron.d/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt -type d ' register: files_found changed_when: false failed_when: false check_mode: false when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - 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.d/ file(s) file: path: '{{ item }}' mode: u-s,g-xwrs,o-xwrt state: directory with_items: - '{{ files_found.stdout_lines }}' when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_d - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_daily - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/cron.daily/ file(s) command: 'find -H /etc/cron.daily/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt -type d ' register: files_found changed_when: false failed_when: false check_mode: false when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - 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.daily/ file(s) file: path: '{{ item }}' mode: u-s,g-xwrs,o-xwrt state: directory with_items: - '{{ files_found.stdout_lines }}' when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_daily - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_hourly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/cron.hourly/ file(s) command: 'find -H /etc/cron.hourly/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt -type d ' register: files_found changed_when: false failed_when: false check_mode: false when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - 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.hourly/ file(s) file: path: '{{ item }}' mode: u-s,g-xwrs,o-xwrt state: directory with_items: - '{{ files_found.stdout_lines }}' when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_hourly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_monthly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/cron.monthly/ file(s) command: 'find -H /etc/cron.monthly/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt -type d ' register: files_found changed_when: false failed_when: false check_mode: false when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - 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.monthly/ file(s) file: path: '{{ item }}' mode: u-s,g-xwrs,o-xwrt state: directory with_items: - '{{ files_found.stdout_lines }}' when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_monthly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_weekly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/cron.weekly/ file(s) command: 'find -H /etc/cron.weekly/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt -type d ' register: files_found changed_when: false failed_when: false check_mode: false when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_weekly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set permissions for /etc/cron.weekly/ file(s) file: path: '{{ item }}' mode: u-s,g-xwrs,o-xwrt state: directory with_items: - '{{ files_found.stdout_lines }}' when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_weekly - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_crontab - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Test for existence /etc/crontab stat: path: /etc/crontab register: file_exists when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - 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: - '"kernel" in ansible_facts.packages' - file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_crontab - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - disable_strategy - file_at_deny_not_exist - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Remove /etc/at.deny file: path: /etc/at.deny state: absent when: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - disable_strategy - file_at_deny_not_exist - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - disable_strategy - file_cron_allow_exists - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Add empty /etc/cron.allow file: path: /etc/cron.allow state: touch owner: '0' mode: '0600' when: '"kernel" in ansible_facts.packages' tags: - disable_strategy - file_cron_allow_exists - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - disable_strategy - file_cron_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: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - disable_strategy - file_cron_deny_not_exist - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - 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/at.allow stat: path: /etc/at.allow register: file_exists when: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - 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: - '"kernel" in ansible_facts.packages' - file_exists.stat is defined and file_exists.stat.exists tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_at_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - 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: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - 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: - '"kernel" in ansible_facts.packages' - file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_groupowner_cron_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - 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/cron.allow stat: path: /etc/cron.allow register: file_exists when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - 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: - '"kernel" in ansible_facts.packages' - file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_owner_cron_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - 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/at.allow stat: path: /etc/at.allow register: file_exists when: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - 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-xws,o-xwrt on /etc/at.allow file: path: /etc/at.allow mode: u-xs,g-xws,o-xwrt when: - '"kernel" in ansible_facts.packages' - file_exists.stat is defined and file_exists.stat.exists tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_at_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_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: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - 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-xws,o-xwrt on /etc/cron.allow file: path: /etc/cron.allow mode: u-xs,g-xws,o-xwrt when: - '"kernel" in ansible_facts.packages' - file_exists.stat is defined and file_exists.stat.exists tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_cron_allow - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure dhcp is removed package: name: dhcp state: absent tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_dhcp_removed - name: Ensure bind is removed package: name: bind state: absent tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_bind_removed - name: Ensure ftp is removed package: name: ftp state: absent tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_ftp_removed - name: Ensure vsftpd is removed package: name: vsftpd state: absent tags: - DISA-STIG-RHEL-08-040360 - 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) - disable_strategy - high_severity - low_complexity - low_disruption - no_reboot_needed - package_vsftpd_removed - name: Ensure httpd is removed package: name: httpd state: absent tags: - 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_httpd_removed - unknown_severity - name: Ensure nginx is removed package: name: nginx state: absent tags: - 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 - name: Ensure cyrus-imapd is removed package: name: cyrus-imapd state: absent tags: - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_cyrus-imapd_removed - unknown_severity - name: Ensure dovecot is removed package: name: dovecot state: absent tags: - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_dovecot_removed - unknown_severity - name: Ensure openldap-clients is removed package: name: openldap-clients state: absent tags: - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_openldap-clients_removed - name: Gather list of packages package_facts: manager: auto when: - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '' tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - 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: (?i)^inet_interfaces\s*=\s.* line: inet_interfaces = {{ var_postfix_inet_interfaces }} state: present insertafter: ^inet_interfaces\s*=\s.* when: - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - '"postfix" in ansible_facts.packages' - '"postfix" in ansible_facts.packages' tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-1.4 - PCI-DSSv4-1.4.2 - low_complexity - low_disruption - medium_severity - no_reboot_needed - postfix_network_listening_disabled - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - service_rpcbind_disabled - name: Disable rpcbind Service - Collect systemd Services Present in the System ansible.builtin.command: systemctl -q list-unit-files --type service register: service_exists changed_when: false failed_when: service_exists.rc not in [0, 1] check_mode: false when: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - service_rpcbind_disabled - name: Disable rpcbind Service - Ensure rpcbind.service is Masked ansible.builtin.systemd: name: rpcbind.service state: stopped enabled: false masked: true when: - '"kernel" in ansible_facts.packages' - service_exists.stdout_lines is search("rpcbind.service", multiline=True) tags: - PCI-DSSv4-2.2 - 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 ansible.builtin.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: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - service_rpcbind_disabled - name: Disable rpcbind Service - Disable Socket rpcbind ansible.builtin.systemd: name: rpcbind.socket enabled: false state: stopped masked: true when: - '"kernel" in ansible_facts.packages' - socket_file_exists.stdout_lines is search("rpcbind.socket", multiline=True) tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - service_rpcbind_disabled - name: Gather the package facts package_facts: manager: auto tags: - 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 Network File System (nfs) - Collect systemd Services Present in the System ansible.builtin.command: systemctl -q list-unit-files --type service register: service_exists changed_when: false failed_when: service_exists.rc not in [0, 1] check_mode: false when: '"kernel" in ansible_facts.packages' tags: - 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 Network File System (nfs) - Ensure nfs-server.service is Masked ansible.builtin.systemd: name: nfs-server.service state: stopped enabled: false masked: true when: - '"kernel" in ansible_facts.packages' - service_exists.stdout_lines is search("nfs-server.service", multiline=True) tags: - 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 ansible.builtin.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: '"kernel" in ansible_facts.packages' tags: - 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 Network File System (nfs) - Disable Socket nfs-server ansible.builtin.systemd: name: nfs-server.socket enabled: false state: stopped masked: true when: - '"kernel" in ansible_facts.packages' - socket_file_exists.stdout_lines is search("nfs-server.socket", multiline=True) tags: - 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: - PCI-DSS-Req-10.4 - PCI-DSSv4-10.6 - PCI-DSSv4-10.6.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_chrony_installed - name: Ensure chrony is installed package: name: chrony state: present when: '"kernel" in ansible_facts.packages' tags: - PCI-DSS-Req-10.4 - PCI-DSSv4-10.6 - PCI-DSSv4-10.6.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_chrony_installed - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-030740 - NIST-800-53-AU-8(1)(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.3 - PCI-DSSv4-10.6 - PCI-DSSv4-10.6.2 - chronyd_specify_remote_server - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - 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: - '"kernel" in ansible_facts.packages' - '"chrony" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030740 - NIST-800-53-AU-8(1)(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.3 - PCI-DSSv4-10.6 - 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: - '"kernel" in ansible_facts.packages' - '"chrony" in ansible_facts.packages' - chrony_servers.matched == 0 tags: - DISA-STIG-RHEL-08-030740 - NIST-800-53-AU-8(1)(a) - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.4.3 - PCI-DSSv4-10.6 - PCI-DSSv4-10.6.2 - chronyd_specify_remote_server - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-10.6 - PCI-DSSv4-10.6.3 - chronyd_run_as_chrony_user - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Detect if file /etc/sysconfig/chronyd is not empty or missing find: path: /etc/sysconfig/ patterns: chronyd contains: ^([\s]*OPTIONS=["]?[^"]*)("?) register: chronyd_file when: - '"kernel" in ansible_facts.packages' - '"chrony" in ansible_facts.packages' tags: - PCI-DSSv4-10.6 - PCI-DSSv4-10.6.3 - chronyd_run_as_chrony_user - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Remove any previous configuration of user used to run chronyd process replace: path: /etc/sysconfig/chronyd regexp: \s*-u\s*\w+\s* replace: ' ' when: - '"kernel" in ansible_facts.packages' - '"chrony" in ansible_facts.packages' - chronyd_file is defined and chronyd_file.matched > 0 tags: - PCI-DSSv4-10.6 - PCI-DSSv4-10.6.3 - chronyd_run_as_chrony_user - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Correct existing line in /etc/sysconfig/chronyd to run chronyd as chrony user lineinfile: path: /etc/sysconfig/chronyd regexp: ^([\s]*OPTIONS=["]?[^"]*)("?) line: \1 -u chrony\2 state: present backrefs: true when: - '"kernel" in ansible_facts.packages' - '"chrony" in ansible_facts.packages' - chronyd_file is defined and chronyd_file.matched > 0 tags: - PCI-DSSv4-10.6 - PCI-DSSv4-10.6.3 - chronyd_run_as_chrony_user - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Insert correct line into /etc/sysconfig/chronyd ensuring chronyd runs as chrony user lineinfile: path: /etc/sysconfig/chronyd line: OPTIONS="-u chrony" state: present create: true when: - '"kernel" in ansible_facts.packages' - '"chrony" in ansible_facts.packages' - chronyd_file is defined and chronyd_file.matched == 0 tags: - PCI-DSSv4-10.6 - PCI-DSSv4-10.6.3 - chronyd_run_as_chrony_user - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Ensure rsync is removed package: name: rsync state: absent tags: - disable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_rsync_removed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_xinetd_removed - name: Ensure xinetd is removed package: name: xinetd state: absent when: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_xinetd_removed - name: Ensure ypbind is removed package: name: ypbind state: absent tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_ypbind_removed - unknown_severity - name: Ensure ypserv is removed package: name: ypserv state: absent tags: - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - NIST-800-53-IA-5(1)(c) - PCI-DSS-Req-2.2.2 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - high_severity - low_complexity - low_disruption - no_reboot_needed - package_ypserv_removed - name: Gather the package facts package_facts: manager: auto tags: - 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: 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 when: '"rsh-server" in ansible_facts.packages' tags: - 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 .rhosts files file: path: '{{ item }}' state: absent with_items: '{{ rhosts_locations.files | map(attribute=''path'') | list }}' when: - '"rsh-server" in ansible_facts.packages' - rhosts_locations is success tags: - 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 when: '"rsh-server" in ansible_facts.packages' tags: - 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: Ensure telnet-server is removed package: name: telnet-server state: absent tags: - DISA-STIG-RHEL-08-040000 - 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 - PCI-DSSv4-2.2.4 - disable_strategy - high_severity - low_complexity - low_disruption - no_reboot_needed - package_telnet-server_removed - name: Ensure telnet is removed package: name: telnet state: absent tags: - NIST-800-171-3.1.13 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_telnet_removed - name: Ensure tftp-server is removed package: name: tftp-server state: absent tags: - DISA-STIG-RHEL-08-040190 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - high_severity - low_complexity - low_disruption - no_reboot_needed - package_tftp-server_removed - name: Ensure tftp is removed package: name: tftp state: absent tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - low_severity - no_reboot_needed - package_tftp_removed - name: Gather the package facts package_facts: manager: auto tags: - 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_cups_disabled - unknown_severity - name: Disable the CUPS Service - Collect systemd Services Present in the System ansible.builtin.command: systemctl -q list-unit-files --type service register: service_exists changed_when: false failed_when: service_exists.rc not in [0, 1] check_mode: false when: '"kernel" in ansible_facts.packages' tags: - 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_cups_disabled - unknown_severity - name: Disable the CUPS Service - Ensure cups.service is Masked ansible.builtin.systemd: name: cups.service state: stopped enabled: false masked: true when: - '"kernel" in ansible_facts.packages' - service_exists.stdout_lines is search("cups.service", multiline=True) tags: - 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_cups_disabled - unknown_severity - name: Unit Socket Exists - cups.socket ansible.builtin.command: systemctl -q list-unit-files cups.socket register: socket_file_exists changed_when: false failed_when: socket_file_exists.rc not in [0, 1] check_mode: false when: '"kernel" in ansible_facts.packages' tags: - 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_cups_disabled - unknown_severity - name: Disable the CUPS Service - Disable Socket cups ansible.builtin.systemd: name: cups.socket enabled: false state: stopped masked: true when: - '"kernel" in ansible_facts.packages' - socket_file_exists.stdout_lines is search("cups.socket", multiline=True) tags: - 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_cups_disabled - unknown_severity - name: Ensure squid is removed package: name: squid state: absent tags: - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_squid_removed - unknown_severity - name: Ensure samba is removed package: name: samba state: absent tags: - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_samba_removed - unknown_severity - name: Ensure net-snmp is removed package: name: net-snmp state: absent tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.4 - disable_strategy - low_complexity - low_disruption - no_reboot_needed - package_net-snmp_removed - unknown_severity - name: Gather the package facts package_facts: manager: auto tags: - 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: Test for existence /etc/ssh/sshd_config stat: path: /etc/ssh/sshd_config register: file_exists when: '"kernel" in ansible_facts.packages' tags: - 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: - '"kernel" in ansible_facts.packages' - file_exists.stat is defined and file_exists.stat.exists tags: - 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: Gather the package facts package_facts: manager: auto tags: - configure_strategy - file_groupownership_sshd_private_key - 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 -regextype posix-extended -regex "^.*_key$" register: files_found changed_when: false failed_when: false check_mode: false when: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - configure_strategy - file_groupownership_sshd_private_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - configure_strategy - file_groupownership_sshd_pub_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 -regextype posix-extended -regex "^.*\.pub$" register: files_found changed_when: false failed_when: false check_mode: false when: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - configure_strategy - file_groupownership_sshd_pub_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - 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: Test for existence /etc/ssh/sshd_config stat: path: /etc/ssh/sshd_config register: file_exists when: '"kernel" in ansible_facts.packages' tags: - 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: - '"kernel" in ansible_facts.packages' - file_exists.stat is defined and file_exists.stat.exists tags: - 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: Gather the package facts package_facts: manager: auto tags: - configure_strategy - file_ownership_sshd_private_key - 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 -regextype posix-extended -regex "^.*_key$" register: files_found changed_when: false failed_when: false check_mode: false when: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - configure_strategy - file_ownership_sshd_private_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - configure_strategy - file_ownership_sshd_pub_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 -regextype posix-extended -regex "^.*\.pub$" register: files_found changed_when: false failed_when: false check_mode: false when: '"kernel" in ansible_facts.packages' tags: - 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: '"kernel" in ansible_facts.packages' tags: - configure_strategy - file_ownership_sshd_pub_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_config - 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: '"kernel" in ansible_facts.packages' tags: - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - 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: - '"kernel" in ansible_facts.packages' - file_exists.stat is defined and file_exists.stat.exists tags: - NIST-800-53-AC-17(a) - NIST-800-53-AC-6(1) - NIST-800-53-CM-6(a) - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_config - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-010490 - 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 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_private_key - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010490 - 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 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010490 - 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 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010490 - 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 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010490 - 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 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_private_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-010480 - 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 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_pub_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 -regextype posix-extended -regex "^.*\.pub$" register: files_found changed_when: false failed_when: false check_mode: false when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010480 - 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 - 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: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-010480 - 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 - PCI-DSSv4-2.2.6 - configure_strategy - file_permissions_sshd_pub_key - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.5.6 - DISA-STIG-RHEL-08-010200 - 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 - PCI-DSSv4-8.2.8 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_keepalive - name: Set SSH Client Alive Count Max block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?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: true regexp: (?i)(?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)(?i)^\s*ClientAliveCountMax\s+ line: ClientAliveCountMax {{ var_sshd_set_keepalive }} state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.5.6 - DISA-STIG-RHEL-08-010200 - 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 - PCI-DSSv4-8.2.8 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_keepalive - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.5.6 - DISA-STIG-RHEL-08-010201 - 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 - PCI-DSSv4-8.2.8 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_idle_timeout - name: Set SSH Client Alive Interval block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?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: true regexp: (?i)(?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)(?i)^\s*ClientAliveInterval\s+ line: ClientAliveInterval {{ sshd_idle_timeout_value }} state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.5.6 - DISA-STIG-RHEL-08-010201 - 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 - PCI-DSSv4-8.2.8 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_idle_timeout - name: Gather the package facts package_facts: manager: auto tags: - 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 - PCI-DSSv4-8.3.1 - disable_host_auth - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Disable Host-Based Authentication block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?i)^\s*HostbasedAuthentication\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: true regexp: (?i)(?i)^\s*HostbasedAuthentication\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)(?i)^\s*HostbasedAuthentication\s+ line: HostbasedAuthentication no state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-8.3.1 - disable_host_auth - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.5.6 - DISA-STIG-RHEL-08-020330 - 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 - PCI-DSSv4-2.2.6 - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy - sshd_disable_empty_passwords - name: Disable SSH Access via Empty Passwords block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?i)^\s*PermitEmptyPasswords\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: true regexp: (?i)(?i)^\s*PermitEmptyPasswords\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)(?i)^\s*PermitEmptyPasswords\s+ line: PermitEmptyPasswords no state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.5.6 - DISA-STIG-RHEL-08-020330 - 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 - PCI-DSSv4-2.2.6 - high_severity - low_complexity - low_disruption - no_reboot_needed - restrict_strategy - sshd_disable_empty_passwords - name: Gather the package facts package_facts: manager: auto tags: - 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 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_disable_rhosts - name: Disable SSH Support for .rhosts Files block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?i)^\s*IgnoreRhosts\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: true regexp: (?i)(?i)^\s*IgnoreRhosts\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)(?i)^\s*IgnoreRhosts\s+ line: IgnoreRhosts yes state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_disable_rhosts - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.5.6 - DISA-STIG-RHEL-08-010550 - 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 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_disable_root_login - name: Disable SSH Root Login block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?i)^\s*PermitRootLogin\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: true regexp: (?i)(?i)^\s*PermitRootLogin\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)(?i)^\s*PermitRootLogin\s+ line: PermitRootLogin no state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.5.6 - DISA-STIG-RHEL-08-010550 - 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 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_disable_root_login - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.5.6 - DISA-STIG-RHEL-08-010830 - 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 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_do_not_permit_user_env - name: Do Not Allow SSH Environment Options block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?i)^\s*PermitUserEnvironment\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: true regexp: (?i)(?i)^\s*PermitUserEnvironment\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)(?i)^\s*PermitUserEnvironment\s+ line: PermitUserEnvironment no state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.5.6 - DISA-STIG-RHEL-08-010830 - 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 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_do_not_permit_user_env - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_enable_pam - name: Enable PAM block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?i)^\s*UsePAM\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: true regexp: (?i)(?i)^\s*UsePAM\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)(?i)^\s*UsePAM\s+ line: UsePAM yes state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_enable_pam - name: Gather the package facts package_facts: manager: auto tags: - 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: Enable SSH Warning Banner block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?i)^\s*Banner\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: true regexp: (?i)(?i)^\s*Banner\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)(?i)^\s*Banner\s+ line: Banner /etc/issue.net state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - 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: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_login_grace_time - name: Ensure SSH LoginGraceTime is configured block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?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: true regexp: (?i)(?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)(?i)^\s*LoginGraceTime\s+ line: LoginGraceTime {{ var_sshd_set_login_grace_time }} state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_login_grace_time - name: Gather the package facts package_facts: manager: auto tags: - 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 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_loglevel_verbose - name: Set SSH Daemon LogLevel to VERBOSE block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?i)^\s*LogLevel\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: true regexp: (?i)(?i)^\s*LogLevel\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)(?i)^\s*LogLevel\s+ line: LogLevel VERBOSE state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_loglevel_verbose - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_max_auth_tries - name: Set SSH authentication attempt limit block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?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: true regexp: (?i)(?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)(?i)^\s*MaxAuthTries\s+ line: MaxAuthTries {{ sshd_max_auth_tries_value }} state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_max_auth_tries - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_max_sessions - name: Set SSH MaxSessions limit block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?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: true regexp: (?i)(?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)(?i)^\s*MaxSessions\s+ line: MaxSessions {{ var_sshd_max_sessions }} state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_max_sessions - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_maxstartups - name: Ensure SSH MaxStartups is configured block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?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: true regexp: (?i)(?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)(?i)^\s*MaxStartups\s+ line: MaxStartups {{ var_sshd_set_maxstartups }} state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.6 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_set_maxstartups - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.5.6 - NIST-800-171-3.1.13 - NIST-800-171-3.13.11 - NIST-800-171-3.13.8 - NIST-800-53-AC-17(2) - NIST-800-53-AC-17(a) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(c) - NIST-800-53-MA-4(6) - NIST-800-53-SC-12(2) - NIST-800-53-SC-12(3) - NIST-800-53-SC-13 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.7 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_use_approved_ciphers - name: Use Only FIPS 140-2 Validated Ciphers block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?i)^\s*Ciphers\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: true regexp: (?i)(?i)^\s*Ciphers\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)(?i)^\s*Ciphers\s+ line: Ciphers {{ sshd_approved_ciphers }} state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - CJIS-5.5.6 - NIST-800-171-3.1.13 - NIST-800-171-3.13.11 - NIST-800-171-3.13.8 - NIST-800-53-AC-17(2) - NIST-800-53-AC-17(a) - NIST-800-53-CM-6(a) - NIST-800-53-IA-5(1)(c) - NIST-800-53-MA-4(6) - NIST-800-53-SC-12(2) - NIST-800-53-SC-12(3) - NIST-800-53-SC-13 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.7 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_use_approved_ciphers - name: Gather the package facts package_facts: manager: auto tags: - PCI-DSS-Req-2.3 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.7 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_use_strong_kex - name: Use Only Strong Key Exchange algorithms block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?i)^\s*KexAlgorithms\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: true regexp: (?i)(?i)^\s*KexAlgorithms\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)(?i)^\s*KexAlgorithms\s+ line: KexAlgorithms {{ sshd_strong_kex }} state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - PCI-DSS-Req-2.3 - PCI-DSSv4-2.2 - PCI-DSSv4-2.2.7 - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_use_strong_kex - name: Gather the package facts package_facts: manager: auto tags: - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_use_strong_macs - name: Use Only Strong MACs block: - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config create: true regexp: (?i)(?i)^\s*MACs\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: true regexp: (?i)(?i)^\s*MACs\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)(?i)^\s*MACs\s+ line: MACs {{ sshd_strong_macs }} state: present insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: '"kernel" in ansible_facts.packages' tags: - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - sshd_use_strong_macs - name: Ensure xorg-x11-server-common is removed package: name: xorg-x11-server-common state: absent tags: - 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 - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-040321 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - xwindows_runlevel_target - name: Switch to multi-user runlevel file: src: /usr/lib/systemd/system/multi-user.target dest: /etc/systemd/system/default.target state: link force: true when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-040321 - NIST-800-53-CM-6(a) - NIST-800-53-CM-7(a) - NIST-800-53-CM-7(b) - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - xwindows_runlevel_target - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-030180 - 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 - PCI-DSSv4-10.2.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - package_audit_installed - name: Ensure audit is installed package: name: audit state: present when: '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030180 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030181 - 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 - PCI-DSSv4-10.2.1 - enable_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - service_auditd_enabled - name: Enable auditd Service - Enable service auditd block: - name: Gather the package facts package_facts: manager: auto - name: Enable auditd Service - Enable Service auditd ansible.builtin.systemd: name: auditd enabled: true state: started masked: false when: - '"audit" in ansible_facts.packages' when: - '"kernel" in ansible_facts.packages' - '"audit" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030181 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030601 - 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 - PCI-DSSv4-10.7.2 - grub2_audit_argument - low_disruption - low_severity - medium_complexity - reboot_required - restrict_strategy - name: Update grub defaults and the bootloader menu command: /sbin/grubby --update-kernel=ALL --args="audit=1" when: - '"kernel" in ansible_facts.packages' - '"grub2-common" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030601 - 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 - PCI-DSSv4-10.7.2 - grub2_audit_argument - low_disruption - low_severity - medium_complexity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-030602 - NIST-800-53-CM-6(a) - PCI-DSSv4-10.7 - PCI-DSSv4-10.7.2 - grub2_audit_backlog_limit_argument - low_disruption - low_severity - medium_complexity - reboot_required - restrict_strategy - name: Update grub defaults and the bootloader menu command: /sbin/grubby --update-kernel=ALL --args="audit_backlog_limit=8192" when: - '"kernel" in ansible_facts.packages' - '"grub2-common" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030602 - NIST-800-53-CM-6(a) - PCI-DSSv4-10.7 - PCI-DSSv4-10.7.2 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030121 - 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 - PCI-DSSv4-10.3.2 - audit_rules_immutable - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030121 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030121 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030121 - 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 - 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: - 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 - 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/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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - 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 - 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: - 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/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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030302 - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.7 - audit_rules_media_export - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit mount tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030302 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030302 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030302 - 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 - PCI-DSSv4-10.2.1 - 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: - 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 - PCI-DSSv4-10.3.4 - audit_rules_networkconfig_modification - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set architecture for audit tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - 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 - 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: - audit_rules_networkconfig_modification_network_scripts - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/sysconfig/network-scripts already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+/etc/sysconfig/network-scripts\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - audit_rules_networkconfig_modification_network_scripts - 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_network_scripts find: paths: /etc/audit/rules.d contains: ^.*(?:-F key=|-k\s+)audit_rules_networkconfig_modification_network_scripts$ patterns: '*.rules' register: find_watch_key when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - audit_rules_networkconfig_modification_network_scripts - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Use /etc/audit/rules.d/audit_rules_networkconfig_modification_network_scripts.rules as the recipient for the rule set_fact: all_files: - /etc/audit/rules.d/audit_rules_networkconfig_modification_network_scripts.rules when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - audit_rules_networkconfig_modification_network_scripts - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - audit_rules_networkconfig_modification_network_scripts - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/sysconfig/network-scripts in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w /etc/sysconfig/network-scripts -p wa -k audit_rules_networkconfig_modification_network_scripts create: true mode: '0640' when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - audit_rules_networkconfig_modification_network_scripts - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Check if watch rule for /etc/sysconfig/network-scripts already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+/etc/sysconfig/network-scripts\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - audit_rules_networkconfig_modification_network_scripts - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Add watch rule for /etc/sysconfig/network-scripts in /etc/audit/audit.rules lineinfile: line: -w /etc/sysconfig/network-scripts -p wa -k audit_rules_networkconfig_modification_network_scripts state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - audit_rules_networkconfig_modification_network_scripts - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - 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 - PCI-DSSv4-10.2.1 - 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/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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - 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: - audit_rules_suid_auid_privilege_function - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Service facts ansible.builtin.service_facts: null when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - '"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: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - '"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: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - (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: - 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: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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/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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.5 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030170 - 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 - PCI-DSSv4-10.2.1 - 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/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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030170 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030170 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030170 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030170 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030170 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030170 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030170 - 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 - PCI-DSSv4-10.2.1 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030160 - 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 - PCI-DSSv4-10.2.1 - 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/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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030160 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030160 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030160 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030160 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030160 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030160 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030160 - 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 - PCI-DSSv4-10.2.1 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030140 - 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 - PCI-DSSv4-10.2.1 - 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/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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030140 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030140 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030140 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030140 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030140 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030140 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030140 - 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 - PCI-DSSv4-10.2.1 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030150 - 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 - PCI-DSSv4-10.2.1 - 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/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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030150 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030150 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030150 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030150 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030150 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030150 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030150 - 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 - PCI-DSSv4-10.2.1 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030130 - 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 - PCI-DSSv4-10.2.1 - 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/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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030130 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030130 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030130 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030130 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030130 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030130 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030130 - 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 - PCI-DSSv4-10.2.1 - 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: - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.3 - 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/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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.3 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.3 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.3 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.3 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.3 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.3 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - PCI-DSS-Req-10.2.2 - PCI-DSS-Req-10.2.5.b - PCI-DSSv4-10.2 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.3 - audit_sudo_log_events - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - configure_strategy - file_groupownership_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/audit/ file(s) matching ^.*audit(\.rules|d\.conf)$ command: find -H /etc/audit/ -maxdepth 1 -type f ! -group 0 -regextype posix-extended -regex "^.*audit(\.rules|d\.conf)$" register: files_found changed_when: false failed_when: false check_mode: false when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 -regextype posix-extended -regex "^.*\.rules$" register: files_found changed_when: false failed_when: false check_mode: false when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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: - configure_strategy - file_ownership_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/audit/ file(s) matching ^.*audit(\.rules|d\.conf)$ command: find -H /etc/audit/ -maxdepth 1 -type f ! -uid 0 -regextype posix-extended -regex "^.*audit(\.rules|d\.conf)$" register: files_found changed_when: false failed_when: false check_mode: false when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 -regextype posix-extended -regex "^.*\.rules$" register: files_found changed_when: false failed_when: false check_mode: false when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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: - configure_strategy - file_permissions_audit_configuration - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Find /etc/audit/ file(s) command: find -H /etc/audit/ -maxdepth 1 -perm /u+xs,g+xws,o+xwrt -type f -regextype posix-extended -regex "^.*audit(\.rules|d\.conf)$" register: files_found changed_when: false failed_when: false check_mode: false when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 -regextype posix-extended -regex "^.*\.rules$" register: files_found changed_when: false failed_when: false check_mode: false when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030070 - 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 - PCI-DSSv4-10.3.1 - file_permissions_var_log_audit - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Get audit log files command: grep -iw ^log_file /etc/audit/auditd.conf failed_when: false register: log_file_exists when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030070 - 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 - 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: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - log_file_exists is not skipped and (log_file_exists.stdout | length > 0) tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030070 - 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 - 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: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - (log_file_exists is skipped) or (log_file_exists is undefined) or (log_file_exists.stdout | length == 0) tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030070 - 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 - 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: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - (log_file_exists is not skipped) and (log_file_line.stdout is defined) and (log_file_line.stdout | length > 0) tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030070 - 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 - PCI-DSSv4-10.3.1 - file_permissions_var_log_audit - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Get log files group command: grep -m 1 ^log_group /etc/audit/auditd.conf failed_when: false register: log_group_line when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030070 - 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 - PCI-DSSv4-10.3.1 - file_permissions_var_log_audit - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Parse log group line command: awk -F '=' '/log_group/ {print $2}' /etc/audit/auditd.conf register: log_group when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - (log_group_line is not skipped) and (log_group_line.stdout | length > 0) tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030070 - 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 - 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 when group root file: path: '{{ log_file }}' mode: (( log_group is defined ) and ( ( log_group.stdout | trim ) == 'root' )) | ternary( '0600', '0640') failed_when: false when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - log_group is not skipped tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030070 - 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 - PCI-DSSv4-10.3.1 - file_permissions_var_log_audit - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: List all log file backups find: path: '{{ log_file | dirname }}' patterns: '{{ log_file | basename }}.*' register: backup_files when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030070 - 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 - 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 when group not root file: path: '{{ item }}' mode: (( log_group is defined ) and ( ( log_group.stdout | trim ) == 'root' )) | ternary( '0400', '0440') loop: '{{ backup_files.files| map(attribute=''path'') | list }}' failed_when: false when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - backup_files is not skipped tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030070 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030490 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_chmod - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit chmod tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030490 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030490 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030490 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_chown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit chown tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030490 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchmod - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit fchmod tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030490 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030490 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030490 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030490 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchmodat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit fchmodat tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030490 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030490 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030490 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit fchown tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fchownat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit fchownat tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fremovexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit fremovexattr tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_fsetxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit fsetxattr tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lchown - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit lchown tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030480 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lremovexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit lremovexattr tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_lsetxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit lsetxattr tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_removexattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit removexattr tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - PCI-DSSv4-10.3.4 - audit_rules_dac_modification_setxattr - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit setxattr tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030200 - 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 - 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: - DISA-STIG-RHEL-08-030570 - audit_rules_execution_chacl - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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 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 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 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 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 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 auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030570 - 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: - DISA-STIG-RHEL-08-030330 - audit_rules_execution_setfacl - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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 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 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 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 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 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 auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030330 - 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: - DISA-STIG-RHEL-08-030260 - 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: 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 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 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 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 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 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 auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030260 - 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: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_rename - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit rename tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) tags: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - 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: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_renameat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit renameat tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - 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: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_unlink - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit unlink tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) tags: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - 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: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - PCI-DSSv4-10.2.1.7 - audit_rules_file_deletion_events_unlinkat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit unlinkat tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030361 - 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 - PCI-DSSv4-10.2.1 - 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: - DISA-STIG-RHEL-08-030420 - 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 - audit_rules_unsuccessful_file_modification_creat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit creat tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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: - DISA-STIG-RHEL-08-030420 - 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 - audit_rules_unsuccessful_file_modification_ftruncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit ftruncate tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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: - DISA-STIG-RHEL-08-030420 - 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 - audit_rules_unsuccessful_file_modification_open - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit open tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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: - DISA-STIG-RHEL-08-030420 - 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 - audit_rules_unsuccessful_file_modification_openat - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit openat tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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: - DISA-STIG-RHEL-08-030420 - 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 - audit_rules_unsuccessful_file_modification_truncate - low_complexity - low_disruption - medium_severity - reboot_required - restrict_strategy - name: Set architecture for audit truncate tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030420 - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030420 - 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 - 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: - audit_rules_kernel_module_loading_create - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set architecture for audit finit_module tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) tags: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - 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: - DISA-STIG-RHEL-08-030390 - 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 - audit_rules_kernel_module_loading_delete - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set architecture for audit delete_module tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - DISA-STIG-RHEL-08-030390 - 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 - 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+)* (-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: - 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+)* (-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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030390 - 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 - 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+)* (-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: - 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+)* (-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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030390 - 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 - 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: - DISA-STIG-RHEL-08-030360 - 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 - audit_rules_kernel_module_loading_finit - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set architecture for audit finit_module tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - DISA-STIG-RHEL-08-030360 - 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 - 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+)* (-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: - 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+)* (-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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030360 - 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 - 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+)* (-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: - 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+)* (-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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030360 - 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 - 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: - DISA-STIG-RHEL-08-030360 - 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 - audit_rules_kernel_module_loading_init - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set architecture for audit init_module tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - DISA-STIG-RHEL-08-030360 - 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 - 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+)* (-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: - 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+)* (-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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030360 - 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 - 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+)* (-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: - 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+)* (-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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - DISA-STIG-RHEL-08-030360 - 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 - 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: - audit_rules_kernel_module_loading_query - configure_strategy - low_complexity - low_disruption - medium_severity - no_reboot_needed - name: Set architecture for audit query_module tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) tags: - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - 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: - DISA-STIG-RHEL-08-030590 - 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 - PCI-DSSv4-10.2.1 - 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_accounts_passwords_pam_faillock_dir }} already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d contains: ^\s*-w\s+{{ var_accounts_passwords_pam_faillock_dir }}\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030590 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - DISA-STIG-RHEL-08-030590 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - DISA-STIG-RHEL-08-030590 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - DISA-STIG-RHEL-08-030590 - 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 - PCI-DSSv4-10.2.1 - 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_accounts_passwords_pam_faillock_dir }} in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' line: -w {{ var_accounts_passwords_pam_faillock_dir }} -p wa -k logins create: true mode: '0640' when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - DISA-STIG-RHEL-08-030590 - 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 - PCI-DSSv4-10.2.1 - 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_accounts_passwords_pam_faillock_dir }} already exists in /etc/audit/audit.rules find: paths: /etc/audit/ contains: ^\s*-w\s+{{ var_accounts_passwords_pam_faillock_dir }}\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030590 - 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 - PCI-DSSv4-10.2.1 - 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_accounts_passwords_pam_faillock_dir }} in /etc/audit/audit.rules lineinfile: line: -w {{ var_accounts_passwords_pam_faillock_dir }} -p wa -k logins state: present dest: /etc/audit/audit.rules create: true mode: '0640' when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - DISA-STIG-RHEL-08-030590 - 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 - PCI-DSSv4-10.2.1 - 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: - DISA-STIG-RHEL-08-030600 - 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 - PCI-DSSv4-10.2.1 - 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/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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030600 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - DISA-STIG-RHEL-08-030600 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - DISA-STIG-RHEL-08-030600 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - DISA-STIG-RHEL-08-030600 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - DISA-STIG-RHEL-08-030600 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030600 - 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 - PCI-DSSv4-10.2.1 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - DISA-STIG-RHEL-08-030600 - 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 - PCI-DSSv4-10.2.1 - 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: - 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 - 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 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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: '{{ privileged_commands | default([]) + item.stdout_lines }}' loop: '{{ result_privileged_commands_search.results }}' when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - item is not skipped tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - privileged_commands is defined tags: - 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 - 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: - DISA-STIG-RHEL-08-030580 - 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: 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 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 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 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 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 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 auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030580 - 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: - DISA-STIG-RHEL-08-030560 - audit_rules_privileged_commands_usermod - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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 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 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 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 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 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 auid>=1000 -F auid!=unset -F key=privileged create: true mode: o-rwx state: present when: syscalls_found | length == 0 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030560 - 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: - 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 - PCI-DSSv4-10.6.3 - audit_rules_time_adjtimex - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set architecture for audit tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - 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 - 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: - 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 - PCI-DSSv4-10.6.3 - audit_rules_time_clock_settime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set architecture for audit tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - 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 - 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: - 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 - PCI-DSSv4-10.6.3 - audit_rules_time_settimeofday - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Set architecture for audit tasks set_fact: audit_arch: b64 when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64" tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - audit_arch == "b64" tags: - 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 - 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: - 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 - PCI-DSSv4-10.6.3 - audit_rules_time_stime - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - ( not ( ansible_architecture == "aarch64" ) and not ( ansible_architecture == "s390x" ) ) tags: - 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 - 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: - 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 - 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/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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - 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: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - 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 - 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: - DISA-STIG-RHEL-08-030040 - 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) - auditd_data_disk_error_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Configure auditd Disk Error Action on Disk Error lineinfile: dest: /etc/audit/auditd.conf line: disk_error_action = {{ var_auditd_disk_error_action.split('|')[0] }} regexp: ^\s*disk_error_action\s*=\s*.*$ state: present create: true when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030040 - 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) - auditd_data_disk_error_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - DISA-STIG-RHEL-08-030060 - 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) - auditd_data_disk_full_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Configure auditd Disk Full Action when Disk Space Is Full lineinfile: dest: /etc/audit/auditd.conf line: disk_full_action = {{ var_auditd_disk_full_action.split('|')[0] }} regexp: ^\s*disk_full_action\s*=\s*.*$ state: present create: true when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - DISA-STIG-RHEL-08-030060 - 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) - auditd_data_disk_full_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - name: Gather the package facts package_facts: manager: auto tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030020 - 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 - auditd_data_retention_action_mail_acct - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030020 - 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 - 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: - 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 - PCI-DSSv4-10.5.1 - auditd_data_retention_admin_space_left_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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 .split('|')[0] }} regexp: ^\s*admin_space_left_action\s*=\s*.*$ state: present create: true when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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: - CJIS-5.4.1.1 - NIST-800-53-AU-11 - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.7 - auditd_data_retention_max_log_file - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - NIST-800-53-AU-11 - NIST-800-53-CM-6(a) - PCI-DSS-Req-10.7 - 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: - 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 - auditd_data_retention_max_log_file_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - 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 - 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: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030731 - 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 - PCI-DSSv4-10.5.1 - auditd_data_retention_space_left_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy - 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.split('|')[0] }} regexp: ^\s*space_left_action\s*=\s*.*$ state: present create: true when: - '"audit" in ansible_facts.packages' - '"kernel" in ansible_facts.packages' tags: - CJIS-5.4.1.1 - DISA-STIG-RHEL-08-030731 - 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 - PCI-DSSv4-10.5.1 - auditd_data_retention_space_left_action - low_complexity - low_disruption - medium_severity - no_reboot_needed - restrict_strategy