Signed-off-by: Frederick Witty <frederick.witty@gotyto.com>
This commit is contained in:
Frederick Witty 2026-02-10 16:01:05 -05:00
parent 2863be6c02
commit 11becb32c5
No known key found for this signature in database
GPG key ID: 0CFA99C02DE4D8C3
17 changed files with 132 additions and 58 deletions

View file

@ -4,5 +4,6 @@ quiet: true
skip_list:
- 'package-latest'
- 'risky-shell-pipe'
- 'var-naming[read-only]'
use_default_rules: true
verbosity: 0

View file

@ -1,5 +1,29 @@
# Changes to RHEL9CIS
## 2.0.5 - Based on CIS v2.0.0
- QA Fixes
- Added rhel9cis_uses_root variable definition for 5.4.2.5 root PATH integrity task
- fixed spelling and grammar across defaults/main.yml, Changelog.md, README.md, tasks/main.yml, and vars/main.yml
- Fixed incorrect product reference in vars/main.yml comment (ubtu24cis -> rhel9cis)
- Fixed broken Changelog link in README.md (case mismatch)
- Added var-naming[read-only] to ansible-lint skip list for molecule files
- Bootloader password logic updated with salt and hash options
- Added passlib dependency documentation for bootloader password hash
- Updated company title
- Tidied up comments and variables for bootloader password
- Removed scheduled tasks
- Fixed typo thanks to Eugene @Frequentis
- Unused variable audit: wired up all unused variables, removed legacy references
- Updated chrony template to use rhel9cis_chrony_server_makestep, rtcsync, and minsources variables instead of hardcoded values
- Wired up rhel9cis_authselect_custom_profile_create toggle in authselect profile creation task
- Fixed task 5.3.3.2.7/5.3.3.2.8 mislabeling: separated password quality enforce and root enforce into correct tasks
- Wired up audit_capture_files_dir in audit_only workflow for file capture to control node
- Clarified rhel9cis_root_unlock_time documentation for commented-out alternative usage
- Removed legacy rhel9cis_rule_1_1_10 from molecule converge files and is_container.yml
- Fixed wrong variable name rhel9cis_unowned_group to rhel9cis_ungrouped_group in tasks/section_7/cis_7.1.x.yml
- Added rhel9cis_install_network_manager toggle to 3.1.2 wireless interfaces task
## 2.0.4 - Based on CIS v2.0.0
addressed issue #419, thank you @aaronk1
@ -17,7 +41,7 @@ Audit improvements and max-concurrent option added
Benchmark version variable in audit template
fixed typo thanks to @fragglexarmy #393
fixed typo thanks to @trumbaut #397 & #399
updated auditd template to be 2.19 complaint
updated auditd template to be 2.19 compliant
PR345 thanks to thulium-drake boot password hash - if used needs passlib module
tidy up tags on tasks/main.yml
@ -88,7 +112,7 @@ tidy up tags on tasks/main.yml
- updated controls 6.2.10-6.2.14
- audit
- steps moved to prelim
- update to coipy and archive logic and variables
- update to copy and archive logic and variables
- removed vars not used
- updated quotes used in mode tasks
- pre-commit update
@ -122,7 +146,7 @@ tidy up tags on tasks/main.yml
- lint updates
- .secrets updated
- file mode quoted
- updated 5.6.5 thansk to feedback from S!ghs on discord community
- updated 5.6.5 thanks to feedback from S!ghs on discord community
## 1.1.1 - Based on CIS v1.0.0
@ -154,7 +178,7 @@ tidy up tags on tasks/main.yml
## 1.0.10
- [#72](https://github.com/ansible-lockdown/RHEL9-CIS/issues/72)
- Only run check when paybook user not a superuser
- Only run check when playbook user not a superuser
- fix for 5.5.3 thanks to @nrg-fv
## 1.0.9
@ -226,7 +250,7 @@ Jan-2023 release
- updated ansible minimum to 2.10
- Lint file updates and improvements
- auditd now shows diff ater initial template added
- auditd now shows diff after initial template added
- many control rewritten
- Many controls moved ID references
- Audit updates aligned
@ -251,7 +275,7 @@ Jan-2023 release
- #209 5.6.5 rewrite umask settings
- #220 tidy up and align variables
- #226 Thanks to Thulium-Drake
-Extended the auditd config required value for auditd space left percentage (not part of CIS Benchmark but required fopr auditd to run correctly in some cases)
-Extended the auditd config required value for auditd space left percentage (not part of CIS Benchmark but required for auditd to run correctly in some cases)
- #227 thanks to OscarElits
- chrony files now RH expected locations
@ -291,9 +315,9 @@ Jan-2023 release
- not all controls work with rhel8 releases any longer
- selinux disabled 1.6.1.4
- logrotate - 4.3.x
- updated to rhel8cis v2.0 benchamrk requirements
- updated to rhel8cis v2.0 benchmark requirements
- removed iptables firewall controls (not valid on rhel9)
- added more to logrotate 4.3.x - sure to logrotate now a seperate package
- added more to logrotate 4.3.x - sure to logrotate now a separate package
- grub path now standard to /boot/grub2/grub.cfg
- 1.6.1.4 from rh8 removed as selinux.cfg doesnt disable selinux any longer
- workflow update
@ -312,7 +336,7 @@ args:
```
- update boolean values to true/false
- 3.4.2 improved checks for p[ackage presence
- 3.4.2 improved checks for package presence
- changed to assert for OS/release and ansible version
## Initial

View file

@ -84,16 +84,16 @@ This role **will make changes to the system** which may have unintended conseque
## Coming From A Previous Release ⏪
CIS release always contains changes, it is highly recommended to review the new references and available variables. This have changed significantly since ansible-lockdown initial release.
CIS release always contains changes, it is highly recommended to review the new references and available variables. These have changed significantly since ansible-lockdown initial release.
This is now compatible with python3 if it is found to be the default interpreter. This does come with pre-requisites which it configures the system accordingly.
Further details can be seen in the [Changelog](./ChangeLog.md)
Further details can be seen in the [Changelog](./Changelog.md)
---
## Matching a security Level for CIS
It is possible to to only run level 1 or level 2 controls for CIS.
It is possible to only run level 1 or level 2 controls for CIS.
This is managed using tags:
- level1-server
@ -101,7 +101,7 @@ This is managed using tags:
- level2-server
- level2-workstation
The control found in defaults main also need to reflect this as this control the testing that takes place if you are using the audit component.
The controls found in defaults/main.yml also need to reflect this, as they control the testing that takes place if you are using the audit component.
---
## Requirements ✅

View file

@ -1,6 +1,6 @@
---
# defaults file for rhel9-cis
# defaults file for RHEL9-CIS
# WARNING:
# These values may be overridden by other vars-setting options(e.g. like the below 'container_vars_file'), as explained here:
# https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable
@ -63,7 +63,7 @@ benchmark: RHEL9-CIS
# System will reboot if false, can give better audit results
skip_reboot: true
# default value will change to true but wont reboot if not enabled but will error
# default value will change to true but won't reboot if not enabled but will error
change_requires_reboot: false
###
@ -93,7 +93,7 @@ audit_capture_files_dir: /some/location to copy to on control node
# How to retrieve audit binary
# Options are copy or download - detailed settings at the bottom of this file
# you will need to access to either github or the file already downloaded
# you will need access to either github or the file already downloaded
get_audit_binary_method: download
## if get_audit_binary_method - copy the following needs to be updated for your environment
@ -387,7 +387,7 @@ rhel9cis_rule_5_3_3_2_6: true
rhel9cis_rule_5_3_3_2_7: true
rhel9cis_rule_5_3_3_2_8: true
# 5.3.3.3 Configure pam_pwhistory module
# This are added as part of 5.3.2.4 using jinja2 template
# These are added as part of 5.3.2.4 using jinja2 template
rhel9cis_rule_5_3_3_3_1: true
rhel9cis_rule_5_3_3_3_2: true
rhel9cis_rule_5_3_3_3_3: true
@ -522,7 +522,7 @@ rhel9cis_rule_7_2_9: true
## Ability to enable debug on mounts to assist in troubleshooting
# 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 are passed to the handler to set the mount point for the controls in section1.
rhel9cis_debug_mount_data: false
## Control 1.1.2
@ -569,9 +569,9 @@ rhel9cis_selinux_enforce: enforcing
# This variable governs whether a bootloader password should be set in '/boot/grub2/user.cfg' file.
rhel9cis_set_boot_pass: false
################### bootloader password #####################################
################### bootloader password ############################################################
#
# Two options for for setting the bootloader password
# Two options for setting the bootloader password
#
# Option 1: Set the bootloader password and salt requires the passlib Python module
# to be available on the Ansible controller.
@ -592,7 +592,7 @@ rhel9cis_bootloader_password: 'password' # pragma: allowlist secret
rhel9cis_bootloader_password_hash: 'grub.pbkdf2.sha512.changethispassword' # pragma: allowlist secret
####################################################
######################################################################################################
## Controls 1.6.x and Controls 5.1.x
# This variable governs if current Ansible role should manage system-wide crypto policy.
@ -614,7 +614,7 @@ rhel9cis_additional_crypto_policy_module: ''
# - 1.7.1 - Ensure message of the day is configured properly
# - 1.7.2 - Ensure local login warning banner is configured properly
# - 1.7.3 - Ensure remote login warning banner is configured properly
# This variable stores the content for the Warning Banner(relevant for issue, issue.net, motd).
# This variable stores the content for the Warning Banner(relevant for issue, issue.net, motd).
rhel9cis_warning_banner: Authorized users only. All activity may be monitored and reported.
# End Banner
@ -850,7 +850,7 @@ rhel9cis_sshd_clientalivecountmax: 3
rhel9cis_sshd_clientaliveinterval: 15
## Control 5.1.12 - disable forwarding
# By Default this will also disablex11 forwarding
# By Default this will also disable X11 forwarding
# set 'yes' if x11 is required this can be changed to run in /etc/ssh/ssh_config.d/50-redhat.conf
rhel9cis_sshd_x11forwarding: 'no'
@ -892,7 +892,7 @@ rhel9cis_ssh_maxsessions: 4
# This variable defines the path and file name of the sudo log file.
rhel9cis_sudolog_location: "/var/log/sudo.log"
## Control 5.2.x -Ensure sudo authentication timeout is configured correctly
## Control 5.2.x - Ensure sudo authentication timeout is configured correctly
# This variable sets the duration (in minutes) during which a user's authentication credentials
# are cached after successfully authenticating using "sudo". This allows the user to execute
# multiple commands with elevated privileges without needing to re-enter their password for each
@ -947,20 +947,37 @@ rhel9cis_authselect_default_profile_to_copy: "sssd --symlink-meta"
# - 5.3.3.1.1
# This variable sets the amount of tries a password can be entered, before a user is locked.
rhel9cis_pam_faillock_deny: 5
# - 5.3.3.1.2
# This variable sets the amount of time a user will be unlocked after the max amount of
# password failures.
# password failures.
rhel9cis_pam_faillock_unlock_time: 900
# This variable represents the number of password change cycles, after which
# an user can re-use a password.
# CIS requires a value of 5 or more.
# 5.3.3.1.3 Locking even deny root or root unlock times
# rhel9cis_pamroot_lock_option options are
# even_deny_root
# root_unlock_time = {{ rhel9cis_root_unlock_time }}
rhel9cis_root_unlock_time: 60
#####################################################################################################################
# 5.3.3.1.3 | Ensure pam_faillock is configured - root account lockout behavior
#
# Controls how root is handled when the failed login threshold is reached.
#################### Two mutually exclusive options #################################################################
#
# -> even_deny_root : Lock root just like any other account
# -> root_unlock_time = <n> : Lock root but auto-unlock after <n> seconds
#
# Note: The default value is set to 'even_deny_root' to align with the CIS Benchmark recommendation of locking root
# identically to regular users when the failed login threshold is reached. If you prefer to have root auto-unlock
# after a specified time, set 'rhel9cis_pamroot_lock_option' to "root_unlock_time = {{ rhel9cis_root_unlock_time }}"
# and adjust 'rhel9cis_root_unlock_time' as needed.
#
# Set ONE of the following:
#
# Option 1: root is locked identically to regular users when the failed login threshold is reached
rhel9cis_pamroot_lock_option: even_deny_root
# Option 2: root is locked but auto-unlocks after the specified seconds.
# Seconds before root is automatically unlocked (only used when rhel9cis_pamroot_lock_option includes root_unlock_time)
rhel9cis_root_unlock_time: 60
# rhel9cis_pamroot_lock_option: "root_unlock_time = {{ rhel9cis_root_unlock_time }}"
#
########################################################################################################################
# 5.3.3.2.1 - password difok
rhel9cis_passwd_difok_file: etc/security/pwquality.conf.d/50-pwdifok.conf # pragma: allowlist secret
@ -995,12 +1012,9 @@ rhel9cis_passwd_maxsequence_value: 3
rhel9cis_passwd_dictcheck_file: etc/security/pwquality.conf.d/50-pwdictcheck.conf # pragma: allowlist secret
rhel9cis_passwd_dictcheck_value: 1
# 5.3.3.2.7 - password quality enforce
# 5.3.3.2.7 - Ensure password quality is enforced for the root user
rhel9cis_passwd_quality_enforce_file: etc/security/pwquality.conf.d/50-pwquality_enforce.conf # pragma: allowlist secret
rhel9cis_passwd_quality_enforce_value: 1
# 5.3.3.2.8 - password quality enforce for root included with 5.3.3.2.7
rhel9cis_passwd_quality_enforce_root_file: etc/security/pwquality.conf.d/50-pwroot.conf # pragma: allowlist secret
rhel9cis_passwd_quality_enforce_root_value: enforce_for_root # pragma: allowlist secret
# PWhistory
@ -1038,7 +1052,7 @@ rhel9cis_force_user_maxdays: false
# This can break current connecting user access
rhel9cis_force_user_mindays: false
## 5.4.1.x Allow the forcing of of number of days before warning users of password expiry
## 5.4.1.x Allow the forcing of number of days before warning users of password expiry
# This can break current connecting user access
rhel9cis_force_user_warnage: false
@ -1048,6 +1062,15 @@ rhel9cis_force_user_warnage: false
rhel9cis_futurepwchgdate_autofix: true
# 5.4.2.x
## 5.4.2.5 Root user used
# Root by default is not used unless setup by user
# The role will only run certain commands if set to true
# This allows the ability to skip tasks that may cause an issue
# With the understanding root has full access
rhel9cis_uses_root: false
## 5.4.2.6 - Ensure root home directory permissions are 750 or more restrictive
rhel9cis_root_umask: '0027' # 0027 or more restrictive
## Control 5.4.2.7 - Ensure system accounts are secured | Set nologin
@ -1064,7 +1087,7 @@ rhel9cis_shell_session_timeout: 900
# This variable specifies the path of the timeout setting file.
# (TMOUT setting can be set in multiple files, but only one is required for the
# rule to pass. Options are:
# - a file in `/etc/profile.d/` ending in `.s`,
# - a file in `/etc/profile.d/` ending in `.sh`,
# - `/etc/profile`, or
# - `/etc/bash.bashrc`.
rhel9cis_shell_session_file: /etc/profile.d/tmout.sh
@ -1107,7 +1130,7 @@ rhel9cis_aide_db_file_age: 1w
# If aide already setup this forces a new DB to be created
rhel9cis_aide_db_recreate: false
# allows to change db file, not config need to be adjusted too
# allows changing the db file; note the config needs to be adjusted too
rhel9cis_aide_db_file: /var/lib/aide/aide.db.gz
## Control 6.1.2 AIDE cron settings
@ -1138,12 +1161,12 @@ rhel9cis_aide_cron:
# This variable governs the day of the month when the AIDE cronjob is run.
# `*` signifies that the job is run on all days; furthermore, specific days
# can be given in the range `1-31`; several days can be concatenated with a comma.
# The specified day(s) can must be in the range `1-31`.
# The specified day(s) must be in the range `1-31`.
aide_day: '*'
# This variable governs months when the AIDE cronjob is run.
# `*` signifies that the job is run in every month; furthermore, specific months
# can be given in the range `1-12`; several months can be concatenated with commas.
# The specified month(s) can must be in the range `1-12`.
# The specified month(s) must be in the range `1-12`.
aide_month: '*'
# This variable governs the weekdays, when the AIDE cronjob is run.
# `*` signifies that the job is run on all weekdays; furthermore, specific weekdays
@ -1185,7 +1208,7 @@ rhel9cis_journald_runtimekeepfree: 100G
# Current variable governs the settings for log retention(how long the log files will be kept).
# Thus, it specifies the maximum time to store entries in a single journal
# file before rotating to the next one. Set to 0 to turn off this feature.
# The given values is interpreted as seconds, unless suffixed with the units
# The given value is interpreted as seconds, unless suffixed with the units
# `year`, `month`, `week`, `day`, `h` or `m` to override the default time unit of seconds.
# Values are Xm, Xh, Xday, Xweek, Xmonth, Xyear, for example 2week is two weeks
# ATTENTION: Uncomment the keyword below when values are set!

View file

@ -10,7 +10,6 @@
system_is_container: true
rhel9cis_selinux_disable: true
rhel9cis_rule_5_2_4: false
rhel9cis_rule_1_1_10: false
rhel9cis_firewall: "none"
rhel9cis_rule_4_1_1_1: false
rhel9cis_rule_4_1_1_2: false

View file

@ -11,7 +11,6 @@
rhel9cis_selinux_disable: true
role_name: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}"
rhel9cis_rule_5_3_4: false
rhel9cis_rule_1_1_10: false
rhel9cis_rsyslog_ansiblemanaged: false
rhel9cis_rule_3_4_1_3: false
rhel9cis_rule_3_4_1_4: false

View file

@ -7,6 +7,30 @@
ansible.builtin.import_tasks:
file: fetch_audit_output.yml
- name: Audit_only | Capture audit files to control node
when:
- audit_only
- audit_capture_files_dir is defined
- audit_capture_files_dir | length > 0
block:
- name: Audit_only | Ensure capture directory exists
ansible.builtin.file:
path: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}"
state: directory
mode: 'u=rwx,go=rx'
become: false
delegate_to: localhost
- name: Audit_only | Copy audit files to capture directory
ansible.builtin.fetch:
src: "{{ item }}"
dest: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}/"
flat: true
failed_when: false
loop:
- "{{ pre_audit_outfile }}"
- "{{ post_audit_outfile }}"
- name: Audit_only | Show Audit Summary
when: audit_only
ansible.builtin.debug:

View file

@ -97,7 +97,7 @@
or
(ansible_env.SUDO_USER in rhel9cis_sudoers_exclude_nopasswd_list)
)
fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_env.SUDO_USER }} has no password set or or the user is not included in the exception list for rule 5.2.4 - It can break access"
fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_env.SUDO_USER }} has no password set or the user is not included in the exception list for rule 5.2.4 - It can break access"
success_msg: "You have a password set for the {{ ansible_env.SUDO_USER }} user or the user is included in the exception list for rule 5.2.4"
- name: "Check account is not locked for {{ ansible_env.SUDO_USER }} | Assert local account not locked" # noqa name[template]

View file

@ -221,6 +221,7 @@
- name: "PRELIM | PATCH | Install Network-Manager | if wireless adapter present"
when:
- rhel9cis_install_network_manager
- discover_wireless_adapters.rc == 0
- "'NetworkManager' not in ansible_facts.packages"
ansible.builtin.package:

View file

@ -14,7 +14,9 @@
- rule_5.3.2.1
block:
- name: "5.3.2.1 | PATCH | Ensure active authselect profile includes pam modules | Create custom profiles"
when: rhel9cis_authselect_custom_profile_name not in prelim_authselect_profile_list.stdout
when:
- rhel9cis_authselect_custom_profile_create
- rhel9cis_authselect_custom_profile_name not in prelim_authselect_profile_list.stdout
ansible.builtin.command: "/usr/bin/authselect create-profile {{ rhel9cis_authselect_custom_profile_name }} -b {{ rhel9cis_authselect_default_profile_to_copy }}"
changed_when: false
args:

View file

@ -340,7 +340,7 @@
- system
notify: Authselect update
- name: "5.3.3.2.7 | PATCH | Ensure password quality is enforced for the root user"
- name: "5.3.3.2.7 | PATCH | Ensure password quality checking is enforced"
when: rhel9cis_rule_5_3_3_2_7
tags:
- level1-server
@ -350,8 +350,8 @@
- NIST800-53R5_IA-5
- pam
ansible.builtin.template:
src: "{{ rhel9cis_passwd_quality_enforce_root_file }}.j2"
dest: "/{{ rhel9cis_passwd_quality_enforce_root_file }}"
src: "{{ rhel9cis_passwd_quality_enforce_file }}.j2"
dest: "/{{ rhel9cis_passwd_quality_enforce_file }}"
owner: root
group: root
mode: 'o-rwx'

View file

@ -179,7 +179,7 @@
- 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
- (item != 'root') and (not rhel9cis_uses_root)
- (item != 'root') and (not rhel9cis_uses_root )
ansible.builtin.file:
path: "{{ item.stat.path }}"
state: directory

View file

@ -254,7 +254,7 @@
ansible.builtin.file:
path: "{{ item }}"
owner: "{{ rhel9cis_unowned_owner }}"
group: "{{ rhel9cis_unowned_group }}"
group: "{{ rhel9cis_ungrouped_group }}"
with_items:
- "{{ discovered_unowned_files_flatten }}"

View file

@ -11,17 +11,19 @@ driftfile /var/lib/chrony/drift
# Allow the system clock to be stepped in the first three updates
# if its offset is larger than 1 second.
makestep 1.0 3
makestep {{ rhel9cis_chrony_server_makestep }}
{% if rhel9cis_chrony_server_rtcsync %}
# Enable kernel synchronization of the real-time clock (RTC).
rtcsync
{% endif %}
# Enable hardware timestamping on all interfaces that support it.
#hwtimestamp *
# Increase the minimum number of selectable sources required to adjust
# the system clock.
#minsources 2
minsources {{ rhel9cis_chrony_server_minsources }}
# Allow NTP client access from local network.
#allow 192.168.0.0/16

View file

@ -1,3 +1,3 @@
# CIS Configurations
# 5.3.3.2.8 Ensure password quality is enforced for the root user
# 5.3.3.2.7 Ensure password quality is enforced for the root user
{{ rhel9cis_passwd_quality_enforce_root_value }}

View file

@ -57,7 +57,6 @@ rhel9cis_rule_1_1_6: false
rhel9cis_rule_1_1_7: false
rhel9cis_rule_1_1_8: false
rhel9cis_rule_1_1_9: false
rhel9cis_rule_1_1_10: false
# /var/log
rhel9cis_rule_1_1_11: false
# /var/log/audit

View file

@ -41,7 +41,7 @@ gpg_key_package: "{{ ansible_facts.distribution | lower }}-gpg-keys"
## Controls 6.3.3.x - Audit template
# This variable is set to true by tasks 6.3.3.1 to 6.3.3.20. As a result, the
# audit settings are overwritten with the role's template. In order to exclude
# specific rules, you must set the variable of form `ubtu24cis_rule_6_3_3_x` above
# specific rules, you must set the variable of form `rhel9cis_rule_6_3_3_x` above
# to `false`.
update_audit_template: false
@ -52,7 +52,7 @@ update_audit_template: false
# system_is_container the true. Otherwise, the default value
# 'false' is left unchanged.
system_is_container: false
# The filename of the existing yml file in role's 'vars/' sub-directory
# The filename of the existing yml file in role's 'vars/' sub-directory
# to be used for managing the role-behavior when a container was detected:
# (de)activating rules or for other tasks(e.g. disabling Selinux or a specific
# firewall-type).