Merge pull request #36 from ansible-lockdown/benchmark_v2.0.0

Benchmark v2.0.0 Sync
This commit is contained in:
uk-bolly 2025-07-01 16:59:02 +01:00 committed by GitHub
commit cf8581fb03
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 129 additions and 97 deletions

View file

@ -39,16 +39,16 @@ repos:
rev: v1.5.0 rev: v1.5.0
hooks: hooks:
- id: detect-secrets - id: detect-secrets
name: Detect Secrets name: Detect Secrets test
- repo: https://github.com/gitleaks/gitleaks - repo: https://github.com/gitleaks/gitleaks
rev: v8.24.3 rev: v8.26.0
hooks: hooks:
- id: gitleaks - id: gitleaks
name: GitLeaks name: Run Gitleaks test
- repo: https://github.com/ansible-community/ansible-lint - repo: https://github.com/ansible-community/ansible-lint
rev: v25.2.1 rev: v25.5.0
hooks: hooks:
- id: ansible-lint - id: ansible-lint
name: Ansible-lint name: Ansible-lint
@ -67,7 +67,7 @@ repos:
# - ansible-core>=2.10.1 # - ansible-core>=2.10.1
- repo: https://github.com/adrienverge/yamllint.git - repo: https://github.com/adrienverge/yamllint.git
rev: v1.37.0 # or higher tag rev: v1.37.1 # or higher tag
hooks: hooks:
- id: yamllint - id: yamllint
name: Check YAML Lint name: Check YAML Lint

View file

@ -1,5 +1,23 @@
# Changes to rhel9CIS # Changes to rhel9CIS
## 2.0.2 - Based on CIS v2.0.0
- Update to audit_only to allow fetching results
- resolved false warning for fetch audit
- fix root user check
- Improved documentation and variable compilation for crypto policies
- Addresses #318 - Thank you @kodebach & @bgro
- Improved logic for 5.2.4 to exclude rhel9cis_sudoers_exclude_nopasswd_list in pre-check tasks/main.yml
- rule_6.3.3.5 updated for missing checks
## 2.0.1 - Based on CIS v2.0.0
- Thanks to @polski-g several issues and improvements added
- Improved testing for 50-redhat.conf for ssh
- 5.1.x regexp improvements
- Improved root password check
- egrep command changed to grep -E
## 2.0.0 - Based on CIS v2.0.0 ## 2.0.0 - Based on CIS v2.0.0
- #325 - thanks to @mindrb - #325 - thanks to @mindrb

View file

@ -12,7 +12,7 @@ os_check: true
# Disruption is high # Disruption is high
## Run tests that are considered higher risk and could have a system impact if not properly tested ## Run tests that are considered higher risk and could have a system impact if not properly tested
## Default false ## Default false
## Will be fine if clean new unconfigured build ## Will be fine if clean new un-configured build
rhel9cis_disruption_high: false rhel9cis_disruption_high: false
## Switching on/off specific baseline sections ## Switching on/off specific baseline sections
@ -37,6 +37,7 @@ rhel9cis_level_2: true
# Create managed not custom local_facts files # Create managed not custom local_facts files
create_benchmark_facts: true create_benchmark_facts: true
ansible_facts_path: /etc/ansible/facts.d ansible_facts_path: /etc/ansible/facts.d
## Section 1.6 - Mandatory Access Control ## Section 1.6 - Mandatory Access Control
# This variable governs whether SELinux is disabled or not. If SELinux is NOT DISABLED by setting # This variable governs whether SELinux is disabled or not. If SELinux is NOT DISABLED by setting
# 'rhel9cis_selinux_disable' to 'true', the 1.6 subsection will be executed. # 'rhel9cis_selinux_disable' to 'true', the 1.6 subsection will be executed.
@ -111,7 +112,7 @@ audit_conf_dest: "/opt"
# Where the audit logs are stored # Where the audit logs are stored
audit_log_dir: '/opt' audit_log_dir: '/opt'
## Ability to collect and take audit files moving to a centralised location ## Ability to collect and take audit files moving to a centralized location
# This enables the collection of the files from the host # This enables the collection of the files from the host
fetch_audit_output: false fetch_audit_output: false
@ -238,7 +239,7 @@ rhel9cis_rule_1_8_8: true
rhel9cis_rule_1_8_9: true rhel9cis_rule_1_8_9: true
rhel9cis_rule_1_8_10: true rhel9cis_rule_1_8_10: true
# Section 2 rules are controlling Services (Special Purpose Services, and service clients) # Section 2 rules are controling Services (Special Purpose Services, and service clients)
## Configure Server Services ## Configure Server Services
rhel9cis_rule_2_1_1: true rhel9cis_rule_2_1_1: true
rhel9cis_rule_2_1_2: true rhel9cis_rule_2_1_2: true
@ -513,7 +514,7 @@ rhel9cis_rule_7_2_9: true
## Section 1 vars ## Section 1 vars
## Ability to enabe debug on mounts to assist in troubleshooting ## Ability to enable debug on mounts to assist in troubleshooting
# Mount point changes are set based upon facts created in Prelim # Mount point changes are set based upon facts created in Prelim
# these then build the variable and options that is passed to the handler to set the mount point for the controls in section1. # these then build the variable and options that is passed to the handler to set the mount point for the controls in section1.
rhel9cis_debug_mount_data: false rhel9cis_debug_mount_data: false
@ -579,8 +580,8 @@ rhel9cis_crypto_policy: 'DEFAULT'
## Control 1.6 ## Control 1.6
# This variable contains the value of the crypto policy module(combinations of policies and # This variable contains the value of the crypto policy module(combinations of policies and
# sub-policies) to be allowed as default setting. Allowed options are defined in 'vars/main.yml' file, # sub-policies) to be allowed as default setting. Allowed options are defined in 'vars/main.yml' file,
# using 'rhel9cis_allowed_crypto_policies_modules' variable. # using those listed in the 'rhel9cis_allowed_crypto_policies_modules' variable.
rhel9cis_crypto_policy_module: '' rhel9cis_additional_crypto_policy_module: ''
## Controls: ## Controls:
# - 1.7.1 - Ensure message of the day is configured properly # - 1.7.1 - Ensure message of the day is configured properly
@ -723,6 +724,7 @@ rhel9cis_ipv6_required: true
## 3.1.2 wireless network requirements ## 3.1.2 wireless network requirements
# if wireless adapter found allow network manager to be installed # if wireless adapter found allow network manager to be installed
rhel9cis_install_network_manager: false rhel9cis_install_network_manager: false
rhel9cis_network_manager_package_name: NetworkManager
# 3.3 System network parameters (host only OR host and router) # 3.3 System network parameters (host only OR host and router)
# This variable governs whether specific CIS rules # This variable governs whether specific CIS rules
# concerned with acceptance and routing of packages are skipped. # concerned with acceptance and routing of packages are skipped.
@ -1045,14 +1047,14 @@ rhel9cis_bash_umask: '0027' # 0027 or more restrictive
# These are discovered via logins.def if set true # These are discovered via logins.def if set true
rhel9cis_discover_int_uid: true rhel9cis_discover_int_uid: true
# This variable sets the minimum number from which to search for UID # This variable sets the minimum number from which to search for UID
# Note that the value will be dynamically overwritten if variable `dicover_int_uid` has # Note that the value will be dynamically overwritten if variable `rhel9cis_discover_int_uid` has
# been set to `true`. # been set to `true`.
min_int_uid: 1000 min_int_uid: 1000
### Controls: ### Controls:
# - Ensure local interactive user home directories exist # - Ensure local interactive user home directories exist
# - Ensure local interactive users own their home directories # - Ensure local interactive users own their home directories
# This variable sets the maximum number at which the search stops for UID # This variable sets the maximum number at which the search stops for UID
# Note that the value will be dynamically overwritten if variable `dicover_int_uid` has # Note that the value will be dynamically overwritten if variable `rhel9cis_discover_int_uid` has
# been set to `true`. # been set to `true`.
max_int_uid: 65533 max_int_uid: 65533

View file

@ -150,7 +150,7 @@
ansible.posix.mount: ansible.posix.mount:
path: "{{ mount_point }}" path: "{{ mount_point }}"
state: remounted state: remounted
notify: Change_requires_reboot notify: Set reboot required
listen: "Remount /boot/efi" listen: "Remount /boot/efi"
- name: Reload sysctl - name: Reload sysctl
@ -186,7 +186,7 @@
- name: Update Crypto Policy - name: Update Crypto Policy
ansible.builtin.set_fact: ansible.builtin.set_fact:
rhel9cis_full_crypto_policy: "{{ rhel9cis_crypto_policy }}{% if rhel9cis_crypto_policy_module | length > 0 %}{{ rhel9cis_crypto_policy_module }}{% endif %}" rhel9cis_full_crypto_policy: "{{ rhel9cis_crypto_policy }}{{ rhel9cis_crypto_policy_module }}{% if rhel9cis_additional_crypto_policy_module | length > 0 %}:{{ rhel9cis_additional_crypto_policy_module }}{% endif %}"
notify: Set Crypto Policy notify: Set Crypto Policy
- name: Set Crypto Policy - name: Set Crypto Policy
@ -194,7 +194,7 @@
ansible.builtin.command: update-crypto-policies --set "{{ rhel9cis_full_crypto_policy }}" ansible.builtin.command: update-crypto-policies --set "{{ rhel9cis_full_crypto_policy }}"
changed_when: true changed_when: true
notify: notify:
- Change_requires_reboot - Set reboot required
- Restart sshd - Restart sshd
- name: Restart firewalld - name: Restart firewalld
@ -255,7 +255,7 @@
when: discovered_auditd_immutable_check.stdout == '1' when: discovered_auditd_immutable_check.stdout == '1'
ansible.builtin.debug: ansible.builtin.debug:
msg: "Reboot required for auditd to apply new rules as immutable set" msg: "Reboot required for auditd to apply new rules as immutable set"
notify: Change_requires_reboot notify: Set reboot required
- name: Stop auditd process - name: Stop auditd process
ansible.builtin.command: systemctl kill auditd ansible.builtin.command: systemctl kill auditd
@ -268,6 +268,6 @@
state: started state: started
listen: Restart auditd listen: Restart auditd
- name: Change_requires_reboot - name: Set reboot required
ansible.builtin.set_fact: ansible.builtin.set_fact:
change_requires_reboot: true change_requires_reboot: true

View file

@ -1,7 +1,7 @@
--- ---
- name: Apply ansible-lockdown hardening - name: Apply ansible-lockdown hardening
hosts: all hosts: "{{ hosts | default('all') }}"
become: true become: true
roles: roles:
- role: "{{ playbook_dir }}" - role: "{{ playbook_dir }}"

View file

@ -1,20 +1,17 @@
--- ---
- name: Audit_Only | Create local Directories for hosts - name: Audit_only | Fetch audit files
when: fetch_audit_files when:
ansible.builtin.file: - fetch_audit_output
mode: 'u+x,go-w' - audit_only
path: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}" ansible.builtin.import_tasks:
recurse: true file: fetch_audit_output.yml
state: directory
delegate_to: localhost
become: false
- name: Audit_only | Show Audit Summary - name: Audit_only | Show Audit Summary
when: audit_only when: audit_only
ansible.builtin.debug: ansible.builtin.debug:
msg: "{{ audit_results.split('\n') }}" msg: "{{ audit_results.split('\n') }}"
- name: Audit_only | Stop Playbook Audit Only selected - name: Audit_only | Stop task for host as audit_only selected
when: audit_only when: audit_only
ansible.builtin.meta: end_play ansible.builtin.meta: end_host

View file

@ -7,6 +7,7 @@
- name: "POST | AUDITD | Set supported_syscalls variable" - name: "POST | AUDITD | Set supported_syscalls variable"
ansible.builtin.shell: ausyscall --dump | awk '{print $2}' ansible.builtin.shell: ausyscall --dump | awk '{print $2}'
changed_when: false changed_when: false
check_mode: false
failed_when: discovered_auditd_syscalls.rc not in [ 0, 1 ] failed_when: discovered_auditd_syscalls.rc not in [ 0, 1 ]
register: discovered_auditd_syscalls register: discovered_auditd_syscalls

View file

@ -8,6 +8,7 @@
src: "{{ item }}" src: "{{ item }}"
dest: "{{ audit_output_destination }}" dest: "{{ audit_output_destination }}"
flat: true flat: true
changed_when: true
failed_when: false failed_when: false
register: discovered_audit_fetch_state register: discovered_audit_fetch_state
loop: loop:

View file

@ -59,7 +59,7 @@
- crypto - crypto
- NIST800-53R5_SC-6 - NIST800-53R5_SC-6
ansible.builtin.assert: ansible.builtin.assert:
that: rhel9cis_crypto_policy_module in rhel9cis_allowed_crypto_policies_modules that: rhel9cis_additional_crypto_policy_module in rhel9cis_allowed_crypto_policies_modules
fail_msg: "Crypto policy module is not a permitted version" fail_msg: "Crypto policy module is not a permitted version"
success_msg: "Crypto policy module is a permitted version" success_msg: "Crypto policy module is a permitted version"
@ -99,10 +99,9 @@
- name: "Check account is not locked for {{ ansible_env.SUDO_USER }} | Assert local account not locked" # noqa name[template] - name: "Check account is not locked for {{ ansible_env.SUDO_USER }} | Assert local account not locked" # noqa name[template]
ansible.builtin.assert: ansible.builtin.assert:
that: that: (not prelim_ansible_user_password_set.stdout.startswith("!")) or (ansible_env.SUDO_USER in rhel9cis_sudoers_exclude_nopasswd_list)
- not prelim_ansible_user_password_set.stdout.startswith("!")
fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_env.SUDO_USER }} is locked - It can break access" fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_env.SUDO_USER }} is locked - It can break access"
success_msg: "The local account is not locked for {{ ansible_env.SUDO_USER }} user" success_msg: "The local account is not locked for {{ ansible_env.SUDO_USER }} is not locked or included in the exception list for rule 5.2.4"
- name: "Check authselect profile is selected" - name: "Check authselect profile is selected"
when: rhel9cis_allow_authselect_updates when: rhel9cis_allow_authselect_updates
@ -130,7 +129,7 @@
- rule_5.4.2.4 - rule_5.4.2.4
block: block:
- name: "Ensure root password is set" - name: "Ensure root password is set"
ansible.builtin.shell: passwd -S root | egrep -e "(Password set, SHA512 crypt|Password locked)" ansible.builtin.shell: passwd -S root | grep -E "(Password set, SHA512 crypt|Password locked)"
changed_when: false changed_when: false
register: prelim_root_passwd_set register: prelim_root_passwd_set

View file

@ -7,12 +7,12 @@
ansible.builtin.shell: cat /etc/passwd | grep -v '^#' ansible.builtin.shell: cat /etc/passwd | grep -v '^#'
changed_when: false changed_when: false
check_mode: false check_mode: false
register: prelim_passwd_file_audit register: prelim_capture_passwd_file
- name: "PRELIM | 5.5.2 | 6.2.7 | 6.2.8 | 6.2.20 | Split passwd entries" - name: "PRELIM | 5.4.2 | 7.2.8 | Split passwd entries"
ansible.builtin.set_fact: ansible.builtin.set_fact:
rhel9cis_passwd: "{{ prelim_passwd_file_audit.stdout_lines | map('regex_replace', ld_passwd_regex, ld_passwd_yaml) | map('from_yaml') | list }}" prelim_captured_passwd_data: "{{ prelim_capture_passwd_file.stdout_lines | map('regex_replace', ld_passwd_regex, ld_passwd_yaml) | map('from_yaml') | list }}"
loop: "{{ prelim_passwd_file_audit.stdout_lines }}" loop: "{{ prelim_capture_passwd_file.stdout_lines }}"
vars: vars:
ld_passwd_regex: >- ld_passwd_regex: >-
^(?P<id>[^:]*):(?P<password>[^:]*):(?P<uid>[^:]*):(?P<gid>[^:]*):(?P<gecos>[^:]*):(?P<dir>[^:]*):(?P<shell>[^:]*) ^(?P<id>[^:]*):(?P<password>[^:]*):(?P<uid>[^:]*):(?P<gid>[^:]*):(?P<gecos>[^:]*):(?P<dir>[^:]*):(?P<shell>[^:]*)

View file

@ -1,4 +1,5 @@
--- ---
- name: Pre Audit Setup | Setup the LE audit - name: Pre Audit Setup | Setup the LE audit
when: setup_audit when: setup_audit
tags: setup_audit tags: setup_audit
@ -46,7 +47,7 @@
remote_src: "{{ (audit_conf_source is contains('http')) | ternary(true, false) }}" remote_src: "{{ (audit_conf_source is contains('http')) | ternary(true, false) }}"
extra_opts: "{{ (audit_conf_source is contains('github')) | ternary('--strip-components=1', []) }}" extra_opts: "{{ (audit_conf_source is contains('github')) | ternary('--strip-components=1', []) }}"
- name: Pre Audit Setup | Check Goss is available - name: Pre Audit Setup | Check goss is available
when: run_audit when: run_audit
block: block:
- name: Pre Audit Setup | Check for goss file - name: Pre Audit Setup | Check for goss file

View file

@ -4,9 +4,7 @@
# List users in order to look files inside each home directory # List users in order to look files inside each home directory
- name: "PRELIM | Include audit specific variables" - name: "PRELIM | Include audit specific variables"
when: when: run_audit or audit_only or setup_audit
- run_audit or audit_only
- setup_audit
tags: tags:
- setup_audit - setup_audit
- run_audit - run_audit
@ -14,9 +12,7 @@
file: audit.yml file: audit.yml
- name: "PRELIM | Include pre-remediation audit tasks" - name: "PRELIM | Include pre-remediation audit tasks"
when: when: run_audit or audit_only or setup_audit
- run_audit or audit_only
- setup_audit
tags: run_audit tags: run_audit
ansible.builtin.import_tasks: pre_remediation_audit.yml ansible.builtin.import_tasks: pre_remediation_audit.yml
@ -31,9 +27,17 @@
- name: "PRELIM | AUDIT | Interactive Users (reformat)" - name: "PRELIM | AUDIT | Interactive Users (reformat)"
tags: always tags: always
ansible.builtin.set_fact: ansible.builtin.set_fact:
prelim_interactive_usernames: "{{ prelim_interactive_users | default([]) + [dict([('username', item.split(':')[0]), ('uid', item.split(':')[1]), ('home', item.split(':')[2])])] }}" prelim_interactive_users: "{{ prelim_interactive_users | default([]) + [dict([('username', item.split(':')[0]), ('uid', item.split(':')[1]), ('home', item.split(':')[2])])] }}"
loop: "{{ prelim_interactive_users_raw.stdout_lines }}" loop: "{{ prelim_interactive_users_raw.stdout_lines }}"
- name: "PRELIM | AUDIT | Interactive User accounts home directories"
tags: always
ansible.builtin.shell: >
grep -E -v '^(root|halt|sync|shutdown)' /etc/passwd | awk -F: '(!index($7, "sbin/nologin") && $7 != "/bin/nologin" && $7 != "/bin/false" && $7 != "/dev/null") { print $6 }'
changed_when: false
check_mode: false
register: prelim_interactive_users_home
- name: "PRELIM | AUDIT | Interactive UIDs" - name: "PRELIM | AUDIT | Interactive UIDs"
tags: always tags: always
ansible.builtin.shell: > ansible.builtin.shell: >
@ -132,8 +136,7 @@
register: prelim_systemd_coredump register: prelim_systemd_coredump
- name: "PRELIM | PATCH | Setup crypto-policy" - name: "PRELIM | PATCH | Setup crypto-policy"
when: when: rhel9cis_rule_1_6_1
- rhel9cis_rule_1_6_1
tags: tags:
- level1-server - level1-server
- level1-workstation - level1-workstation
@ -181,17 +184,14 @@
grub2_path: /etc/grub2-efi.cfg grub2_path: /etc/grub2-efi.cfg
- name: "PRELIM | AUDIT | Discover Gnome Desktop Environment" - name: "PRELIM | AUDIT | Discover Gnome Desktop Environment"
tags: tags: always
- always
ansible.builtin.stat: ansible.builtin.stat:
path: /usr/share/gnome/gnome-version.xml path: /usr/share/gnome/gnome-version.xml
register: prelim_gnome_present register: prelim_gnome_present
- name: "PRELIM | PATCH | Install dconf if gui installed" - name: "PRELIM | PATCH | Install dconf if gui installed"
when: when: rhel9cis_gui
- rhel9cis_gui tags: always
tags:
- always
ansible.builtin.package: ansible.builtin.package:
name: dconf name: dconf
state: present state: present
@ -200,10 +200,9 @@
when: when:
- rhel9cis_rule_3_1_2 - rhel9cis_rule_3_1_2
- not system_is_container - not system_is_container
tags: tags: always
- always
block: block:
- name: "PRELIM | AUDIT | Discover is wirelss adapter on system" - name: "PRELIM | AUDIT | Discover is wireless adapter on system"
ansible.builtin.command: find /sys/class/net/*/ -type d -name wireless ansible.builtin.command: find /sys/class/net/*/ -type d -name wireless
register: discover_wireless_adapters register: discover_wireless_adapters
changed_when: false changed_when: false
@ -246,6 +245,12 @@
mode: 'go-rwx' mode: 'go-rwx'
state: touch state: touch
- name: "PRELIM | PATCH | sshd_config.d/50-redhat.conf exists"
when: rhel9cis_rule_5_1_10 or rhel9cis_rule_5_1_11
ansible.builtin.stat:
path: /etc/ssh/sshd_config.d/50-redhat.conf
register: prelim_sshd_50_redhat_file
- name: "PRELIM | AUDIT | Capture pam security related files" - name: "PRELIM | AUDIT | Capture pam security related files"
tags: always tags: always
ansible.builtin.find: ansible.builtin.find:
@ -269,8 +274,7 @@
- name: "PRELIM | PATCH | Create journald config directory" - name: "PRELIM | PATCH | Create journald config directory"
when: when:
- rhel9cis_syslog == 'journald' - rhel9cis_syslog == 'journald'
- rhel9cis_rule_6_2_1_3 or - rhel9cis_rule_6_2_1_3 or rhel9cis_rule_6_2_1_4
rhel9cis_rule_6_2_1_4
tags: always tags: always
ansible.builtin.file: ansible.builtin.file:
path: /etc/systemd/journald.conf.d path: /etc/systemd/journald.conf.d

View file

@ -27,8 +27,7 @@
mode: 'go-rwx' mode: 'go-rwx'
- name: "1.1.1.1 | PATCH | Ensure cramfs kernel module is not available | Disable cramfs" - name: "1.1.1.1 | PATCH | Ensure cramfs kernel module is not available | Disable cramfs"
when: when: not system_is_container
- not system_is_container
community.general.modprobe: community.general.modprobe:
name: cramfs name: cramfs
state: absent state: absent

View file

@ -21,12 +21,12 @@
register: discovered_home_mount register: discovered_home_mount
- name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | Absent" - name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | Absent"
when: discovered_dev_shm_mount is undefined when: discovered_home_mount is undefined
ansible.builtin.debug: ansible.builtin.debug:
msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" msg: "Warning!! {{ required_mount }} is not mounted on a separate partition"
- name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | Present" - name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | Present"
when: discovered_dev_shm_mount is undefined when: discovered_home_mount is undefined
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: warning_facts.yml file: warning_facts.yml

View file

@ -22,12 +22,12 @@
register: discovered_var_mount register: discovered_var_mount
- name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | Absent" - name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | Absent"
when: discovered_dev_shm_mount is undefined when: discovered_var_mount is undefined
ansible.builtin.debug: ansible.builtin.debug:
msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" msg: "Warning!! {{ required_mount }} is not mounted on a separate partition"
- name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | Present" - name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | Present"
when: discovered_dev_shm_mount is undefined when: discovered_var_mount is undefined
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: warning_facts.yml file: warning_facts.yml

View file

@ -13,4 +13,4 @@
ansible.builtin.package: ansible.builtin.package:
name: "*" name: "*"
state: latest state: latest
notify: Change_requires_reboot notify: Set reboot required

View file

@ -106,7 +106,7 @@
warn_control_id: '1.3.1.6' warn_control_id: '1.3.1.6'
block: block:
- name: "1.3.1.6 | AUDIT | Ensure no unconfined services exist | Find the unconfined services" - name: "1.3.1.6 | AUDIT | Ensure no unconfined services exist | Find the unconfined services"
ansible.builtin.shell: ps -eZ | grep unconfined_service_t | egrep -vw "tr|ps|egrep|bash|awk" | tr ':' ' ' | awk '{ print $NF }' ansible.builtin.shell: ps -eZ | grep unconfined_service_t | grep -Evw "tr|ps|egrep|bash|awk" | tr ':' ' ' | awk '{ print $NF }'
register: discovered_unconf_services register: discovered_unconf_services
failed_when: false failed_when: false
changed_when: false changed_when: false

View file

@ -39,7 +39,7 @@
warn_control_id: '3.1.2' warn_control_id: '3.1.2'
block: block:
- name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Check for network-manager tool" - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Check for network-manager tool"
when: "'network-manager' in ansible_facts.packages" when: "rhel9cis_network_manager_package_name in ansible_facts.packages"
ansible.builtin.command: nmcli radio wifi ansible.builtin.command: nmcli radio wifi
changed_when: false changed_when: false
failed_when: false failed_when: false
@ -48,19 +48,19 @@
- name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Disable wireless if network-manager installed" - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Disable wireless if network-manager installed"
when: when:
- "'network-manager' in ansible_facts.packages" - "rhel9cis_network_manager_package_name in ansible_facts.packages"
- "'enabled' in discovered_wifi_status.stdout" - "'enabled' in discovered_wifi_status.stdout"
ansible.builtin.command: nmcli radio all off ansible.builtin.command: nmcli radio all off
changed_when: discovered_nmcli_radio_off.rc == 0 changed_when: discovered_nmcli_radio_off.rc == 0
register: discovered_nmcli_radio_off register: discovered_nmcli_radio_off
- name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Warn about wireless if network-manager not installed" - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Warn about wireless if network-manager not installed"
when: "'network-manager' not in ansible_facts.packages" when: "rhel9cis_network_manager_package_name not in ansible_facts.packages"
ansible.builtin.debug: ansible.builtin.debug:
msg: "Warning!! You need to disable wireless interfaces manually since network-manager is not installed" msg: "Warning!! You need to disable wireless interfaces manually since network-manager is not installed"
- name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Set warning count" - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Set warning count"
when: "'network-manager' not in ansible_facts.packages" when: "rhel9cis_network_manager_package_name not in ansible_facts.packages"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: warning_facts.yml file: warning_facts.yml

View file

@ -276,9 +276,10 @@
notify: Restart sshd notify: Restart sshd
- name: "5.1.10 | PATCH | Ensure sshd DisableForwarding is enabled | override" - name: "5.1.10 | PATCH | Ensure sshd DisableForwarding is enabled | override"
when: prelim_sshd_50_redhat_file.stat.exists
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config.d/50-redhat.conf path: /etc/ssh/sshd_config.d/50-redhat.conf
regexp: ^(?i)(#|)\s*X11Forwarding regexp: (?i)^(#|)\s*X11Forwarding
line: 'X11Forwarding {{ rhel9cis_sshd_x11forwarding }}' line: 'X11Forwarding {{ rhel9cis_sshd_x11forwarding }}'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd notify: Restart sshd
@ -298,9 +299,10 @@
- NIST800-53R5_IA-5 - NIST800-53R5_IA-5
block: block:
- name: "5.1.11 | PATCH | Ensure sshd GSSAPIAuthentication is disabled | redhat file" - name: "5.1.11 | PATCH | Ensure sshd GSSAPIAuthentication is disabled | redhat file"
when: prelim_sshd_50_redhat_file.stat.exists
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config.d/50-redhat.conf path: /etc/ssh/sshd_config.d/50-redhat.conf
regexp: ^(?i)(#|)\s*GSSAPIAuthentication regexp: (?i)^(#|)\s*GSSAPIAuthentication
line: GSSAPIAuthentication no line: GSSAPIAuthentication no
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd notify: Restart sshd
@ -308,7 +310,7 @@
- name: "5.1.11 | PATCH | Ensure sshd GSSAPIAuthentication is disabled | ssh config" - name: "5.1.11 | PATCH | Ensure sshd GSSAPIAuthentication is disabled | ssh config"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: ^(?i)(#|)\s*GSSAPIAuthentication regexp: (?i)^(#|)\s*GSSAPIAuthentication
line: GSSAPIAuthentication no line: GSSAPIAuthentication no
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd notify: Restart sshd
@ -328,7 +330,7 @@
- NIST800-53R5_IA-5 - NIST800-53R5_IA-5
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: ^(?i)(#|)\s*HostbasedAuthentication regexp: (?i)^(#|)\s*HostbasedAuthentication
line: 'HostbasedAuthentication no' line: 'HostbasedAuthentication no'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd notify: Restart sshd
@ -348,7 +350,7 @@
- NIST800-53R5_IA-5 - NIST800-53R5_IA-5
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: ^(?i)(#|)\s*IgnoreRhosts regexp: (?i)^(#|)\s*IgnoreRhosts
line: 'IgnoreRhosts yes' line: 'IgnoreRhosts yes'
insertbefore: "^Match" insertbefore: "^Match"
firstmatch: true firstmatch: true
@ -366,7 +368,7 @@
- NIST800-53R5_CM-6 - NIST800-53R5_CM-6
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: ^(?i)(#|)\s*LoginGraceTime regexp: (?i)^(#|)\s*LoginGraceTime
line: "LoginGraceTime {{ rhel9cis_sshd_logingracetime }}" line: "LoginGraceTime {{ rhel9cis_sshd_logingracetime }}"
insertbefore: "^Match" insertbefore: "^Match"
firstmatch: true firstmatch: true
@ -386,7 +388,7 @@
- NIST800-53R5_SI-5 - NIST800-53R5_SI-5
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: ^(?i)(#|)\s*LogLevel regexp: (?i)^(#|)\s*LogLevel
line: 'LogLevel {{ rhel9cis_ssh_loglevel }}' line: 'LogLevel {{ rhel9cis_ssh_loglevel }}'
insertbefore: "^Match" insertbefore: "^Match"
firstmatch: true firstmatch: true
@ -424,7 +426,7 @@
- NIST800-53R5_IA-5 - NIST800-53R5_IA-5
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: ^(?i)(#|)\s*MaxStartups regexp: (?i)^(#|)\s*MaxStartups
line: 'MaxStartups {{ rhel9cis_ssh_maxstartups }}' line: 'MaxStartups {{ rhel9cis_ssh_maxstartups }}'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd notify: Restart sshd
@ -444,7 +446,7 @@
- NIST800-53R5_IA-5 - NIST800-53R5_IA-5
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: ^(?i)(#|)\s*MaxSessions regexp: (?i)^(#|)\s*MaxSessions
line: 'MaxSessions {{ rhel9cis_ssh_maxsessions }}' line: 'MaxSessions {{ rhel9cis_ssh_maxsessions }}'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd notify: Restart sshd
@ -464,7 +466,7 @@
- NIST800-53R5_IA-5 - NIST800-53R5_IA-5
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: ^(?i)(#|)\s*PermitEmptyPasswords regexp: (?i)^(#|)\s*PermitEmptyPasswords
line: 'PermitEmptyPasswords no' line: 'PermitEmptyPasswords no'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd notify: Restart sshd
@ -482,7 +484,7 @@
- name: "5.1.20 | PATCH | Ensure sshd PermitRootLogin is disabled | config file" - name: "5.1.20 | PATCH | Ensure sshd PermitRootLogin is disabled | config file"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: ^(?i)(#|)\s*PermitRootLogin regexp: (?i)^(#|)\s*PermitRootLogin
line: 'PermitRootLogin no' line: 'PermitRootLogin no'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd notify: Restart sshd
@ -508,7 +510,7 @@
- NIST800-53R5_IA-5 - NIST800-53R5_IA-5
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: ^(?i)(#|)\s*PermitUserEnvironment regexp: (?i)^(#|)\s*PermitUserEnvironment
line: 'PermitUserEnvironment no' line: 'PermitUserEnvironment no'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd notify: Restart sshd
@ -528,7 +530,7 @@
- NIST800-53R5_IA-5 - NIST800-53R5_IA-5
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: ^(?i)(#|)\s*UsePAM regexp: (?i)^(#|)\s*UsePAM
line: 'UsePAM yes' line: 'UsePAM yes'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd notify: Restart sshd

View file

@ -29,7 +29,7 @@
- name: "5.4.1.1 | PATCH | Ensure password expiration is 365 days or less | Set existing users PASS_MAX_DAYS" - name: "5.4.1.1 | PATCH | Ensure password expiration is 365 days or less | Set existing users PASS_MAX_DAYS"
when: when:
- discovered_max_days.stdout_lines | length > 0 - discovered_max_days.stdout_lines | length > 0
- item in prelim_interactive_usernames | map(attribute='username') | list - item in prelim_interactive_users | map(attribute='username') | list
- rhel9cis_force_user_maxdays - rhel9cis_force_user_maxdays
ansible.builtin.user: ansible.builtin.user:
name: "{{ item }}" name: "{{ item }}"
@ -60,7 +60,7 @@
- name: "5.4.1.2 | PATCH | Ensure minimum password days is configured | Set existing users PASS_MIN_DAYS" - name: "5.4.1.2 | PATCH | Ensure minimum password days is configured | Set existing users PASS_MIN_DAYS"
when: when:
- discovered_min_days.stdout_lines | length > 0 - discovered_min_days.stdout_lines | length > 0
- item in prelim_interactive_usernames | map(attribute='username') | list - item in prelim_interactive_users | map(attribute='username') | list
- rhel9cis_force_user_mindays - rhel9cis_force_user_mindays
ansible.builtin.user: ansible.builtin.user:
name: "{{ item }}" name: "{{ item }}"
@ -91,7 +91,7 @@
- name: "5.4.1.3 | PATCH | Ensure password expiration warning days is configured | Set existing users WARN_DAYS" - name: "5.4.1.3 | PATCH | Ensure password expiration warning days is configured | Set existing users WARN_DAYS"
when: when:
- discovered_warn_days.stdout_lines | length > 0 - discovered_warn_days.stdout_lines | length > 0
- item in prelim_interactive_usernames | map(attribute='username') | list - item in prelim_interactive_users | map(attribute='username') | list
- rhel9cis_force_user_warnage - rhel9cis_force_user_warnage
ansible.builtin.command: "chage --warndays {{ rhel9cis_pass['warn_age'] }} {{ item }}" ansible.builtin.command: "chage --warndays {{ rhel9cis_pass['warn_age'] }} {{ item }}"
changed_when: true changed_when: true
@ -140,7 +140,7 @@
register: discovered_passwdlck_user_list register: discovered_passwdlck_user_list
- name: "5.4.1.5 | PATCH | Ensure inactive password lock is 30 days or less | Apply Inactive setting to existing accounts" - name: "5.4.1.5 | PATCH | Ensure inactive password lock is 30 days or less | Apply Inactive setting to existing accounts"
when: item in prelim_interactive_usernames | map(attribute='username') | list when: item in prelim_interactive_users | map(attribute='username') | list
ansible.builtin.command: chage --inactive {{ rhel9cis_inactivelock.lock_days }} "{{ item }}" ansible.builtin.command: chage --inactive {{ rhel9cis_inactivelock.lock_days }} "{{ item }}"
changed_when: true changed_when: true
loop: "{{ discovered_passwdlck_user_list.stdout_lines }}" loop: "{{ discovered_passwdlck_user_list.stdout_lines }}"

View file

@ -195,7 +195,7 @@
- name: "5.4.2.7 | PATCH | Ensure system accounts do not have a valid login shell" - name: "5.4.2.7 | PATCH | Ensure system accounts do not have a valid login shell"
when: when:
- rhel9cis_rule_5_4_2_7 - rhel9cis_rule_5_4_2_7
- "item.id not in prelim_interactive_usernames | map(attribute='username')" - "item.id not in prelim_interactive_users | map(attribute='username')"
- item.id not in rhel9cis_system_users_shell - item.id not in rhel9cis_system_users_shell
- "'root' not in item.id" - "'root' not in item.id"
- rhel9cis_disruption_high - rhel9cis_disruption_high
@ -212,7 +212,7 @@
ansible.builtin.user: ansible.builtin.user:
name: "{{ item.id }}" name: "{{ item.id }}"
shell: /usr/sbin/nologin shell: /usr/sbin/nologin
loop: "{{ rhel9cis_passwd }}" loop: "{{ prelim_captured_passwd_data }}"
loop_control: loop_control:
label: "{{ item.id }}" label: "{{ item.id }}"
@ -220,7 +220,7 @@
when: when:
- rhel9cis_rule_5_4_2_8 - rhel9cis_rule_5_4_2_8
- rhel9cis_disruption_high - rhel9cis_disruption_high
- "item.id not in prelim_interactive_usernames | map(attribute='username')" - "item.id not in prelim_interactive_users | map(attribute='username')"
- "'root' not in item.id" - "'root' not in item.id"
tags: tags:
- level1-server - level1-server
@ -235,6 +235,6 @@
ansible.builtin.user: ansible.builtin.user:
name: "{{ item.id }}" name: "{{ item.id }}"
password_lock: true password_lock: true
loop: "{{ rhel9cis_passwd }}" loop: "{{ prelim_captured_passwd_data }}"
loop_control: loop_control:
label: "{{ item.id }}" label: "{{ item.id }}"

View file

@ -220,7 +220,7 @@
- name: "7.2.7 | AUDIT | Ensure no duplicate group names exist | Print warning about users with duplicate group names" - name: "7.2.7 | AUDIT | Ensure no duplicate group names exist | Print warning about users with duplicate group names"
when: discovered_group_check.stdout | length > 0 when: discovered_group_check.stdout | length > 0
ansible.builtin.debug: ansible.builtin.debug:
msg: "Warning!! The following group names are duplicates: {{ discovered_group_group_check.stdout_lines }}" msg: "Warning!! The following group names are duplicates: {{ discovered_group_check.stdout_lines }}"
- name: "7.2.7 | AUDIT | Ensure no duplicate group names exist | Set warning count" - name: "7.2.7 | AUDIT | Ensure no duplicate group names exist | Set warning count"
when: discovered_group_check.stdout | length > 0 when: discovered_group_check.stdout | length > 0
@ -243,7 +243,7 @@
state: directory state: directory
owner: "{{ item.id }}" owner: "{{ item.id }}"
group: "{{ item.gid }}" group: "{{ item.gid }}"
loop: "{{ rhel9cis_passwd | selectattr('uid', '>=', prelim_min_int_uid | int) | selectattr('uid', '<=', prelim_max_int_uid | int) | list }}" loop: "{{ prelim_captured_passwd_data | selectattr('uid', '>=', prelim_min_int_uid | int) | selectattr('uid', '<=', prelim_max_int_uid | int) | list }}"
loop_control: loop_control:
label: "{{ item.id }}" label: "{{ item.id }}"
@ -315,6 +315,6 @@
ansible.builtin.file: ansible.builtin.file:
path: '{{ item }}' path: '{{ item }}'
mode: 'go-w' mode: 'go-w'
owner: "{{ rhel9cis_passwd | selectattr('dir', 'in', prelim_interactive_users_raw.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='uid') | last }}" owner: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_raw.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='uid') | last }}"
group: "{{ rhel9cis_passwd | selectattr('dir', 'in', prelim_interactive_users_raw.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='gid') | last }}" group: "{{ prelim_captured_passwd_data | selectattr('dir', 'in', prelim_interactive_users_raw.stdout_lines) | selectattr('dir', 'in', item) | map(attribute='gid') | last }}"
with_items: "{{ discovered_homedir_hidden_files.stdout_lines }}" with_items: "{{ discovered_homedir_hidden_files.stdout_lines }}"

View file

@ -56,8 +56,10 @@
-w /etc/issue -p wa -k system-locale -w /etc/issue -p wa -k system-locale
-w /etc/issue.net -p wa -k system-locale -w /etc/issue.net -p wa -k system-locale
-w /etc/hosts -p wa -k system-locale -w /etc/hosts -p wa -k system-locale
-w /etc/hostname -p wa -k system-locale
-w /etc/sysconfig/network -p wa -k system-locale -w /etc/sysconfig/network -p wa -k system-locale
-w /etc/sysconfig/network-scripts -p wa -k system-locale -w /etc/sysconfig/network-scripts -p wa -k system-locale
-w /etc/NetworkManager -p wa -k system-locale
{% endif %} {% endif %}
{% if rhel9cis_rule_6_3_3_6 %} {% if rhel9cis_rule_6_3_3_6 %}
{% for proc in discovered_priv_procs.stdout_lines -%} {% for proc in discovered_priv_procs.stdout_lines -%}

View file

@ -7,10 +7,16 @@ rhel9cis_allowed_crypto_policies:
- 'FUTURE' - 'FUTURE'
- 'FIPS' - 'FIPS'
# Following is left blank for ability to build string
rhel9cis_crypto_policy_module: ''
# Do not adjust these are recognized as part of the CIS benchmark and used during testing
rhel9cis_allowed_crypto_policies_modules: rhel9cis_allowed_crypto_policies_modules:
# Recognized by CIS as possible extra options
- 'OSPP' - 'OSPP'
- 'AD-SUPPORT' - 'AD-SUPPORT'
- 'AD-SUPPORT-LEGACY' - 'AD-SUPPORT-LEGACY'
# The following are already included in 1.6.x controls
- 'NO-SHA1' - 'NO-SHA1'
- 'NO-SSHCBC' - 'NO-SSHCBC'
- 'NO-SSHETM' - 'NO-SSHETM'