--- - name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadowed passwords" block: - name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadowed passwords | discover" ansible.builtin.shell: awk -F':' '($2 != "x" ) { print $1 " is not set to shadowed passwords "}' /etc/passwd changed_when: false register: shadow_passwd - name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadowed passwords | Output" ansible.builtin.debug: msg: | - "Warning!! Below are the accounts that do not have shadowed passwords set" - "{{ shadow_passwd.stdout_line }}" when: shadow_passwd.stdout | length > 0 - name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadowed passwords | warning fact" ansible.builtin.import_tasks: warning_facts.yml vars: warn_control_id: '6.2.1' when: shadow_passwd.stdout | length >= 1 when: - rhel9cis_rule_6_2_1 tags: - level1-server - level1-workstation - patch - accounts - rule_6.2.1 - name: "6.2.2 | PATCH | Ensure password fields are not empty" ansible.builtin.shell: passwd -l {{ item }} changed_when: false failed_when: false loop: "{{ empty_password_accounts.stdout_lines }}" when: - empty_password_accounts.rc - rhel9cis_rule_6_2_2 tags: - level1-server - level1-workstation - patch - accounts - rule_6.2.2 - name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group" block: - name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Check /etc/passwd entries" ansible.builtin.shell: pwck -r | grep 'no group' | awk '{ gsub("[:\47]",""); print $2}' changed_when: false failed_when: false check_mode: false register: rhel9cis_6_2_3_passwd_gid_check - name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Print warning about users with invalid GIDs missing GID entries in /etc/group" ansible.builtin.debug: msg: "Warning!! The following users have non-existent GIDs (Groups): {{ rhel9cis_6_2_3_passwd_gid_check.stdout_lines | join (', ') }}" when: rhel9cis_6_2_3_passwd_gid_check.stdout | length >= 1 - name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | warning count" ansible.builtin.import_tasks: warning_facts.yml vars: warn_control_id: '6.2.3' when: rhel9cis_6_2_3_passwd_gid_check.stdout | length >= 1 when: - rhel9cis_rule_6_2_3 tags: - level1-server - level1-workstation - audit - accounts - groups - rule_6.2.2 - name: "6.2.4 | AUDIT Ensure no duplicate UIDs exist" block: - name: "6.2.4 | AUDIT | Ensure no duplicate UIDs exist | Check for duplicate UIDs" ansible.builtin.shell: "pwck -r | awk -F: '{if ($3 in uid) print $1 ; else uid[$3]}' /etc/passwd" changed_when: false failed_when: false register: rhel9cis_6_2_4_user_uid_check - name: "6.2.4 | AUDIT | Ensure no duplicate UIDs exist | Print warning about users with duplicate UIDs" ansible.builtin.debug: msg: "Warning!! The following users have UIDs that are duplicates: {{ rhel9cis_6_2_4_user_uid_check.stdout_lines }}" when: rhel9cis_6_2_4_user_uid_check.stdout | length >= 1 - name: "6.2.4 | AUDIT| Ensure no duplicate UIDs exist | warning count" ansible.builtin.import_tasks: warning_facts.yml when: rhel9cis_6_2_4_user_uid_check.stdout | length >= 1 vars: warn_control_id: '6.2.4' when: - rhel9cis_rule_6_2_4 tags: - level1-server - level1-workstation - audit - accounts - users - rule_6.2.4 - name: "6.2.5 | AUDIT | Ensure no duplicate GIDs exist" block: - name: "6.2.5 | AUDIT | Ensure no duplicate GIDs exist | Check for duplicate GIDs" ansible.builtin.shell: "pwck -r | awk -F: '{if ($3 in users) print $1 ; else users[$3]}' /etc/group" changed_when: false failed_when: false register: rhel9cis_6_2_5_user_user_check - name: "6.2.5 | AUDIT | Ensure no duplicate GIDs exist | Print warning about users with duplicate GIDs" ansible.builtin.debug: msg: "Warning!! The following groups have duplicate GIDs: {{ rhel9cis_6_2_5_user_user_check.stdout_lines }}" when: rhel9cis_6_2_5_user_user_check.stdout | length >= 1 - name: "6.2.5 | AUDIT | Ensure no duplicate GIDs exist | warning count" ansible.builtin.import_tasks: warning_facts.yml vars: warn_control_id: '6.2.5' when: rhel9cis_6_2_5_user_user_check.stdout_lines | length >= 1 when: - rhel9cis_rule_6_2_5 tags: - level1-server - level1-workstation - audit - accounts - groups - rule_6.2.5 - name: "6.2.6 | AUDIT | Ensure no duplicate user names exist" block: - name: "6.2.6 | AUDIT | Ensure no duplicate user names exist | Check for duplicate User Names" ansible.builtin.shell: "pwck -r | awk -F: '{if ($1 in users) print $1 ; else users[$1]}' /etc/passwd" changed_when: false failed_when: false register: rhel9cis_6_2_6_user_username_check - name: "6.2.6 | AUDIT | Ensure no duplicate user names exist | Print warning about users with duplicate User Names" ansible.builtin.debug: msg: "Warning!! The following user names are duplicates: {{ rhel9cis_6_2_6_user_username_check.stdout_lines }}" when: rhel9cis_6_2_6_user_username_check.stdout | length >= 1 - name: "6.2.6 | AUDIT | Ensure no duplicate user names exist | warning count" ansible.builtin.import_tasks: warning_facts.yml vars: warn_control_id: '6.2.6' when: rhel9cis_6_2_6_user_username_check.stdout | length >= 1 when: - rhel9cis_rule_6_2_6 tags: - level1-server - level1-workstation - audit - accounts - users - rule_6.2.6 - name: "6.2.7 | AUDIT | Ensure no duplicate group names exist" block: - name: "6.2.7 | AUDIT | Ensure no duplicate group names exist | Check for duplicate group names" ansible.builtin.shell: 'getent passwd | cut -d: -f1 | sort -n | uniq -d' changed_when: false failed_when: false check_mode: false register: rhel9cis_6_2_7_group_group_check - name: "6.2.7 | AUDIT | Ensure no duplicate group names exist | Print warning about users with duplicate group names" ansible.builtin.debug: msg: "Warning!! The following group names are duplicates: {{ rhel9cis_6_2_7_group_group_check.stdout_lines }}" when: rhel9cis_6_2_7_group_group_check.stdout is not defined - name: "6.2.7 | AUDIT | Ensure no duplicate group names exist | warning count" ansible.builtin.import_tasks: warning_facts.yml vars: warn_control_id: '6.2.7' when: rhel9cis_6_2_7_group_group_check.stdout is not defined when: - rhel9cis_rule_6_2_7 tags: - level1-server - level1-workstation - audit - accounts - groups - rule_6.2.7 - name: "6.2.8 | PATCH | Ensure root PATH Integrity" block: - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Get root paths" ansible.builtin.shell: sudo -Hiu root env | grep '^PATH' | cut -d= -f2 changed_when: false register: rhel9cis_6_2_8_root_paths - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Get root paths" ansible.builtin.shell: sudo -Hiu root env | grep '^PATH' | cut -d= -f2 | tr ":" "\n" changed_when: false register: rhel9cis_6_2_8_root_paths_split - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Set fact" ansible.builtin.set_fact: root_paths: "{{ rhel9cis_6_2_8_root_paths.stdout }}" - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Check for empty dirs" ansible.builtin.shell: 'echo {{ root_paths }} | grep -q "::" && echo "roots path contains a empty directory (::)"' changed_when: false failed_when: root_path_empty_dir.rc not in [ 0, 1 ] register: root_path_empty_dir - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Check for trailing ':'" ansible.builtin.shell: '{{ root_paths }} | cut -d= -f2 | grep -q ":$" && echo "roots path contains a trailing (:)"' changed_when: false failed_when: root_path_trailing_colon.rc not in [ 0, 1 ] register: root_path_trailing_colon - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Check for owner and permissions" block: - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Check for owner and permissions" ansible.builtin.stat: path: "{{ item }}" register: root_path_perms loop: "{{ rhel9cis_6_2_8_root_paths_split.stdout_lines }}" - ansible.builtin.debug: msg: "{{ root_path_perms.results }}" - name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Set permissions" ansible.builtin.file: path: "{{ item.stat.path }}" state: directory owner: root group: root mode: "0755" follow: false loop: "{{ root_path_perms.results }}" loop_control: label: "{{ item }}" when: - item.stat.exists - item.stat.isdir - item.stat.pw_name != 'root' or item.stat.gr_name != 'root' or item.stat.woth or item.stat.wgrp when: - rhel9cis_rule_6_2_8 tags: - level1-server - level1-workstation - patch - paths - rule_6.2.8 - name: "6.2.9 | PATCH | Ensure root is the only UID 0 account" ansible.builtin.shell: passwd -l {{ item }} changed_when: false failed_when: false loop: "{{ rhel9cis_uid_zero_accounts_except_root.stdout_lines }}" when: - rhel9cis_uid_zero_accounts_except_root.rc - rhel9cis_rule_6_2_9 tags: - level1-server - level1-workstation - patch - accounts - users - rule_6.2.9 - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist" block: - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | Create dir if absent" ansible.builtin.file: path: "{{ item.dir }}" state: directory owner: "{{ item.id }}" group: "{{ item.gid }}" register: rhel_09_6_2_10_home_dir loop: "{{ rhel9cis_passwd | selectattr('uid', '>=', min_int_uid | int ) | selectattr('uid', '<=', max_int_uid | int ) | list }}" loop_control: label: "{{ item.id }}" # set default ACLs so the homedir has an effective umask of 0027 - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | Set group ACL" ansible.posix.acl: path: "{{ item }}" default: true etype: group permissions: rx state: present loop: "{{ interactive_users_home.stdout_lines }}" when: not system_is_container - name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | Set other ACL" ansible.posix.acl: path: "{{ item }}" default: true etype: other permissions: 0 state: present loop: "{{ interactive_users_home.stdout_lines }}" when: not system_is_container when: - rhel9cis_rule_6_2_10 tags: - level1-server - level1-workstation - patch - users - rule_6.2.10 - name: "6.2.11 | PATCH | Ensure local interactive users own their home directories" ansible.builtin.file: path: "{{ item.dir }}" owner: "{{ item.id }}" state: directory loop: "{{ rhel9cis_passwd | selectattr('uid', '>=', min_int_uid | int ) | selectattr('uid', '<=', max_int_uid | int ) | list }}" loop_control: label: "{{ item.id }}" when: - item.uid >= min_int_uid | int - item.id != 'nobody' - (item.id != 'tss' and item.dir != '/dev/null') - item.shell != '/sbin/nologin' - rhel9cis_rule_6_2_11 tags: - level1-server - level1-workstation - patch - users - rule_6.2.11 - name: "6.2.12 | PATCH | Ensure local interactive user home directories are mode 750 or more restrictive" block: - name: "6.2.12 | AUDIT | Ensure local interactive user home directories are mode 750 or more restrictive | get stat" ansible.builtin.stat: path: "{{ item }}" register: rhel_09_6_2_12_home_dir_perms loop: "{{ interactive_users_home.stdout_lines }}" - name: "6.2.12 | PATCH | Ensure local interactive user home directories are mode 750 or more restrictive | amend if needed" ansible.builtin.file: path: "{{ item.stat.path }}" state: directory mode: "0750" loop: "{{ rhel_09_6_2_12_home_dir_perms.results }}" loop_control: label: "{{ item }}" when: - item.stat.mode > '0750' # set default ACLs so the homedir has an effective umask of 0027 - name: "6.2.12 | PATCH | Ensure local interactive user home directories are mode 750 or more restrictive | Set group ACL" ansible.posix.acl: path: "{{ item }}" default: true etype: group permissions: rx state: present loop: "{{ interactive_users_home.stdout_lines }}" when: not system_is_container - name: "6.2.12 | PATCH | Ensure local interactive user home directories are mode 750 or more restrictive | Set other ACL" ansible.posix.acl: path: "{{ item }}" default: true etype: other permissions: 0 state: present loop: "{{ interactive_users_home.stdout_lines }}" when: not system_is_container when: - rhel9cis_rule_6_2_12 tags: - level1-server - level1-workstation - patch - users - permissions - rule_6.2.12 - name: "6.2.13 | PATCH | Ensure no local interactive user has .netrc files" ansible.builtin.file: path: "{{ item }}/.netrc" state: absent loop: "{{ interactive_users_home.stdout_lines }}" when: - rhel9cis_rule_6_2_13 tags: - level1-server - level1-workstation - patch - users - permissions - rule_6.2.13 - name: "6.2.14 | PATCH | Ensure no local interactive user has .forward files" ansible.builtin.file: path: "{{ item }}/.forward" state: absent loop: "{{ interactive_users_home.stdout_lines }}" when: - rhel9cis_rule_6_2_14 tags: - level1-server - level1-workstation - patch - users - files - rule_6.2.14 - name: "6.2.15 | PATCH | Ensure no local interactive user has .rhosts files" ansible.builtin.file: path: "~{{ item }}/.rhosts" state: absent loop: "{{ interactive_users_home.stdout_lines }}" when: - rhel9cis_rule_6_2_15 tags: - level1-server - level1-workstation - patch - users - files - rule_6.2.15 - name: "6.2.16 | PATCH | Ensure local interactive user dot files are not group or world writable" block: - name: "6.2.16 | AUDIT | Ensure local interactive user dot files are not group or world writable | Check for files" ansible.builtin.find: path: /home depth: 3 patterns: ".*" hidden: true recurse: true file_type: file register: user_dot_files - name: "6.2.16 | AUDIT | Ensure local interactive user dot files are not group or world writable | update permissions" ansible.builtin.file: path: "{{ item.path }}" mode: go-w loop: "{{ user_dot_files.files }}" loop_control: label: "{{ item.path }}" when: - rhel9cis_rule_6_2_16 tags: - level1-server - level1-workstation - patch - users - permissions - rule_6.2.16