diff --git a/tasks/main.yml b/tasks/main.yml index e254973..41c1fd8 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -23,8 +23,8 @@ - no_reboot_needed - package_aide_installed -- name: Ensure AIDE is installed - package: +- name: Build and Test AIDE Database - Ensure AIDE Is Installed + ansible.builtin.package: name: '{{ item }}' state: present with_items: @@ -50,8 +50,8 @@ - no_reboot_needed - restrict_strategy -- name: Build and Test AIDE Database - command: /usr/sbin/aide --init +- name: Build and Test AIDE Database - Build and Test AIDE Database + ansible.builtin.command: /usr/sbin/aide --init changed_when: true when: - aide_build_database | bool @@ -74,8 +74,8 @@ - no_reboot_needed - restrict_strategy -- name: Check whether the stock AIDE Database exists - stat: +- 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: @@ -99,8 +99,8 @@ - no_reboot_needed - restrict_strategy -- name: Stage AIDE Database - copy: +- 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 @@ -1127,7 +1127,7 @@ - name: Limit Password Reuse - Check if expected PAM module line is present in {{ pam_file_path }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' - regexp: ^\s*password\s+requisite\s+pam_pwhistory.so\s*.* + regexp: ^\s*password\s+{{ 'requisite' | regex_escape() }}\s+pam_pwhistory.so\s*.* state: absent check_mode: true changed_when: false @@ -1500,7 +1500,7 @@ - name: Limit Password Reuse - Check if expected PAM module line is present in {{ pam_file_path }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' - regexp: ^\s*password\s+requisite\s+pam_pwhistory.so\s*.* + regexp: ^\s*password\s+{{ 'requisite' | regex_escape() }}\s+pam_pwhistory.so\s*.* state: absent check_mode: true changed_when: false @@ -1544,7 +1544,7 @@ - name: Limit Password Reuse - Check if the required PAM module option is present in {{ pam_file_path }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' - regexp: ^\s*password\s+requisite\s+pam_pwhistory.so\s*.*\sremember\b + regexp: ^\s*password\s+{{ 'requisite' | regex_escape() }}\s+pam_pwhistory.so\s*.*\sremember\b state: absent check_mode: true changed_when: false @@ -1553,7 +1553,7 @@ ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true - regexp: ^(\s*password\s+requisite\s+pam_pwhistory.so.*) + regexp: ^(\s*password\s+{{ 'requisite' | regex_escape() }}\s+pam_pwhistory.so.*) line: \1 remember={{ var_password_pam_unix_remember }} state: present register: result_pam_remember_add @@ -1564,7 +1564,7 @@ ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true - regexp: ^(\s*password\s+requisite\s+pam_pwhistory.so\s+.*)(remember)=[0-9a-zA-Z]+\s*(.*) + regexp: ^(\s*password\s+{{ 'requisite' | regex_escape() }}\s+pam_pwhistory.so\s+.*)(remember)=[0-9a-zA-Z]+\s*(.*) line: \1\2={{ var_password_pam_unix_remember }} \3 register: result_pam_remember_edit when: @@ -4456,7 +4456,7 @@ - name: Set PAM's Password Hashing Algorithm - Check if expected PAM module line is present in {{ pam_file_path }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' - regexp: ^\s*password\s+sufficient\s+pam_unix.so\s*.* + regexp: ^\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so\s*.* state: absent check_mode: true changed_when: false @@ -4502,7 +4502,7 @@ - name: Set PAM's Password Hashing Algorithm - Check if the required PAM module option is present in {{ pam_file_path }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' - regexp: ^\s*password\s+sufficient\s+pam_unix.so\s*.*\ssha512\b + regexp: ^\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so\s*.*\ssha512\b state: absent check_mode: true changed_when: false @@ -4512,7 +4512,7 @@ ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true - regexp: ^(\s*password\s+sufficient\s+pam_unix.so.*) + regexp: ^(\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so.*) line: \1 sha512 state: present register: result_pam_sha512_add @@ -4818,7 +4818,7 @@ }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' - regexp: ^\s*password\s+sufficient\s+pam_unix.so\s*.* + regexp: ^\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so\s*.* state: absent check_mode: true changed_when: false @@ -4867,7 +4867,7 @@ pam_file_path }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' - regexp: ^\s*password\s+sufficient\s+pam_unix.so\s*.*\srounds\b + regexp: ^\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so\s*.*\srounds\b state: absent check_mode: true changed_when: false @@ -4877,7 +4877,7 @@ ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true - regexp: ^(\s*password\s+sufficient\s+pam_unix.so.*) + regexp: ^(\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so.*) line: \1 rounds={{ var_password_pam_unix_rounds }} state: present register: result_pam_rounds_add @@ -4888,7 +4888,7 @@ ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true - regexp: ^(\s*password\s+sufficient\s+pam_unix.so\s+.*)(rounds)=[0-9a-zA-Z]+\s*(.*) + regexp: ^(\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so\s+.*)(rounds)=[0-9a-zA-Z]+\s*(.*) line: \1\2={{ var_password_pam_unix_rounds }} \3 register: result_pam_rounds_edit when: @@ -5077,7 +5077,7 @@ }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' - regexp: ^\s*password\s+sufficient\s+pam_unix.so\s*.* + regexp: ^\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so\s*.* state: absent check_mode: true changed_when: false @@ -5126,7 +5126,7 @@ }} ansible.builtin.lineinfile: path: '{{ pam_file_path }}' - regexp: ^\s*password\s+sufficient\s+pam_unix.so\s*.*\srounds\b + regexp: ^\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so\s*.*\srounds\b state: absent check_mode: true changed_when: false @@ -5136,7 +5136,7 @@ ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true - regexp: ^(\s*password\s+sufficient\s+pam_unix.so.*) + regexp: ^(\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so.*) line: \1 rounds={{ var_password_pam_unix_rounds }} state: present register: result_pam_rounds_add @@ -5147,7 +5147,7 @@ ansible.builtin.lineinfile: path: '{{ pam_file_path }}' backrefs: true - regexp: ^(\s*password\s+sufficient\s+pam_unix.so\s+.*)(rounds)=[0-9a-zA-Z]+\s*(.*) + regexp: ^(\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so\s+.*)(rounds)=[0-9a-zA-Z]+\s*(.*) line: \1\2={{ var_password_pam_unix_rounds }} \3 register: result_pam_rounds_edit when: @@ -5261,6 +5261,28 @@ - no_reboot_needed - restrict_strategy +- name: Gather the package facts + package_facts: + manager: auto + tags: + - CCE-83644-5 + - NIST-800-53-AC-6(1) + - NIST-800-53-CM-6(a) + - PCI-DSSv4-8.6.1 + - accounts_umask_etc_bashrc + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - restrict_strategy + when: + - accounts_umask_etc_bashrc | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - restrict_strategy | bool + - name: Check if umask in /etc/bashrc is already set ansible.builtin.lineinfile: path: /etc/bashrc @@ -5269,6 +5291,14 @@ check_mode: true changed_when: false register: umask_replace + when: + - accounts_umask_etc_bashrc | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - restrict_strategy | bool + - '"bash" in ansible_facts.packages' tags: - CCE-83644-5 - NIST-800-53-AC-6(1) @@ -5280,13 +5310,6 @@ - medium_severity - no_reboot_needed - restrict_strategy - when: - - accounts_umask_etc_bashrc | bool - - low_complexity | bool - - low_disruption | bool - - medium_severity | bool - - no_reboot_needed | bool - - restrict_strategy | bool - name: Replace user umask in /etc/bashrc ansible.builtin.replace: @@ -5300,6 +5323,7 @@ - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool + - '"bash" in ansible_facts.packages' - umask_replace.found > 0 tags: - CCE-83644-5 @@ -5325,6 +5349,7 @@ - medium_severity | bool - no_reboot_needed | bool - restrict_strategy | bool + - '"bash" in ansible_facts.packages' - umask_replace.found == 0 tags: - CCE-83644-5 @@ -5548,6 +5573,116 @@ - no_reboot_needed | bool - restrict_strategy | bool +- name: Ensure audit is installed + package: + name: audit + state: present + when: + - enable_strategy | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - package_audit_installed | bool + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + tags: + - CCE-83649-4 + - NIST-800-53-AC-7(a) + - NIST-800-53-AU-12(2) + - NIST-800-53-AU-14 + - NIST-800-53-AU-2(a) + - NIST-800-53-AU-7(1) + - NIST-800-53-AU-7(2) + - NIST-800-53-CM-6(a) + - PCI-DSS-Req-10.1 + - PCI-DSSv4-10.2.1 + - enable_strategy + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - package_audit_installed + +- name: Gather the package facts + package_facts: + manager: auto + tags: + - CCE-90829-3 + - CJIS-5.4.1.1 + - NIST-800-171-3.3.1 + - NIST-800-171-3.3.2 + - NIST-800-171-3.3.6 + - NIST-800-53-AC-2(g) + - NIST-800-53-AC-6(9) + - NIST-800-53-AU-10 + - NIST-800-53-AU-12(c) + - NIST-800-53-AU-14(1) + - NIST-800-53-AU-2(d) + - NIST-800-53-AU-3 + - NIST-800-53-CM-6(a) + - NIST-800-53-SI-4(23) + - PCI-DSS-Req-10.1 + - PCI-DSSv4-10.2.1 + - enable_strategy + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - service_auditd_enabled + when: + - enable_strategy | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - service_auditd_enabled | bool + +- name: Enable service auditd + block: + - name: Gather the package facts + package_facts: + manager: auto + - name: Enable service auditd + systemd: + name: auditd + enabled: 'yes' + state: started + masked: 'no' + when: + - '"audit" in ansible_facts.packages' + when: + - enable_strategy | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - service_auditd_enabled | bool + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - '"audit" in ansible_facts.packages' + tags: + - CCE-90829-3 + - CJIS-5.4.1.1 + - NIST-800-171-3.3.1 + - NIST-800-171-3.3.2 + - NIST-800-171-3.3.6 + - NIST-800-53-AC-2(g) + - NIST-800-53-AC-6(9) + - NIST-800-53-AU-10 + - NIST-800-53-AU-12(c) + - NIST-800-53-AU-14(1) + - NIST-800-53-AU-2(d) + - NIST-800-53-AU-3 + - NIST-800-53-CM-6(a) + - NIST-800-53-SI-4(23) + - PCI-DSS-Req-10.1 + - PCI-DSSv4-10.2.1 + - enable_strategy + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - service_auditd_enabled + - name: Gather the package facts package_facts: manager: auto @@ -8137,6 +8272,78 @@ - no_reboot_needed | bool - restrict_strategy | bool +- name: Check if watch rule for /etc/sudoers already exists in /etc/audit/audit.rules + find: + paths: /etc/audit/ + contains: ^\s*-w\s+/etc/sudoers\s+-p\s+wa(\s|$)+ + patterns: audit.rules + register: find_existing_watch_audit_rules + when: + - audit_rules_sysadmin_actions | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - restrict_strategy | bool + - '"audit" in ansible_facts.packages' + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + tags: + - CCE-83729-4 + - CJIS-5.4.1.1 + - NIST-800-171-3.1.7 + - NIST-800-53-AC-2(7)(b) + - NIST-800-53-AC-6(9) + - NIST-800-53-AU-12(c) + - NIST-800-53-AU-2(d) + - NIST-800-53-CM-6(a) + - PCI-DSS-Req-10.2.2 + - PCI-DSS-Req-10.2.5.b + - PCI-DSSv4-10.2.1.5 + - PCI-DSSv4-10.2.2 + - audit_rules_sysadmin_actions + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - restrict_strategy + +- name: Add watch rule for /etc/sudoers in /etc/audit/audit.rules + lineinfile: + line: -w /etc/sudoers -p wa -k actions + state: present + dest: /etc/audit/audit.rules + create: true + mode: '0640' + when: + - audit_rules_sysadmin_actions | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - restrict_strategy | bool + - '"audit" in ansible_facts.packages' + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 + tags: + - CCE-83729-4 + - CJIS-5.4.1.1 + - NIST-800-171-3.1.7 + - NIST-800-53-AC-2(7)(b) + - NIST-800-53-AC-6(9) + - NIST-800-53-AU-12(c) + - NIST-800-53-AU-2(d) + - NIST-800-53-CM-6(a) + - PCI-DSS-Req-10.2.2 + - PCI-DSS-Req-10.2.5.b + - PCI-DSSv4-10.2.1.5 + - PCI-DSSv4-10.2.2 + - audit_rules_sysadmin_actions + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - restrict_strategy + - name: Check if watch rule for /etc/sudoers already exists in /etc/audit/rules.d/ find: paths: /etc/audit/rules.d @@ -8314,10 +8521,10 @@ - no_reboot_needed - restrict_strategy -- name: Check if watch rule for /etc/sudoers already exists in /etc/audit/audit.rules +- 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\s+-p\s+wa(\s|$)+ + contains: ^\s*-w\s+/etc/sudoers.d/\s+-p\s+wa(\s|$)+ patterns: audit.rules register: find_existing_watch_audit_rules when: @@ -8349,9 +8556,9 @@ - no_reboot_needed - restrict_strategy -- name: Add watch rule for /etc/sudoers in /etc/audit/audit.rules +- name: Add watch rule for /etc/sudoers.d/ in /etc/audit/audit.rules lineinfile: - line: -w /etc/sudoers -p wa -k actions + line: -w /etc/sudoers.d/ -p wa -k actions state: present dest: /etc/audit/audit.rules create: true @@ -8563,133 +8770,61 @@ - no_reboot_needed - restrict_strategy -- name: Check if watch rule for /etc/sudoers.d/ already exists in /etc/audit/audit.rules - find: - paths: /etc/audit/ - contains: ^\s*-w\s+/etc/sudoers.d/\s+-p\s+wa(\s|$)+ - patterns: audit.rules - register: find_existing_watch_audit_rules - when: - - audit_rules_sysadmin_actions | bool - - low_complexity | bool - - low_disruption | bool - - medium_severity | bool - - no_reboot_needed | bool - - restrict_strategy | bool - - '"audit" in ansible_facts.packages' - - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] +- name: Gather the package facts + package_facts: + manager: auto tags: - - CCE-83729-4 + - CCE-83722-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - - NIST-800-53-AC-2(7)(b) + - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - - PCI-DSS-Req-10.2.2 - - PCI-DSS-Req-10.2.5.b + - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - - PCI-DSSv4-10.2.2 - - audit_rules_sysadmin_actions + - audit_rules_usergroup_modification_group - low_complexity - low_disruption - medium_severity - - no_reboot_needed + - reboot_required - restrict_strategy + when: + - audit_rules_usergroup_modification_group | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - reboot_required | bool + - restrict_strategy | bool -- name: 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' +- name: Check if watch rule for /etc/group already exists in /etc/audit/rules.d/ + find: + paths: /etc/audit/rules.d + contains: ^\s*-w\s+/etc/group\s+-p\s+wa(\s|$)+ + patterns: '*.rules' + register: find_existing_watch_rules_d when: - - audit_rules_sysadmin_actions | bool + - audit_rules_usergroup_modification_group | bool - low_complexity | bool - low_disruption | bool - medium_severity | bool - - no_reboot_needed | bool + - reboot_required | bool - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 tags: - - CCE-83729-4 + - CCE-83722-9 - CJIS-5.4.1.1 - NIST-800-171-3.1.7 - - NIST-800-53-AC-2(7)(b) + - NIST-800-53-AC-2(4) - NIST-800-53-AC-6(9) - NIST-800-53-AU-12(c) - NIST-800-53-AU-2(d) - NIST-800-53-CM-6(a) - - PCI-DSS-Req-10.2.2 - - PCI-DSS-Req-10.2.5.b + - PCI-DSS-Req-10.2.5 - PCI-DSSv4-10.2.1.5 - - PCI-DSSv4-10.2.2 - - audit_rules_sysadmin_actions - - low_complexity - - low_disruption - - medium_severity - - no_reboot_needed - - restrict_strategy - -- name: Gather the package facts - package_facts: - manager: auto - tags: - - CCE-83722-9 - - CJIS-5.4.1.1 - - NIST-800-171-3.1.7 - - NIST-800-53-AC-2(4) - - NIST-800-53-AC-6(9) - - NIST-800-53-AU-12(c) - - NIST-800-53-AU-2(d) - - NIST-800-53-CM-6(a) - - PCI-DSS-Req-10.2.5 - - PCI-DSSv4-10.2.1.5 - - audit_rules_usergroup_modification_group - - low_complexity - - low_disruption - - medium_severity - - reboot_required - - restrict_strategy - when: - - audit_rules_usergroup_modification_group | bool - - low_complexity | bool - - low_disruption | bool - - medium_severity | bool - - reboot_required | bool - - restrict_strategy | bool - -- name: Check if watch rule for /etc/group already exists in /etc/audit/rules.d/ - find: - paths: /etc/audit/rules.d - contains: ^\s*-w\s+/etc/group\s+-p\s+wa(\s|$)+ - patterns: '*.rules' - register: find_existing_watch_rules_d - when: - - audit_rules_usergroup_modification_group | bool - - low_complexity | bool - - low_disruption | bool - - medium_severity | bool - - reboot_required | bool - - restrict_strategy | bool - - '"audit" in ansible_facts.packages' - - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - tags: - - CCE-83722-9 - - CJIS-5.4.1.1 - - NIST-800-171-3.1.7 - - NIST-800-53-AC-2(4) - - NIST-800-53-AC-6(9) - - NIST-800-53-AU-12(c) - - NIST-800-53-AU-2(d) - - NIST-800-53-CM-6(a) - - PCI-DSS-Req-10.2.5 - - PCI-DSSv4-10.2.1.5 - - audit_rules_usergroup_modification_group + - audit_rules_usergroup_modification_group - low_complexity - low_disruption - medium_severity @@ -9950,6 +10085,229 @@ - reboot_required - restrict_strategy +- name: Gather the package facts + package_facts: + manager: auto + tags: + - CCE-86433-0 + - PCI-DSS-Req-10.2.2 + - PCI-DSS-Req-10.2.5.b + - PCI-DSSv4-10.2.1.5 + - PCI-DSSv4-10.2.2 + - audit_sudo_log_events + - low_complexity + - low_disruption + - medium_severity + - reboot_required + - restrict_strategy + when: + - audit_sudo_log_events | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - reboot_required | bool + - restrict_strategy | bool + +- name: Check if watch rule for /var/log/sudo.log already exists in /etc/audit/rules.d/ + find: + paths: /etc/audit/rules.d + contains: ^\s*-w\s+/var/log/sudo.log\s+-p\s+wa(\s|$)+ + patterns: '*.rules' + register: find_existing_watch_rules_d + when: + - audit_sudo_log_events | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - reboot_required | bool + - restrict_strategy | bool + - '"audit" in ansible_facts.packages' + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + tags: + - CCE-86433-0 + - PCI-DSS-Req-10.2.2 + - PCI-DSS-Req-10.2.5.b + - PCI-DSSv4-10.2.1.5 + - PCI-DSSv4-10.2.2 + - audit_sudo_log_events + - low_complexity + - low_disruption + - medium_severity + - reboot_required + - restrict_strategy + +- name: Search /etc/audit/rules.d for other rules with specified key logins + find: + paths: /etc/audit/rules.d + contains: ^.*(?:-F key=|-k\s+)logins$ + patterns: '*.rules' + register: find_watch_key + when: + - audit_sudo_log_events | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - reboot_required | bool + - restrict_strategy | bool + - '"audit" in ansible_facts.packages' + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 + tags: + - CCE-86433-0 + - PCI-DSS-Req-10.2.2 + - PCI-DSS-Req-10.2.5.b + - PCI-DSSv4-10.2.1.5 + - PCI-DSSv4-10.2.2 + - audit_sudo_log_events + - low_complexity + - low_disruption + - medium_severity + - reboot_required + - restrict_strategy + +- name: Use /etc/audit/rules.d/logins.rules as the recipient for the rule + set_fact: + all_files: + - /etc/audit/rules.d/logins.rules + when: + - audit_sudo_log_events | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - reboot_required | bool + - restrict_strategy | bool + - '"audit" in ansible_facts.packages' + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched is defined and + find_existing_watch_rules_d.matched == 0 + tags: + - CCE-86433-0 + - PCI-DSS-Req-10.2.2 + - PCI-DSS-Req-10.2.5.b + - PCI-DSSv4-10.2.1.5 + - PCI-DSSv4-10.2.2 + - audit_sudo_log_events + - low_complexity + - low_disruption + - medium_severity + - reboot_required + - restrict_strategy + +- name: Use matched file as the recipient for the rule + set_fact: + all_files: + - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}' + when: + - audit_sudo_log_events | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - reboot_required | bool + - restrict_strategy | bool + - '"audit" in ansible_facts.packages' + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched is defined and + find_existing_watch_rules_d.matched == 0 + tags: + - CCE-86433-0 + - PCI-DSS-Req-10.2.2 + - PCI-DSS-Req-10.2.5.b + - PCI-DSSv4-10.2.1.5 + - PCI-DSSv4-10.2.2 + - audit_sudo_log_events + - low_complexity + - low_disruption + - medium_severity + - reboot_required + - restrict_strategy + +- name: Add watch rule for /var/log/sudo.log in /etc/audit/rules.d/ + lineinfile: + path: '{{ all_files[0] }}' + line: -w /var/log/sudo.log -p wa -k logins + create: true + mode: '0640' + when: + - audit_sudo_log_events | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - reboot_required | bool + - restrict_strategy | bool + - '"audit" in ansible_facts.packages' + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched == 0 + tags: + - CCE-86433-0 + - PCI-DSS-Req-10.2.2 + - PCI-DSS-Req-10.2.5.b + - PCI-DSSv4-10.2.1.5 + - PCI-DSSv4-10.2.2 + - audit_sudo_log_events + - low_complexity + - low_disruption + - medium_severity + - reboot_required + - restrict_strategy + +- name: Check if watch rule for /var/log/sudo.log already exists in /etc/audit/audit.rules + find: + paths: /etc/audit/ + contains: ^\s*-w\s+/var/log/sudo.log\s+-p\s+wa(\s|$)+ + patterns: audit.rules + register: find_existing_watch_audit_rules + when: + - audit_sudo_log_events | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - reboot_required | bool + - restrict_strategy | bool + - '"audit" in ansible_facts.packages' + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + tags: + - CCE-86433-0 + - PCI-DSS-Req-10.2.2 + - PCI-DSS-Req-10.2.5.b + - PCI-DSSv4-10.2.1.5 + - PCI-DSSv4-10.2.2 + - audit_sudo_log_events + - low_complexity + - low_disruption + - medium_severity + - reboot_required + - restrict_strategy + +- name: Add watch rule for /var/log/sudo.log in /etc/audit/audit.rules + lineinfile: + line: -w /var/log/sudo.log -p wa -k logins + state: present + dest: /etc/audit/audit.rules + create: true + mode: '0640' + when: + - audit_sudo_log_events | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - reboot_required | bool + - restrict_strategy | bool + - '"audit" in ansible_facts.packages' + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched == 0 + tags: + - CCE-86433-0 + - PCI-DSS-Req-10.2.2 + - PCI-DSS-Req-10.2.5.b + - PCI-DSSv4-10.2.1.5 + - PCI-DSSv4-10.2.2 + - audit_sudo_log_events + - low_complexity + - low_disruption + - medium_severity + - reboot_required + - restrict_strategy + - name: Gather the package facts package_facts: manager: auto @@ -9988,6 +10346,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - 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: @@ -10110,6 +10469,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) tags: - CCE-83830-0 - CJIS-5.4.1.1 @@ -10230,6 +10590,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CCE-83830-0 @@ -10285,6 +10646,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - 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: @@ -10409,6 +10771,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) tags: - CCE-83812-8 - CJIS-5.4.1.1 @@ -10531,6 +10894,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CCE-83812-8 @@ -12796,6 +13160,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - 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: @@ -12920,6 +13285,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) tags: - CCE-83833-4 - CJIS-5.4.1.1 @@ -13042,6 +13408,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CCE-83833-4 @@ -15381,6 +15748,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - 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: @@ -15506,6 +15874,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) tags: - CCE-83754-2 - NIST-800-171-3.1.7 @@ -15629,6 +15998,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CCE-83754-2 @@ -15983,6 +16353,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - 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: @@ -16108,6 +16479,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) tags: - CCE-83758-3 - NIST-800-171-3.1.7 @@ -16231,6 +16603,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CCE-83758-3 @@ -16284,6 +16657,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - 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: @@ -16409,6 +16783,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) tags: - CCE-83757-5 - NIST-800-171-3.1.7 @@ -16532,6 +16907,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CCE-83757-5 @@ -16888,6 +17264,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - 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: @@ -17019,6 +17396,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) tags: - CCE-83786-4 - NIST-800-171-3.1.7 @@ -17148,6 +17526,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CCE-83786-4 @@ -17278,6 +17657,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) tags: - CCE-83786-4 - NIST-800-171-3.1.7 @@ -17407,6 +17787,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CCE-83786-4 @@ -18040,6 +18421,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - 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: @@ -18171,6 +18553,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) tags: - CCE-83801-1 - NIST-800-171-3.1.7 @@ -18300,6 +18683,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CCE-83801-1 @@ -18430,6 +18814,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) tags: - CCE-83801-1 - NIST-800-171-3.1.7 @@ -18559,6 +18944,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - not ( ansible_architecture == "aarch64" ) - audit_arch == "b64" tags: - CCE-83801-1 @@ -20626,10 +21012,10 @@ - reboot_required | bool - restrict_strategy | bool -- name: Check if watch rule for /var/log/faillock already exists in /etc/audit/rules.d/ +- 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/log/faillock\s+-p\s+wa(\s|$)+ + contains: ^\s*-w\s+{{ var_accounts_passwords_pam_faillock_dir }}\s+-p\s+wa(\s|$)+ patterns: '*.rules' register: find_existing_watch_rules_d when: @@ -20751,10 +21137,10 @@ - reboot_required - restrict_strategy -- name: Add watch rule for /var/log/faillock in /etc/audit/rules.d/ +- name: Add watch rule for {{ var_accounts_passwords_pam_faillock_dir }} in /etc/audit/rules.d/ lineinfile: path: '{{ all_files[0] }}' - line: -w /var/log/faillock -p wa -k logins + line: -w {{ var_accounts_passwords_pam_faillock_dir }} -p wa -k logins create: true mode: '0640' when: @@ -20783,10 +21169,10 @@ - reboot_required - restrict_strategy -- name: Check if watch rule for /var/log/faillock already exists in /etc/audit/audit.rules +- 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/log/faillock\s+-p\s+wa(\s|$)+ + 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: @@ -20814,9 +21200,9 @@ - reboot_required - restrict_strategy -- name: Add watch rule for /var/log/faillock in /etc/audit/audit.rules +- name: Add watch rule for {{ var_accounts_passwords_pam_faillock_dir }} in /etc/audit/audit.rules lineinfile: - line: -w /var/log/faillock -p wa -k logins + line: -w {{ var_accounts_passwords_pam_faillock_dir }} -p wa -k logins state: present dest: /etc/audit/audit.rules create: true @@ -22283,6 +22669,7 @@ - restrict_strategy | bool - '"audit" in ansible_facts.packages' - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - ( not ( ansible_architecture == "aarch64" ) and not ( ansible_architecture == "s390x" ) ) tags: - CCE-83835-9 - CJIS-5.4.1.1 @@ -23891,11 +24278,56 @@ - no_reboot_needed - rsyslog_files_permissions -- name: Configure daily log rotation in /etc/logrotate.conf - lineinfile: - create: true - dest: /etc/logrotate.conf - regexp: ^daily$ +- name: Ensure logrotate is installed + package: + name: logrotate + state: present + when: + - enable_strategy | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - package_logrotate_installed | bool + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + tags: + - CCE-86155-9 + - NIST-800-53-CM-6(a) + - PCI-DSS-Req-10.7 + - enable_strategy + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - package_logrotate_installed + +- name: Gather the package facts + package_facts: + manager: auto + tags: + - CCE-83993-6 + - NIST-800-53-CM-6(a) + - PCI-DSS-Req-10.7 + - PCI-DSSv4-10.5.1 + - configure_strategy + - ensure_logrotate_activated + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + when: + - configure_strategy | bool + - ensure_logrotate_activated | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + +- name: Configure daily log rotation in /etc/logrotate.conf + lineinfile: + create: true + dest: /etc/logrotate.conf + regexp: ^daily$ line: daily when: - configure_strategy | bool @@ -23905,6 +24337,7 @@ - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - '"logrotate" in ansible_facts.packages' tags: - CCE-83993-6 - NIST-800-53-CM-6(a) @@ -23931,6 +24364,7 @@ - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - '"logrotate" in ansible_facts.packages' tags: - CCE-83993-6 - NIST-800-53-CM-6(a) @@ -23964,6 +24398,7 @@ - medium_severity | bool - no_reboot_needed | bool - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - '"logrotate" in ansible_facts.packages' tags: - CCE-83993-6 - NIST-800-53-CM-6(a) @@ -23976,6 +24411,60 @@ - medium_severity - no_reboot_needed +- name: Gather the package facts + package_facts: + manager: auto + tags: + - CCE-86158-3 + - NIST-800-53-CM-6(a) + - PCI-DSS-Req-10.7 + - enable_strategy + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - timer_logrotate_enabled + when: + - enable_strategy | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - timer_logrotate_enabled | bool + +- name: Enable timer logrotate + block: + - name: Gather the package facts + package_facts: + manager: auto + - name: Enable timer logrotate + systemd: + name: logrotate.timer + enabled: 'yes' + state: started + when: + - '"logrotate" in ansible_facts.packages' + when: + - enable_strategy | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - timer_logrotate_enabled | bool + - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - ( ansible_distribution == 'RedHat' and ansible_distribution_version is version('9', '>=') and "logrotate" in ansible_facts.packages + ) + tags: + - CCE-86158-3 + - NIST-800-53-CM-6(a) + - PCI-DSS-Req-10.7 + - enable_strategy + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - timer_logrotate_enabled + - name: Set rsyslog remote loghost lineinfile: dest: /etc/rsyslog.conf @@ -27598,14 +28087,84 @@ - no_reboot_needed | bool - restrict_strategy | bool -- name: Get all world-writable directories with no sticky bits set - shell: 'set -o pipefail +- 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: + - CCE-83895-3 + - NIST-800-53-AC-6(1) + - NIST-800-53-CM-6(a) + - dir_perms_world_writable_sticky_bits + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - restrict_strategy + when: + - dir_perms_world_writable_sticky_bits | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - restrict_strategy | bool - df --local -P | awk ''{if (NR!=1) print $6}'' | xargs -I ''{}'' find ''{}'' -xdev -type d \( -perm -0002 -a ! -perm -1000 - \) 2>/dev/null +- 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: + - CCE-83895-3 + - NIST-800-53-AC-6(1) + - NIST-800-53-CM-6(a) + - dir_perms_world_writable_sticky_bits + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - restrict_strategy + when: + - dir_perms_world_writable_sticky_bits | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - restrict_strategy | bool - ' - register: dir_output +- 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: - CCE-83895-3 - NIST-800-53-AC-6(1) @@ -27624,12 +28183,129 @@ - no_reboot_needed | bool - restrict_strategy | bool -- name: Ensure sticky bit is set - file: +- 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: + - dir_perms_world_writable_sticky_bits | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - restrict_strategy | bool + - item.fstype not in excluded_fstypes + - item.mount != '/' + tags: + - CCE-83895-3 + - NIST-800-53-AC-6(1) + - NIST-800-53-CM-6(a) + - dir_perms_world_writable_sticky_bits + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - restrict_strategy + +- 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: + - dir_perms_world_writable_sticky_bits | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - restrict_strategy | bool + - item.device is search("localhost:") + tags: + - CCE-83895-3 + - NIST-800-53-AC-6(1) + - NIST-800-53-CM-6(a) + - dir_perms_world_writable_sticky_bits + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - restrict_strategy + +- name: Verify that All World-Writable Directories Have Sticky Bits Set - Define Rule Specific Facts + ansible.builtin.set_fact: + world_writable_dirs: [] + tags: + - CCE-83895-3 + - NIST-800-53-AC-6(1) + - NIST-800-53-CM-6(a) + - dir_perms_world_writable_sticky_bits + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - restrict_strategy + when: + - dir_perms_world_writable_sticky_bits | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - restrict_strategy | bool + +- name: 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: + - CCE-83895-3 + - NIST-800-53-AC-6(1) + - NIST-800-53-CM-6(a) + - dir_perms_world_writable_sticky_bits + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - restrict_strategy + when: + - dir_perms_world_writable_sticky_bits | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - restrict_strategy | bool + +- name: 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 }}' + tags: + - CCE-83895-3 + - NIST-800-53-AC-6(1) + - NIST-800-53-CM-6(a) + - dir_perms_world_writable_sticky_bits + - low_complexity + - low_disruption + - medium_severity + - no_reboot_needed + - restrict_strategy + when: + - dir_perms_world_writable_sticky_bits | bool + - low_complexity | bool + - low_disruption | bool + - medium_severity | bool + - no_reboot_needed | bool + - restrict_strategy | bool + +- name: 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 - with_items: - - '{{ dir_output.stdout_lines }}' + loop: '{{ world_writable_dirs }}' tags: - CCE-83895-3 - NIST-800-53-AC-6(1) @@ -29894,18 +30570,19 @@ - configure_strategy | bool - high_disruption | bool - low_complexity | bool + - medium_severity | bool - mount_option_var_nosuid | bool - no_reboot_needed | bool - - unknown_severity | bool - - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var" in ansible_mounts | + map(attribute="mount") | list ) tags: - CCE-83867-2 - configure_strategy - high_disruption - low_complexity + - medium_severity - mount_option_var_nosuid - no_reboot_needed - - unknown_severity - name: 'Add nosuid Option to /var: Create mount_info dictionary variable' set_fact: @@ -29917,10 +30594,11 @@ - configure_strategy | bool - high_disruption | bool - low_complexity | bool + - medium_severity | bool - mount_option_var_nosuid | bool - no_reboot_needed | bool - - unknown_severity | bool - - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var" in ansible_mounts | + map(attribute="mount") | list ) - device_name.stdout is defined and device_name.stdout_lines is defined - (device_name.stdout | length > 0) tags: @@ -29928,9 +30606,9 @@ - configure_strategy - high_disruption - low_complexity + - medium_severity - mount_option_var_nosuid - no_reboot_needed - - unknown_severity - name: 'Add nosuid Option to /var: If /var not mounted, craft mount_info manually' set_fact: @@ -29948,10 +30626,11 @@ - configure_strategy | bool - high_disruption | bool - low_complexity | bool + - medium_severity | bool - mount_option_var_nosuid | bool - no_reboot_needed | bool - - unknown_severity | bool - - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var" in ansible_mounts | + map(attribute="mount") | list ) - ("--fstab" | length == 0) - (device_name.stdout | length == 0) tags: @@ -29959,9 +30638,9 @@ - configure_strategy - high_disruption - low_complexity + - medium_severity - mount_option_var_nosuid - no_reboot_needed - - unknown_severity - name: 'Add nosuid Option to /var: Make sure nosuid option is part of the to /var options' set_fact: @@ -29970,19 +30649,20 @@ - configure_strategy | bool - high_disruption | bool - low_complexity | bool + - medium_severity | bool - mount_option_var_nosuid | bool - no_reboot_needed | bool - - unknown_severity | bool - - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var" in ansible_mounts | + map(attribute="mount") | list ) - mount_info is defined and "nosuid" not in mount_info.options tags: - CCE-83867-2 - configure_strategy - high_disruption - low_complexity + - medium_severity - mount_option_var_nosuid - no_reboot_needed - - unknown_severity - name: 'Add nosuid Option to /var: Ensure /var is mounted with nosuid option' mount: @@ -29995,19 +30675,20 @@ - configure_strategy | bool - high_disruption | bool - low_complexity | bool + - medium_severity | bool - mount_option_var_nosuid | bool - no_reboot_needed | bool - - unknown_severity | bool - - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] + - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] and "/var" in ansible_mounts | + map(attribute="mount") | list ) - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab" | length == 0) tags: - CCE-83867-2 - configure_strategy - high_disruption - low_complexity + - medium_severity - mount_option_var_nosuid - no_reboot_needed - - unknown_severity - name: 'Add noexec Option to /var/tmp: Check information associated to mountpoint' command: findmnt --fstab '/var/tmp' @@ -31536,7 +32217,7 @@ - name: Check for duplicate values lineinfile: path: /etc/selinux/config - create: false + create: true regexp: ^SELINUXTYPE= state: absent check_mode: true @@ -31545,7 +32226,7 @@ - name: Deduplicate values from /etc/selinux/config lineinfile: path: /etc/selinux/config - create: false + create: true regexp: ^SELINUXTYPE= state: absent when: dupes.found is defined and dupes.found > 1 @@ -31584,7 +32265,7 @@ - name: Check for duplicate values lineinfile: path: /etc/selinux/config - create: false + create: true regexp: ^SELINUX= state: absent check_mode: true @@ -31593,7 +32274,7 @@ - name: Deduplicate values from /etc/selinux/config lineinfile: path: /etc/selinux/config - create: false + create: true regexp: ^SELINUX= state: absent when: dupes.found is defined and dupes.found > 1 @@ -31638,8 +32319,8 @@ - medium_severity | bool - no_reboot_needed | bool - sebool_polyinstantiation_enabled | bool + - ( not ( lookup("env", "container") == "bwrap-osbuild" ) ) - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - - not ( lookup("env", "container") == "bwrap-osbuild" ) tags: - CCE-84083-5 - enable_strategy @@ -31661,8 +32342,8 @@ - medium_severity | bool - no_reboot_needed | bool - sebool_polyinstantiation_enabled | bool + - ( not ( lookup("env", "container") == "bwrap-osbuild" ) ) - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"] - - not ( lookup("env", "container") == "bwrap-osbuild" ) tags: - CCE-84083-5 - enable_strategy @@ -32325,7 +33006,7 @@ - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config - create: false + create: true regexp: (?i)^\s*ClientAliveCountMax\s+ state: absent check_mode: true @@ -32334,7 +33015,7 @@ - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config - create: false + create: true regexp: (?i)^\s*ClientAliveCountMax\s+ state: absent when: dupes.found is defined and dupes.found > 1 @@ -32345,7 +33026,7 @@ regexp: (?i)^\s*ClientAliveCountMax\s+ line: ClientAliveCountMax {{ var_sshd_set_keepalive }} state: present - insertbefore: ^[#\s]*Match + insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool @@ -32378,7 +33059,7 @@ - name: Check for duplicate values lineinfile: path: /etc/ssh/sshd_config - create: false + create: true regexp: (?i)^\s*ClientAliveInterval\s+ state: absent check_mode: true @@ -32387,7 +33068,7 @@ - name: Deduplicate values from /etc/ssh/sshd_config lineinfile: path: /etc/ssh/sshd_config - create: false + create: true regexp: (?i)^\s*ClientAliveInterval\s+ state: absent when: dupes.found is defined and dupes.found > 1 @@ -32398,7 +33079,7 @@ regexp: (?i)^\s*ClientAliveInterval\s+ line: ClientAliveInterval {{ sshd_idle_timeout_value }} state: present - insertbefore: ^[#\s]*Match + insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool @@ -32464,7 +33145,7 @@ regexp: (?i)^\s*{{ "PermitRootLogin"| regex_escape }}\s+ line: PermitRootLogin no state: present - insertbefore: ^[#\s]*Match + insertbefore: BOF validate: /usr/sbin/sshd -t -f %s when: - low_complexity | bool