diff --git a/defaults/main.yml b/defaults/main.yml index 2029bd4..04f8f71 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -35,10 +35,11 @@ rhel9cis_disruption_high: false # If you do not want the tasks from that section to get executed you simply set the variable to "false". rhel9cis_section1: true rhel9cis_section2: true -rhel9cis_section3: false -rhel9cis_section4: false -rhel9cis_section5: false -rhel9cis_section6: false +rhel9cis_section3: true +rhel9cis_section4: true +rhel9cis_section5: true +rhel9cis_section6: true +rhel9cis_section7: true # This is used for audit purposes to run only specific level use the tags # e.g. @@ -343,6 +344,7 @@ rhel9cis_rule_5_1_18: true rhel9cis_rule_5_1_19: true rhel9cis_rule_5_1_20: true rhel9cis_rule_5_1_21: true +rhel9cis_rule_5_1_22: true ## 5.2 Configure Privilege Escalation rhel9cis_rule_5_2_1: true rhel9cis_rule_5_2_2: true @@ -360,6 +362,7 @@ rhel9cis_rule_5_3_2_1: true rhel9cis_rule_5_3_2_2: true rhel9cis_rule_5_3_2_3: true rhel9cis_rule_5_3_2_4: true +rhel9cis_rule_5_3_2_5: true # 5.3.3.1 Configure pam_faillock module rhel9cis_rule_5_3_3_1_1: true rhel9cis_rule_5_3_3_1_2: true @@ -635,6 +638,8 @@ rhel9cis_chrony_server_minsources: 2 # Mask # - false - leaves service in current status # - true - sets service name to masked +# +# Setting both Service and Mask to false will remove the package if exists rhel9cis_autofs_services: false rhel9cis_autofs_mask: true rhel9cis_avahi_server: false @@ -696,13 +701,19 @@ rhel9cis_tftp_client: false # Mask # - false - leaves service in current status # - true - sets service name to masked +# +# Setting both Service and Mask to false will remove the package if exists +# rhel9cis_bluetooth_service: false -rhel9cis_bluetooth_mask: true +rhel9cis_bluetooth_mask: false ## 3.1 IPv6 requirement toggle # This variable governs whether ipv6 is enabled or disabled. rhel9cis_ipv6_required: true +## 3.1.2 wireless network requirements +# if wireless adapetr found allow network manager to be installed +rhel9cis_install_network_manager: false # 3.3 System network parameters (host only OR host and router) # This variable governs whether specific CIS rules # concerned with acceptance and routing of packages are skipped. @@ -766,7 +777,7 @@ rhel9cis_sshd_allowusers: "{% if ansible_facts.user_id != 'root' %}{{ ansible_fa # (String) This variable, if specified, configures a list of GROUP name patterns, separated by spaces, to allow SSH access # for users whose primary group or supplementary group list matches one of the patterns. This is done # by setting the value of `AllowGroups` option in `/etc/ssh/sshd_config` file. -# rhel9cis_sshd_allowgroups: "wheel" +rhel9cis_sshd_allowgroups: "" # This variable, if specified, configures a list of USER name patterns, separated by spaces, to prevent SSH access # for users whose user name matches one of the patterns. This is done @@ -818,7 +829,7 @@ rhel9cis_ssh_loglevel: INFO # number, error messages will be written to the syslog file detailing the login failure. rhel9cis_ssh_maxauthtries: '4' -## Control 5.1.7 MaxStartups +## Control 5.1.17 MaxStartups # The MaxStartups parameter specifies the maximum number of concurrent unauthenticated connections to the SSH daemon. rhel9cis_ssh_maxstartups: '10:30:60' @@ -866,53 +877,62 @@ rhel9cis_authselect_pkg_update: false # NOTE the risks if system is using SSSD # - 5.5.3 - Ensure password reuse is limited # - 5.5.4 - Ensure password hashing algorithm is SHA-512 # - 5.4.2 - Ensure authselect includes with-faillock -rhel9cis_pam_faillock: - # - 5.3.3.1.1 - # This variable sets the amount of tries a password can be entered, before a user is locked. - 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. - 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. - interval: 900 - root_unlock_time: 60 - # Choose options below for root options - root_option: even_deny_root - # root_option: "root_unlock_time = {{ root_unlock_time }}" +# - 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. +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 +rhel9cis_pamroot_lock_option: even_deny_root +# rhel9cis_pamroot_lock_option: "root_unlock_time = {{ rhel9cis_root_unlock_time }}" -## Control 5.3.3.2.x - Ensure password creation requirements are configured - PAM -rhel9cis_pam_password: - # - 5.3.3.2.1 - # The pwquality difok option sets the number of characters in a password that must not - # be present in the old password. - difok: 2 - # - 5.3.3.2.2 - # minlen - Minimum acceptable size for the new password (plus one if credits are not - # disabled which is the default). Cannot be set to lower value than 6. - minlen: 14 - # - 5.3.3.2.3 - # Password complexity can be set through - # This variable set password complexity,the minimum number of - # character types that must be used (i.e., uppercase, lowercase, digits, other) - # Set to 2, passwords cannot have all lower/upper case. - # Set to 3, passwords needs numbers. - # set to 4, passwords will have to include all four types of characters. - minclass: 4 - # - 5.3.3.2.4 - # The pwquality maxrepeat option sets the maximum number of allowed same - # consecutive characters in a new password. - maxrepeat: 3 - # - 5.3.3.2.5 - # The pwquality maxsequence option sets the maximum length of monotonic character - # sequences in the new password. Examples of such sequence are 12345 or fedcb. The - # check is disabled if the value is 0. - maxseq: 3 +# 5.3.3.2.1 - password difok +rhel9cis_passwd_difok_file: etc/security/pwquality.conf.d/50-pwdifok.conf # pragma: allowlist secret +rhel9cis_passwd_difok_value: 2 + +# 5.3.3.2.2 - password minlength +rhel9cis_passwd_minlen_file: etc/security/pwquality.conf.d/50-pwlength.conf # pragma: allowlist secret +rhel9cis_passwd_minlen_value: 14 + +# 5.3.3.2.3 - password complex +rhel9cis_passwd_complex_file: etc/security/pwquality.conf.d/50-pwcomplexity.conf # pragma: allowlist secret +rhel9cis_passwd_minclass: 3 +rhel9cis_passwd_dcredit: -1 +rhel9cis_passwd_ucredit: -2 +rhel9cis_passwd_ocredit: 0 +rhel9cis_passwd_lcredit: -2 + +# 5.3.3.2.4 - password maxrepeat +rhel9cis_passwd_maxrepeat_file: etc/security/pwquality.conf.d/50-pwrepeat.conf # pragma: allowlist secret +rhel9cis_passwd_maxrepeat_value: 3 + +# 5.3.3.2.5 - password maxsequence +rhel9cis_passwd_maxsequence_file: etc/security/pwquality.conf.d/50-pwmaxsequence.conf # pragma: allowlist secret +rhel9cis_passwd_maxsequence_value: 3 + +# 5.3.3.2.6 - password dictcheck +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 +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 # 5.3.3.4.x -rhel9cis_passwd_hash_algo: sha512 +rhel9cis_passwd_hash_algo: sha512 # pragma: allowlist secret ## Section 5.4.1.x: Shadow Password Suite Parameters rhel9cis_pass: @@ -952,33 +972,26 @@ rhel9cis_force_user_warnage: false # to 'false' will just display users in violation, while 'true' will expire those users passwords. rhel9cis_futurepwchgdate_autofix: true -## Section 5.4 - Configure authselect: Custom authselect profile settings(name, profile to customize, options) -## Controls: -# - 5.4.1 - Ensure custom authselect profile is used('custom_profile_name', 'default_file_to_copy' subsettings) -# - 5.4.2 - Ensure authselect includes with-faillock | with auth select profile('custom_profile_name') -# Settings in place now will fail, they are placeholders from the control example. Due to the way many multiple -# options and ways to configure this control needs to be enabled and settings adjusted to minimise risk. -rhel9cis_authselect: - # This variable configures the name of the custom profile to be created and selected. - custom_profile_name: custom-profile - # This variable configures the ID of the existing profile that should be used as a base for the new profile. - default_file_to_copy: "sssd --symlink-meta" - options: with-sudo with-faillock without-nullok with-pwhistory - -## Control 5.4.1 - Ensure custom authselect profile is used -# This variable governs if an authselect custom profile should be automatically created, by copying and -# customizing one of the default profiles. The default profiles include: sssd, winbind, or the nis. This profile can then be -# customized to follow site specific requirements. -rhel9cis_authselect_custom_profile_create: false - -## Control 5.4.2 - Ensure authselect includes with-faillock | Create custom profiles -# This variable governs if the existing custom profile should be selected(Note: please keep in mind that all future updates -# to the PAM templates and meta files in the original profile will be reflected in your custom profile, too.) -rhel9cis_authselect_custom_profile_select: false - # 5.4.2.x rhel9cis_root_umask: '0027' # 0027 or more restrictive +## Control 5.4.3.2 - Configuring user shell timeout +# This dictionary is related to ensuring the rule about user shell timeout +# This variable represents the amount of seconds a command or process is allowed to +# run before being forcefully terminated. +# CIS requires a value of at most 900 seconds. +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`, +# - `/etc/profile`, or +# - `/etc/bash.bashrc`. +rhel9cis_shell_session_file: /etc/profile.d/tmout.sh + +## Control 5.4.3.2 bash umask +rhel9cis_bash_umask: '0027' # 0027 or more restrictive + ### Controls: # - 5.6.2 - Ensure system accounts are secured # - 6.2.10 - Ensure local interactive user home directories exist @@ -991,29 +1004,13 @@ rhel9cis_discover_int_uid: true # been set to `true`. min_int_uid: 1000 ### Controls: -# - 6.2.10 - Ensure local interactive user home directories exist -# - 6.2.11 - Ensure local interactive users own their home directories +# - Ensure local interactive user home directories exist +# - Ensure local interactive users own their home directories # 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 # been set to `true`. max_int_uid: 65533 -## Control 5.6.3 - Ensure default user shell timeout is 900 seconds or less -# Session timeout setting file (TMOUT setting can be set in multiple files) -# Timeout value is in seconds. (60 seconds * 10 = 600) -rhel9cis_shell_session_timeout: - # 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`, - # - `/etc/profile`, or - # - `/etc/bash.bashrc`. - file: /etc/profile.d/tmout.sh - # This variable represents the amount of seconds a command or process is allowed to - # run before being forcefully terminated. - # CIS requires a value of at most 900 seconds. - timeout: 600 - ## Section6 vars ## Control 6.1.1 - allow aide to be configured @@ -1118,23 +1115,6 @@ rhel9cis_remote_log_retrycount: 100 # of rsyslog forwarding must be enabled('rhel9cis_remote_log_server: true'). rhel9cis_remote_log_queuesize: 1000 -## Control 6.2.3.8 rsyslog log rotate option -# These variable allow you to change accordint to site policy settings -# When to rotate options: hourly, daily, weekly, monthly, yearly -rhel9cis_rsyslog_logrotate_rotated: weekly -# Number of backlog files to keep -rhel9cis_rsyslog_logrotate_keep: 4 -# compress file once rotated, false will not compress -rhel9cis_rsyslog_logrotate_compress: true -# If the log file is missing, go on to the next one without issuing an error message -rhel9cis_rsyslog_logrotate_missingok: -# Dont rotate file if has no contents, false will still rotate -rhel9cis_rsyslog_logrotate_notifempty: true -# rhel9cis_rsyslog_logrotate_create give the options to create permissions and ownerships -# allows create iption to be used and sets options below based on mode owner group -rhel9cis_rsyslog_logrotate_create: false -rhel9cis_rsyslog_logrotate_create_opts: 0640 root root - ## Control 6.2.2.1.2 - Ensure systemd-journal-remote is configured # 'rhel9cis_journal_upload_url' is the ip address to upload the journal entries to # URL value may specify either just the hostname or both the protocol and hostname. 'https' is the default. The port @@ -1158,7 +1138,7 @@ rhel9cis_journal_servercertificatefile: "/etc/ssl/certs/journal-upload.pem" rhel9cis_journal_trustedcertificatefile: "/etc/ssl/ca/trusted.pem" # ATTENTION: Uncomment the keyword below when values are set! -## Control 6.2.2.6 - Ensure journald log rotation is configured per site policy +## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy # Current variable configures the max amount of disk space the logs will use(thus, journal files # will not grow without bounds) # The variables below related to journald, please set these to your site specific values @@ -1166,18 +1146,18 @@ rhel9cis_journal_trustedcertificatefile: "/etc/ssl/ca/trusted.pem" # Specify values in bytes or use K, M, G, T, P, E as units for the specified sizes. # See https://www.freedesktop.org/software/systemd/man/journald.conf.html for more information. rhel9cis_journald_systemmaxuse: 10M -## Control 6.2.2.6 - Ensure journald log rotation is configured per site policy +## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy # Current variable configures the amount of disk space to keep free for other uses. rhel9cis_journald_systemkeepfree: 100G -## Control 6.2.2.6 - Ensure journald log rotation is configured per site policy +## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy # This variable configures how much disk space the journal may use up at most. # Similar with 'rhel9cis_journald_systemmaxuse', but related to runtime space. rhel9cis_journald_runtimemaxuse: 10M -## Control 6.2.2.6 - Ensure journald log rotation is configured per site policy +## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy # This variable configures the actual amount of disk space to keep free # Similar with 'rhel9cis_journald_systemkeepfree', but related to runtime space. rhel9cis_journald_runtimekeepfree: 100G -## Control 6.2.2.6 - Ensure journald log rotation is configured per site policy +## Control 6.2.1.3 - Ensure journald log rotation is configured per site policy # 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. @@ -1187,7 +1167,7 @@ rhel9cis_journald_runtimekeepfree: 100G # ATTENTION: Uncomment the keyword below when values are set! rhel9cis_journald_maxfilesec: 1month -# Control 6.3.1.3 - Ensure rhel9cis_audit_back_log_limit is sufficient +## Control 6.3.2.1 - Ensure audit_backlog_limit is sufficient # This variable represents the audit backlog limit, i.e., the maximum number of audit records that the # system can buffer in memory, if the audit subsystem is unable to process them in real-time. # Buffering in memory is useful in situations, where the audit system is overwhelmed @@ -1195,21 +1175,91 @@ rhel9cis_journald_maxfilesec: 1month # This variable should be set to a sufficient value. The CIS baseline recommends at least `8192` as value. rhel9cis_audit_back_log_limit: 8192 -## Advanced option found in auditd post and used in tempate 98_auditd_exceptions.rules.j2 +## Controls 6.3.2.x - What to do when log files fill up +## Control 6.3.2.1 - Ensure audit log storage size is configured +# This variable specifies the maximum size in MB that an audit log file can reach +# before it is archived or deleted to make space for the new audit data. +# This should be set based on your sites policy. CIS does not provide a specific value. +rhel9cis_auditd_max_log_file_size: 10 + +## Control 6.3.2.2 +# This variable determines what action the audit system should take when the maximum +# size of a log file is reached. +# The options for setting this variable are as follows: +# - `ignore`: the system does nothing when the size of a log file is full; +# - `syslog`: a message is sent to the system log indicating the problem; +# - `suspend`: the system suspends recording audit events until the log file is cleared or rotated; +# - `rotate`: the log file is rotated (archived) and a new empty log file is created; +# - `keep_logs`: the system attempts to keep as many logs as possible without violating disk space constraints. +# CIS prescribes the value `keep_logs`. +rhel9cis_auditd_max_log_file_action: keep_logs + +## Control 6.3.2.3 +# This variable determines how the system should act in case of issues with disk +# The disk_full_action parameter tells the system what action to take when no free space is available on the partition that holds the audit log files. +# Valid values are ignore, syslog, rotate, exec, suspend, single, and halt. +# +# The disk_error_action parameter tells the system what action to take when an error is detected on the partition that holds the audit log files. +# Valid values are ignore, syslog, exec, suspend, single, and halt. +# +# CIS prescribes +# disk_full_action parameter: +# Set to halt - the auditd daemon will shutdown the system when the disk partition containing the audit logs becomes full. +# Set to single - the auditd daemon will put the computer system in single user mode when the disk partition containing the audit logs becomes full. +# +# disk_error_action parameter: +# Set to halt - the auditd daemon will shutdown the system when an error is detected on the partition that holds the audit log files. +# Set to single - the auditd daemon will put the computer system in single user mode when an error is detected on the partition that holds the audit log files. +# Set to syslog - the auditd daemon will issue no more than 5 consecutive warnings to syslog when an error is detected on the partition that holds the audit log files. +rhel9cis_auditd_disk_full_action: halt +rhel9cis_auditd_disk_error_action: syslog + +# Control 6.3.2.4 +# Wait to do when space left is low. +# The space_left_action parameter tells the system what action to take when the system has detected that it is starting to get low on disk space. +# Valid values are ignore, syslog, rotate, email, exec, suspend, single, and halt. +# The admin_space_left_action parameter tells the system what action to take when the system has detected that it is low on disk space. +# Valid values are ignore, syslog, rotate, email, exec, suspend, single, and halt. +rhel9cis_auditd_space_left_action: email +rhel9cis_auditd_admin_space_left_action: halt + +# This value governs if the below extra-vars for auditd should be used by the role +rhel9cis_auditd_extra_conf_usage: false + +# 6.3.3.x allow exceptions for UID in auditd config +## Advanced option found in auditd post # This variable governs if defining user exceptions for auditd logging is acceptable. rhel9cis_allow_auditd_uid_user_exclusions: false # This variable contains a list of uids to be excluded(users whose actions are not logged by auditd) rhel9cis_auditd_uid_exclude: - 1999 +# This can be used to configure other keys in auditd.conf +# Example: +rhel9cis_auditd_extra_conf: + admin_space_left: '10%' + # Section 7 Vars -## Control 6.1.9 - Ensure no world writable files exist +# 7.1.12 Ensure no files or directories without an owner and a group exist +rhel9cis_exclude_unowned_search_path: (! -path "/run/user/*" -a ! -path "/proc/*" -a ! -path "*/containerd/*" -a ! -path "*/kubelet/pods/*" -a ! -path "*/kubelet/plugins/*" -a ! -path "/sys/fs/cgroup/memory/*" -a ! -path "/var/*/private/*") + +# Control 7.1.12 +# The value of this variable specifies the owner that will be set for unowned files and directories. +rhel9cis_unowned_owner: root +rhel9cis_ungrouped_group: root +# This variable is a toggle for enabling/disabling the automated +# setting of an owner (specified in variable `rhel9cis_unowned_owner`) +# for all unowned files and directories. +# Possible values are `true` and `false`. +rhel9cis_ownership_adjust: true + +## Control 7.1.13 +# This variable is a toggle for enabling/disabling the automated removal +# of the SUID bit from all files on all mounts. +# Possible values are `true` and `false`. +rhel9cis_suid_sgid_adjust: false + +## Control 7.1.11 - Ensure no world writable files exist # Allow ansible to adjust world-writable files. False will just display world-writable files, True will remove world-writable. rhel9cis_no_world_write_adjust: true - -## Control 6.2.16 - Ensure local interactive user dot files are not group or world writable -# This boolean variable governs if current role should follow filesystem links for changes to -# user home directory. -rhel_09_6_2_16_home_follow_symlinks: false -# thanks to @dulin-gnet and community for rhel9-cis feedback. diff --git a/tasks/section_5/cis_5.1.x.yml b/tasks/section_5/cis_5.1.x.yml index 0b4c63f..62c3af9 100644 --- a/tasks/section_5/cis_5.1.x.yml +++ b/tasks/section_5/cis_5.1.x.yml @@ -194,7 +194,7 @@ notify: Restart sshd - name: "5.1.7 | PATCH | Ensure sshd access is configured | Add line to sshd_config for denyusers" - when: "rhel9cis_sshd_denyusers'|default('') | length > 0" + when: "rhel9cis_sshd_denyusers | length > 0" ansible.builtin.lineinfile: path: "{{ rhel9_cis_sshd_config_file }}" regexp: "^DenyUsers" @@ -203,7 +203,7 @@ notify: Restart sshd - name: "5.1.7 | PATCH | Ensure sshd access is configured | Add line to sshd_config for denygroups" - when: "rhel9cis_sshd_denygroups|default('') | length > 0" + when: "rhel9cis_sshd_denygroups | length > 0" ansible.builtin.lineinfile: path: "{{ rhel9_cis_sshd_config_file }}" regexp: "^DenyGroups" @@ -500,17 +500,17 @@ - name: "5.1.22 | PATCH | Ensure SSH PAM is enabled" when: - rhel9cis_rule_5_1_22 - - NIST800-53R5_CM-1 - - NIST800-53R5_CM-2 - - NIST800-53R5_CM-6 - - NIST800-53R5_CM-7 - - NIST800-53R5_IA-5 tags: - level1-server - level1-workstation - patch - ssh - rule_5.1.22 + - NIST800-53R5_CM-1 + - NIST800-53R5_CM-2 + - NIST800-53R5_CM-6 + - NIST800-53R5_CM-7 + - NIST800-53R5_IA-5 ansible.builtin.lineinfile: path: "{{ rhel9_cis_sshd_config_file }}" regexp: ^(?i)(#|)\s*MaxStartupsUsePAM diff --git a/tasks/section_5/cis_5.3.1.x.yml b/tasks/section_5/cis_5.3.1.x.yml index 050a081..b8a5576 100644 --- a/tasks/section_5/cis_5.3.1.x.yml +++ b/tasks/section_5/cis_5.3.1.x.yml @@ -42,7 +42,7 @@ - name: "5.3.1.3 | PATCH | Ensure libpwquality is installed" when: - rhel9cis_rule_5_3_1_3 - - ansible_facts.packages['libpwquality'][0]['version'] is version('1.4.4-8', '<') + - ansible_facts.packages['libpwquality'][0]['version'] is version('1.4.4-8', '<') or "'libpwquality' not in ansible_facts.packages" tags: - level1-server diff --git a/tasks/section_5/cis_5.3.3.1.x.yml b/tasks/section_5/cis_5.3.3.1.x.yml index 67b8763..8206074 100644 --- a/tasks/section_5/cis_5.3.3.1.x.yml +++ b/tasks/section_5/cis_5.3.3.1.x.yml @@ -2,7 +2,7 @@ - name: "5.3.3.1.1 | PATCH | Ensure password failed attempts lockout is configured" when: - - rhel8cis_rule_5_3_3_1_1 + - rhel9cis_rule_5_3_3_1_1 tags: - level1-server - level1-workstation @@ -16,10 +16,12 @@ path: /etc/security/faillock.conf state: present regexp: '^(#|)\s*deny\s*=\s*\d' - line: "deny = {{ rhel8cis_pam_faillock['deny'] }}" + line: "deny = {{ rhel9cis_pam_faillock_deny }}" - - name: "5.3.3.1.1 | PATCH | Ensure password failed attempts lockout is configured | pam_files" - when: not rhel8cis_allow_authselect_updates + - name: "5.3.3.1.1 | PATCH | Ensure password failed attempts lockout is configured | remove deny from pam files NOT AuthSelect" + when: + - not rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high ansible.builtin.replace: path: "/etc/pam.d/{{ item }}-auth" regexp: ^(\s*auth\s+(requisite|required|sufficient)\s+pam_faillock\.so)(.*)\s+deny\s*=\s*\S+(.*$) @@ -28,9 +30,22 @@ - password - system + - name: "5.3.3.1.1 | PATCH | Ensure password failed attempts lockout is configured | remove deny from AuthSelect config" + when: + - rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*auth\s+(requisite|required|sufficient)\s+pam_faillock\.so)(.*)\s+deny\s*=\s*\S+(.*$) + replace: \1\2\3 + loop: + - password + - system + notify: Authselect update + - name: "5.3.3.1.2 | PATCH | Ensure password unlock time is configured" when: - - rhel8cis_rule_5_3_3_1_2 + - rhel9cis_rule_5_3_3_1_2 tags: - level1-server - level1-workstation @@ -44,10 +59,12 @@ path: /etc/security/faillock.conf state: present regexp: '^(#|)\s*unlock_time\s*=\s*\d' - line: "unlock_time = {{ rhel8cis_pam_faillock['unlock_time'] }}" + line: "unlock_time = {{ rhel9cis_pam_faillock_unlock_time }}" - - name: "5.3.3.1.2 | PATCH | Ensure password unlock time is configured | pam_files" - when: not rhel8cis_allow_authselect_updates + - name: "5.3.3.1.2 | PATCH | Ensure password unlock time is configured | remove unlock from pam files NOT AuthSelect" + when: + - rhel9cis_disruption_high + - not rhel9cis_allow_authselect_updates ansible.builtin.replace: path: "/etc/pam.d/{{ item }}-auth" regexp: ^(\s*auth\s+(requisite|required|sufficient)\s+pam_faillock\.so)(.*)\s+unlock_time\s*=\s*\S+(.*$) @@ -56,6 +73,19 @@ - password - system + - name: "5.3.3.1.2 | PATCH | Ensure password unlock time is configured | remove unlock from pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*auth\s+(requisite|required|sufficient)\s+pam_faillock\.so)(.*)\s+unlock_time\s*=\s*\S+(.*$) + replace: \1\2\3 + loop: + - password + - system + notify: Authselect update + - name: "5.3.3.1.3 | PATCH | Ensure password failed attempts lockout includes root account" when: - rhel9cis_rule_5_3_3_1_3 @@ -71,12 +101,14 @@ ansible.builtin.lineinfile: path: /etc/security/faillock.conf regexp: '^{{ rhel9cis_pamroot_lock_option }}' - line: "{{ rhel9cis_pamroot_lock_string }}" + line: "{{ rhel9cis_pamroot_lock_option }}" insertafter: '^# end of pam-auth-update config' create: true - - name: "5.3.3.1.3 | PATCH | Ensure password failed attempts lockout includes root account | pam_files" - when: not rhel9cis_allow_authselect_updates + - name: "5.3.3.1.3 | PATCH | Ensure password failed attempts lockout includes root account | remove lockout from pam files NOT AuthSelect" + when: + - rhel9cis_disruption_high + - not rhel9cis_allow_authselect_updates ansible.builtin.replace: path: "/etc/pam.d/{{ item }}-auth" regexp: ^(\s*auth\s+(requisite|required|sufficient)\s+pam_faillock\.so)(.*)\s(even_deny_root|root_unlock_time=\d*)"(\s*=\s*\d|.*)\S+(.*$) @@ -84,3 +116,16 @@ loop: - password - system + + - name: "5.3.3.1.3 | PATCH | Ensure password failed attempts lockout includes root account | remove lockout from pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*auth\s+(requisite|required|sufficient)\s+pam_faillock\.so)(.*)\s(even_deny_root|root_unlock_time=\d*)"(\s*=\s*\d|.*)\S+(.*$) + replace: \1\2\4 + loop: + - password + - system + notify: Authselect update diff --git a/tasks/section_5/cis_5.3.3.2.x.yml b/tasks/section_5/cis_5.3.3.2.x.yml index 931f867..9317326 100644 --- a/tasks/section_5/cis_5.3.3.2.x.yml +++ b/tasks/section_5/cis_5.3.3.2.x.yml @@ -14,6 +14,7 @@ - name: "5.3.3.2.1 | PATCH | Ensure password number of changed characters is configured | Remove difok from conf files except expected file" when: - item != rhel9cis_passwd_difok_file + - rhel9cis_disruption_high ansible.builtin.replace: path: "{{ item }}" regexp: 'difok\s*=\s*\d+\b' @@ -31,6 +32,31 @@ group: root mode: '0600' + - name: "5.3.3.2.1 | PATCH | Ensure password number of changed characters is configured | Remove difok from pam files Not AuthSelect" + when: + - not rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/pam.d/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\sdifok=\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + + - name: "5.3.3.2.1 | PATCH | Ensure password number of changed characters is configured | Remove difok from pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\sdifok=\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + notify: Authselect update + - name: "5.3.3.2.2 | PATCH | Ensure password length is configured" when: - rhel9cis_rule_5_3_3_2_2 @@ -45,6 +71,7 @@ - name: "5.3.3.2.2 | PATCH | Ensure minimum password length is configured | Remove minlen from conf files except expected file" when: - item != rhel9cis_passwd_minlen_file + - rhel9cis_disruption_high ansible.builtin.replace: path: "{{ item }}" regexp: 'minlen\s*=\s*\d+\b' @@ -62,6 +89,31 @@ group: root mode: '0600' + - name: "5.3.3.2.2 | PATCH | Ensure minimum password length is configured | Remove minlen from pam files NOT AuthSelect" + when: + - not rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/pam.d/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\sminlen=\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + + - name: "5.3.3.2.2 | PATCH | Ensure minimum password length is configured | Remove minlen from pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\sminlen=\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + notify: Authselect update + - name: "5.3.3.2.3 | PATCH | Ensure password complexity is configured" when: - rhel9cis_rule_5_3_3_2_3 @@ -76,6 +128,7 @@ - name: "5.3.3.2.3 | PATCH | Ensure password complexity is configured | Remove pwd complex settings from conf files except expected file" when: - item != rhel9cis_passwd_complex_file + - rhel9cis_disruption_high ansible.builtin.replace: path: "{{ item }}" regexp: '(minclass|[dulo]credit)\s*=\s*(-\d|\d+)\b' @@ -93,6 +146,31 @@ group: root mode: '0600' + - name: "5.3.3.2.3 | PATCH | Ensure password complexity is configured | Remove complexity from pam files NOT AuthSelect" + when: + - not rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/pam.d/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\s(minclass=[0-3]|[dulo]credit=[^-]\d*)(.*$) + replace: \1\2\4 + loop: + - password + - system + + - name: "5.3.3.2.3 | PATCH | Ensure password complexity is configured | Remove complexity from pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\s(minclass=[0-3]|[dulo]credit=[^-]\d*)(.*$) + replace: \1\2\4 + loop: + - password + - system + notify: Authselect update + - name: "5.3.3.2.4 | PATCH | Ensure password same consecutive characters is configured" when: - rhel9cis_rule_5_3_3_2_4 @@ -124,6 +202,31 @@ group: root mode: '0600' + - name: "5.3.3.2.4 | PATCH | Ensure password same consecutive characters is configured | Remove maxrepeat from pam files NOT AuthSelect" + when: + - not rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/pam.d/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\smaxrepeat\s*=\s*\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + + - name: "5.3.3.2.4 | PATCH | Ensure password same consecutive characters is configured | Remove maxrepeat from pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\smaxrepeat\s*=\s*\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + notify: Authselect update + - name: "5.3.3.2.5 | PATCH | Ensure password maximum sequential characters is is configured" when: - rhel9cis_rule_5_3_3_2_5 @@ -138,6 +241,7 @@ - name: "5.3.3.2.5 | PATCH | Ensure password maximum sequential characters is configured | Remove maxsequence settings from conf files except expected file" when: - item != rhel9cis_passwd_maxsequence_file + - rhel9cis_disruption_high ansible.builtin.replace: path: "{{ item }}" regexp: 'maxsequence\s*=\s*\d+\b' @@ -155,6 +259,31 @@ group: root mode: '0600' + - name: "5.3.3.2.5 | PATCH | Ensure password maximum sequential characters is configured | Remove maxsequence from pam files NOT AuthSelect" + when: + - not rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/pam.d/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\smaxsequence\s*=\s*\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + + - name: "5.3.3.2.5 | PATCH | Ensure password maximum sequential characters is configured | Remove maxsequence from pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\smaxsequence\s*=\s*\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + notify: Authselect update + - name: "5.3.3.2.6 | PATCH | Ensure password dictionary check is enabled" when: - rhel9cis_rule_5_3_3_2_6 @@ -186,6 +315,32 @@ group: root mode: '0600' + - name: "5.3.3.2.6 | PATCH | Ensure password dictionary check is enabled | Remove dictcheck from pam files NOT AuthSelect" + when: + - not rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/pam.d/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\sdictcheck\s*=\s*\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + notify: Authselect update + + - name: "5.3.3.2.6 | PATCH | Ensure password dictionary check is enabled | Remove dictcheck from pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\sdictcheck\s*=\s*\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + notify: Authselect update + - name: "5.3.3.2.7 | PATCH | Ensure password quality is enforced for the root user" when: - rhel9cis_rule_5_3_3_2_7 diff --git a/tasks/section_5/cis_5.3.3.3.x.yml b/tasks/section_5/cis_5.3.3.3.x.yml index 659ea82..ffb1bff 100644 --- a/tasks/section_5/cis_5.3.3.3.x.yml +++ b/tasks/section_5/cis_5.3.3.3.x.yml @@ -3,7 +3,6 @@ - name: "5.3.3.3.1 | PATCH | Ensure password history remember is configured" when: - rhel9cis_rule_5_3_3_3_1 - - rhel9cis_disruption_high tags: - level1-server - level1-workstation @@ -18,7 +17,9 @@ failed_when: rhel9_pwhistory_remember.rc not in [0, 1] - name: "5.3.3.3.1 | PATCH | Ensure password number of changed characters is configured | Ensure remember is set" - when: rhel9_pwhistory_remember.stdout | length > 0 + when: + - rhel9_pwhistory_remember.stdout | length > 0 + - not rhel9cis_allow_authselect_updates ansible.builtin.lineinfile: path: "/{{ rhel9cis_pam_confd_dir }}{{ rhel9cis_pam_pwhistory_file }}" regexp: ^(password\s+[^#\n\r]+\h+pam_pwhistory\.so\s+)(.*)(remember=\d+) @@ -26,6 +27,31 @@ backrefs: true notify: Pam_auth_update_pwhistory + - name: "5.3.3.3.1 | PATCH | Ensure password number of changed characters is configured | Remove remember from pam files NOT AuthSelect" + when: + - not rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/pam.d/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwhistory\.so)(.*)\sremember=\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + + - name: "5.3.3.3.1 | PATCH | Ensure password number of changed characters is configured | Remove remember from pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.replace: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwhistory\.so)(.*)\sremember=\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + notify: Authselect update + - name: "5.3.3.3.2 | PATCH | Ensure password history is enforced for the root user" when: - rhel9cis_rule_5_3_3_3_2 @@ -38,13 +64,15 @@ - pam block: - name: "5.3.3.3.2 | AUDIT | Ensure password history is enforced for the root user | Check existing files" - ansible.builtin.shell: grep -Psi -- '^\h*password\h+[^#\n\r]+\h+pam_pwhistory\.so\h+([^#\n\r]+\h+)?enforce_for_root\b' /etc/pam.d/common-password + ansible.builtin.shell: grep -Psi -- '^\h*password\h+[^#\n\r]+\h+pam_pwhistory\.so\h+([^#\n\r]+\h+)?enforce_for_root\b' /etc/pam.d/{system,password}-auth register: rhel9_pwhistory_enforce_for_root changed_when: false failed_when: rhel9_pwhistory_enforce_for_root.rc not in [0, 1] - name: "5.3.3.3.2 | PATCH | Ensure password history is enforced for the root user | Ensure remember is set" - when: rhel9_pwhistory_enforce_for_root.stdout | length > 0 + when: + - not rhel9cis_allow_authselect_updates + - rhel9_pwhistory_enforce_for_root.stdout | length > 0 ansible.builtin.lineinfile: path: "/{{ rhel9cis_pam_confd_dir }}{{ rhel9cis_pam_pwhistory_file }}" regexp: ^(password\h+[^#\n\r]+\h+pam_pwhistory\.so\h+)(.*)(enforce_for_root) @@ -64,16 +92,32 @@ - pam block: - name: "5.3.3.3.3 | AUDIT | Ensure pam_pwhistory includes use_authtok | Check existing files" - ansible.builtin.shell: grep -Psi -- '^\h*password\h+[^#\n\r]+\h+pam_pwhistory\.so\h+([^#\n\r]+\h+)?use_authtok\b' /etc/pam.d/common-password + ansible.builtin.shell: grep -Psi -- '^\h*password\h+[^#\n\r]+\h+pam_pwhistory\.so\h+([^#\n\r]+\h+)?use_authtok\b' /etc/pam.d/{system,password}-auth register: rhel9_pwhistory_use_authtok changed_when: false failed_when: rhel9_pwhistory_use_authtok.rc not in [0, 1] - name: "5.3.3.3.3 | PATCH | Ensure pam_pwhistory includes use_authtok | Ensure remember is set" - when: rhel9_pwhistory_use_authtok.stdout | length > 0 + when: + - not rhel9cis_allow_authselect_updates + - rhel9_pwhistory_use_authtok.stdout | length > 0 ansible.builtin.lineinfile: path: "/{{ rhel9cis_pam_confd_dir }}{{ rhel9cis_pam_pwhistory_file }}" regexp: ^(password\h+[^#\n\r]+\h+pam_pwhistory\.so\h+)(.*)(use_authtok) line: '\1\2\3 use_authtok' backrefs: true notify: Pam_auth_update_pwhistory + + - name: "PATCH | Ensure pam_pwhistory includes use_authtok | add authtok to pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + - rhel9cis_disruption_high + ansible.builtin.lineinfile: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwhistory\.so)(.*)\suse_authtok(.*$) + line: \1\2 use_authtok\3 + backrefs: true + loop: + - password + - system + notify: Authselect update diff --git a/tasks/section_5/cis_5.3.3.4.x.yml b/tasks/section_5/cis_5.3.3.4.x.yml index 4faedb3..89f39cc 100644 --- a/tasks/section_5/cis_5.3.3.4.x.yml +++ b/tasks/section_5/cis_5.3.3.4.x.yml @@ -18,17 +18,31 @@ register: rhel9cis_pam_nullok - name: "5.3.3.4.1 | PATCH | Ensure pam_unix does not include nullok | Ensure nullok removed" - when: rhel9cis_pam_nullok.stdout | length > 0 + when: + - rhel9cis_pam_nullok.stdout | length > 0 + - not rhel9cis_allow_authselect_updates ansible.builtin.replace: path: "{{ item }}" regexp: nullok replace: '' loop: "{{ rhel9cis_pam_nullok.stdout_lines }}" - notify: Pam_auth_update_pwunix + + - name: "5.3.3.4.1 | PATCH | Ensure password number of changed characters is configured | Remove nullok from pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + ansible.builtin.replace: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_unix\.so)(.*)\snullok(.*$) + replace: \1\2\3 + loop: + - password + - system + notify: Authselect update - name: "5.3.3.4.2 | PATCH | Ensure pam_unix does not include remember" when: - rhel9cis_rule_5_3_3_4_2 + - rhel9cis_disruption_high tags: - level1-server - level1-workstation @@ -37,22 +51,36 @@ - rule_5.3.3.4.2 block: - name: "5.3.3.4.2 | AUDIT | Ensure pam_unix does not include remember | capture state" - ansible.builtin.shell: grep -PH -- '^\h*^\h*[^#\n\r]+\h+pam_unix\.so\b' /etc/pam.d/common-{password,auth,account,session,session-noninteractive} | grep -Pv -- '\bremember=\d\b' + ansible.builtin.shell: grep -PH -- '^\h*^password\h*[^#\n\r]+\h+pam_unix\.so\b' /etc/pam.d/{password,system}-auth | grep -P -- '\bremember\b' changed_when: false failed_when: rhel9cis_pam_remember.rc not in [ 0, 1 ] register: rhel9cis_pam_remember - name: "5.3.3.4.2 | PATCH | Ensure pam_unix does not include remember | Ensure remember removed" - when: rhel9cis_pam_remember.stdout | length > 0 + when: + - not rhel9cis_allow_authselect_updates + - rhel9cis_pam_remember.stdout | length > 0 ansible.builtin.replace: path: "/{{ rhel9cis_pam_confd_dir }}{{ rhel9cis_pam_pwunix_file }}" regexp: remember=\d+ replace: '' - notify: Pam_auth_update_pwunix + + - name: "5.3.3.4.2 | PATCH | Ensure pam_unix does not include remember | Remove remember from pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + ansible.builtin.replace: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_unix\.so)(.*)\sremember\s*=\s*=\d*(.*$) + replace: \1\2\3 + loop: + - password + - system + notify: Authselect update - name: "5.3.3.4.3 | PATCH | Ensure pam_unix includes a strong password hashing algorithm" when: - rhel9cis_rule_5_3_3_4_3 + - rhel9cis_disruption_high tags: - level1-server - level1-workstation @@ -68,16 +96,31 @@ register: rhel9cis_pam_pwhash - name: "5.3.3.4.3 | PATCH | Ensure pam_unix includes a strong password hashing algorithm | Ensure hash algorithm set" - when: rhel9cis_pam_remember.stdout | length > 0 + when: + - not rhel9cis_allow_authselect_updates + - rhel9cis_pam_remember.stdout | length > 0 ansible.builtin.replace: path: "/{{ rhel9cis_pam_confd_dir }}{{ rhel9cis_pam_pwunix_file }}" regexp: "(md5|bigcrypt|sha256|blowfish|gost_yescrypt|sha512|yescrypt)" replace: '{{ rhel9cis_passwd_hash_algo }}' - notify: Pam_auth_update_pwunix + + - name: "5.3.3.4.3 | PATCH | Ensure pam_unix includes a strong password hashing algorithm | Remove remember from pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + ansible.builtin.lineinfile: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_unix\.so)(.*)(sha512|yescrypt)(.*$) + line: \1\2 {{ rhel9cis_passwd_hash_algo }}\4 + backrefs: true + loop: + - password + - system + notify: Authselect update - name: "5.3.3.4.4 | PATCH | Ensure pam_unix includes use_authtok" when: - rhel9cis_rule_5_3_3_4_4 + - rhel9cis_disruption_high tags: - level1-server - level1-workstation @@ -87,18 +130,32 @@ - NIST800-53R5_IA-5 block: - name: "5.3.3.4.4 | PATCH | Ensure pam_unix includes use_authtok | capture state" - ansible.builtin.shell: grep -PH -- '^\h*password\h+([^#\n\r]+)\h+pam_unix\.so\h+([^#\n\r]+\h+)?use_authtok\b' /etc/pam.d/{password,system}-auth + ansible.builtin.shell: grep -PH -- '^\h*^password\h*[^#\n\r]+\h+pam_unix\.so\b' /etc/pam.d/{password,system}-auth | grep -Pv -- '\buse_authtok\b' changed_when: false failed_when: rhel9cis_pam_authtok.rc not in [ 0, 1 ] register: rhel9cis_pam_authtok - name: "5.3.3.4.4 | PATCH | Ensure pam_unix includes use_authtok | pam_files" when: + - not rhel9cis_allow_authselect_updates - rhel9cis_pam_authtok is defined - rhel9cis_pam_authtok.stdout | length > 0 ansible.builtin.lineinfile: path: "{{ item }}" - regexp: ^(\s*password\s+[success=end.*]\s+pam_unix\.so)(.*)\s+use_authtok\s*=\s*\S+(.*$) - line: \1\2\3 use_authtok + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_unix\.so)(.*)use_authtok(.*$) + line: \1\2 use_authtok\3 backrefs: true loop: "{{ rhel9cis_pam_authtok.stdout_lines }}" + + - name: "5.3.3.4.4 | PATCH | Ensure pam_unix includes use_authtok | Add use_authtok pam files AuthSelect" + when: + - rhel9cis_allow_authselect_updates + ansible.builtin.lineinfile: + path: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_unix\.so)(.*)use_authtok(.*$) + line: \1\2 use_authtok\3 + backrefs: true + loop: + - password + - system + notify: Authselect update diff --git a/tasks/section_5/cis_5.4.1.x.yml b/tasks/section_5/cis_5.4.1.x.yml index fb30e24..9da1ed0 100644 --- a/tasks/section_5/cis_5.4.1.x.yml +++ b/tasks/section_5/cis_5.4.1.x.yml @@ -1,6 +1,6 @@ --- -- name: "5.4.1.1 | PATCH | Ensure password expiration is configured" +- name: "5.4.1.1 | PATCH | Ensure password expiration is 365 days or less" when: - rhel9cis_rule_5_4_1_1 tags: @@ -15,34 +15,34 @@ - NIST800-53R5_CM-7 - NIST800-53R5_IA-5 block: - - name: "5.4.1.1 | PATCH | Ensure password expiration is configured" + - name: "5.4.1.1 | PATCH | Ensure password expiration is 365 days or less" ansible.builtin.lineinfile: path: /etc/login.defs regexp: '^PASS_MAX_DAYS' line: "PASS_MAX_DAYS {{ rhel9cis_pass['max_days'] }}" - - name: "5.4.1.1 | AUDIT | Ensure password expiration is configured | Get existing users PASS_MAX_DAYS" + - name: "5.4.1.1 | AUDIT | Ensure password expiration is 365 days or less | Get existing users PASS_MAX_DAYS" ansible.builtin.shell: "awk -F: '(/^[^:]+:[^!*]/ && ($5> {{ rhel9cis_pass['max_days'] }} || $5< {{ rhel9cis_pass['max_days'] }} || $5 == -1)){print $1}' /etc/shadow" changed_when: false failed_when: false register: discovered_max_days - - name: "5.4.1.1 | PATCH | Ensure password expiration is configured | 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: + - discovered_max_days.stdout_lines | length > 0 + - item in prelim_interactive_usernames.stdout + - rhel9cis_force_user_maxdays ansible.builtin.user: name: "{{ item }}" password_expire_max: "{{ rhel9cis_pass['max_days'] }}" loop: "{{ discovered_max_days.stdout_lines }}" - when: - - discovered_max_days.stdout_lines | length > 0 - - item in discovered_interactive_usernames.stdout - - rhel9cis_force_user_maxdays -- name: "5.4.1.2 | PATCH | Ensure minimum days between password changes is 7 or more" +- name: "5.4.1.2 | PATCH | Ensure minimum password days is configured" when: - rhel9cis_rule_5_4_1_2 tags: - - level2-server - - level2-workstation + - level1-server + - level1-workstation - patch - password - rule_5.4.1.2 @@ -60,14 +60,14 @@ register: discovered_min_days - name: "5.4.1.2 | PATCH | Ensure minimum password days is configured | Set existing users PASS_MIN_DAYS" + when: + - discovered_min_days.stdout_lines | length > 0 + - item in prelim_interactive_usernames.stdout + - rhel9cis_force_user_mindays ansible.builtin.user: name: "{{ item }}" password_expire_max: "{{ rhel9cis_pass['min_days'] }}" loop: "{{ discovered_min_days.stdout_lines }}" - when: - - discovered_min_days.stdout_lines | length > 0 - - item in discovered_interactive_usernames.stdout - - rhel9cis_force_user_mindays - name: "5.4.1.3 | PATCH | Ensure password expiration warning days is configured" when: @@ -92,12 +92,12 @@ register: discovered_warn_days - name: "5.4.1.3 | PATCH | Ensure password expiration warning days is configured | Set existing users WARN_DAYS" - ansible.builtin.shell: "chage --warndays {{ rhel9cis_pass['warn_age'] }} {{ item }}" - loop: "{{ discovered_warn_days.stdout_lines }}" when: - discovered_warn_days.stdout_lines | length > 0 - - item in discovered_interactive_usernames.stdout + - item in prelim_interactive_usernames.stdout - rhel9cis_force_user_warnage + ansible.builtin.shell: "chage --warndays {{ rhel9cis_pass['warn_age'] }} {{ item }}" + loop: "{{ discovered_warn_days.stdout_lines }}" - name: "5.4.1.4 | PATCH | Ensure strong password hashing algorithm is configured" when: @@ -135,16 +135,16 @@ ansible.builtin.shell: useradd -D -f {{ rhel9cis_inactivelock.lock_days }} when: rhel9cis_5_4_1_5_inactive_settings.stdout | length == 0 - - name: "5.4.1.5 | AUDIT | Ensure inactive password lock is configured | Getting user list" + - name: "5.4.1.5 | AUDIT | Ensure inactive password lock is 30 days or less | Getting user list" ansible.builtin.shell: "awk -F: '/^[^#:]+:[^\\!\\*:]*:[^:]*:[^:]*:[^:]*:[^:]*:(\\s*|-1|3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):[^:]*:[^:]*\\s*$/ {print $1}' /etc/shadow" changed_when: false check_mode: false register: rhel9cis_5_4_1_5_user_list - - name: "5.4.1.5 | PATCH | Ensure inactive password lock is configured | 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.stdout ansible.builtin.shell: chage --inactive {{ rhel9cis_inactivelock.lock_days }} "{{ item }}" loop: "{{ rhel9cis_5_4_1_5_user_list.stdout_lines }}" - when: item in discovered_interactive_usernames.stdout - name: "5.4.1.6 | PATCH | Ensure all users last password change date is in the past" when: @@ -172,22 +172,22 @@ register: rhel9cis_5_4_1_6_user_list - name: "5.4.1.6 | AUDIT | Ensure all users last password change date is in the past | Alert on accounts with pw change in the future" + ansible.builtin.debug: + msg: "Warning!! The following accounts have the last PW change date in the future: {{ rhel9cis_5_4_1_6_user_list.stdout_lines }}" when: - rhel9cis_5_4_1_6_user_list.stdout | length > 0 - not rhel9cis_futurepwchgdate_autofix - ansible.builtin.debug: - msg: "Warning!! The following accounts have the last PW change date in the future: {{ rhel9cis_5_4_1_5_user_list.stdout_lines }}" - name: "5.4.1.6 | AUDIT | Ensure all users last password change date is in the past | warning count" + ansible.builtin.import_tasks: + file: warning_facts.yml when: - rhel9cis_5_4_1_6_user_list.stdout | length > 0 - not rhel9cis_futurepwchgdate_autofix - ansible.builtin.import_tasks: - file: warning_facts.yml - name: "5.4.1.6 | PATCH | Ensure all users last password change date is in the past | Fix accounts with pw change in the future" - when: - - rhel9cis_5_4_1_6_user_list.stdout | length > 0 - - rhel9cis_futurepwchgdate_autofix ansible.builtin.shell: passwd --expire {{ item }} + when: + - rhel9cis_5_4_1_5_user_list.stdout | length > 0 + - rhel9cis_futurepwchgdate_autofix loop: "{{ rhel9cis_5_4_1_6_user_list.stdout_lines }}" diff --git a/tasks/section_5/cis_5.4.2.x.yml b/tasks/section_5/cis_5.4.2.x.yml index d22e4d0..4d75928 100644 --- a/tasks/section_5/cis_5.4.2.x.yml +++ b/tasks/section_5/cis_5.4.2.x.yml @@ -51,10 +51,9 @@ - discovered_gid0_members.stdout | length > 0 ansible.builtin.user: name: "{{ item }}" - gid: 0 + group: root state: absent - loop: - - discovered_gid0_members.stdout_lines + loop: "{{ discovered_gid0_members.stdout_lines }}" - name: "5.4.2.3 | AUDIT | Ensure group root is the only GID 0 group" when: @@ -96,7 +95,7 @@ vars: warn_control_id: '5.4.2.3' -- name: "5.4.2.4 | PATCH | Ensure root account access is controlled" +- name: "5.4.2.4 | PATCH | Ensure root account access is controlled " when: - rhel9cis_rule_5_4_2_4 tags: diff --git a/tasks/section_5/cis_5.4.3.x.yml b/tasks/section_5/cis_5.4.3.x.yml index 15e8e12..7816938 100644 --- a/tasks/section_5/cis_5.4.3.x.yml +++ b/tasks/section_5/cis_5.4.3.x.yml @@ -55,7 +55,7 @@ - NIST800-53R5_MP-2 ansible.builtin.replace: path: "{{ item.path }}" - regexp: (?i)(umask\s+\d\d\d) + regexp: (?i)(umask\s+\d*) replace: '{{ item.line }} {{ rhel9cis_bash_umask }}' loop: - { path: '/etc/profile', line: 'umask' } diff --git a/tasks/section_5/cis_5.4.x.yml b/tasks/section_5/cis_5.4.x.yml deleted file mode 100644 index e463998..0000000 --- a/tasks/section_5/cis_5.4.x.yml +++ /dev/null @@ -1,89 +0,0 @@ ---- - -- name: "5.4.1 | PATCH | Ensure custom authselect profile is used" - block: - - name: "5.4.1 | AUDIT | Ensure custom authselect profile is used | Gather profiles" - ansible.builtin.shell: 'authselect list | grep custom' - failed_when: false - changed_when: false - check_mode: false - register: rhel9cis_5_4_1_current_profile - - - name: "5.4.1 | PATCH | Ensure custom authselect profile is used | Create custom profiles" - ansible.builtin.shell: authselect create-profile {{ rhel9cis_authselect['custom_profile_name'] }} -b {{ rhel9cis_authselect['default_file_to_copy'] }} - when: - - rhel9cis_authselect_custom_profile_create - - "rhel9cis_authselect.custom_profile_name not in rhel9cis_5_4_1_current_profile.stdout" - - - name: "5.4.1 | PATCH | Ensure custom authselect profile is used | Force custom profile creates backup" - ansible.builtin.shell: "authselect select custom/{{ rhel9cis_authselect['custom_profile_name'] }} --force --backup=rhel9cis_5_4_1_{{ ansible_date_time.epoch}}" - register: authselect_5_4_1_select - when: - - rhel9cis_authselect_custom_profile_create - - "rhel9cis_authselect.custom_profile_name not in rhel9cis_5_4_1_current_profile.stdout" - - when: - - rhel9cis_rule_5_4_1 - tags: - - level1-server - - level1-workstation - - manual - - patch - - authselect - - rule_5.4.1 - -- name: "5.4.2 | PATCH | Ensure authselect includes with-faillock | Get Authselect profile options" - block: - - name: "5.4.2 | AUDIT | Ensure authselect includes with-faillock | Gather profiles and enabled features" - ansible.builtin.shell: "authselect current | grep with-faillock" - failed_when: false - changed_when: false - check_mode: false - register: rhel9cis_5_4_2_profiles_faillock - - - name: "5.4.2 | AUDIT | Ensure authselect includes with-faillock | Show profiles" - ansible.builtin.debug: - msg: - - "Below are the current custom profiles" - - "{{ rhel9cis_5_4_2_profiles_faillock.stdout_lines }}" - - - name: "5.4.2 | PATCH | Ensure authselect includes with-faillock | Authselect add options" - ansible.builtin.shell: "authselect select custom/{{ rhel9cis_authselect['custom_profile_name'] }} {{ rhel9cis_authselect['options'] }} --force" - when: rhel9cis_authselect_custom_profile_select - - - name: 5.4.2 | PATCH | Ensure authselect includes with-faillock | not Authselect profile" - ansible.builtin.lineinfile: - path: "/etc/pam.d/password-auth" - regexp: "{{ item.regexp }}" - line: "{{ item.line }}" - insertbefore: "{{ item.before }}" - loop: - - { 'regexp': '^auth\s+required\s+pam_faillock.so preauth silent deny=.*unlock_time=.*', 'line': 'auth required pam_faillock.so preauth silent deny={{ rhel9cis_pam_faillock.deny }} unlock_time={{ rhel9cis_pam_faillock.unlock_time }}', 'before':'^auth\s+sufficient\s+pam_unix.so try_first_pass'} - - { 'regexp': '^auth\s+required\s+pam_faillock.so authfail deny=.*unlock_time=.*', 'line': 'auth required pam_faillock.so authfail deny={{ rhel9cis_pam_faillock.deny }} unlock_time={{ rhel9cis_pam_faillock.unlock_time }}', 'before':'^auth\s+required\s+pam_deny.so'} - - { 'regexp': '^account\s+required\s+pam_faillock.so', 'line': 'account required pam_faillock.so', 'before':'^account required pam_unix.so'} - when: - - rhel9cis_add_faillock_without_authselect - - rhel9cis_5_4_2_risks == 'ACCEPT' - - - name: 5.4.2 | PATCH | Ensure authselect includes with-faillock | not Authselect profile" - ansible.builtin.lineinfile: - path: "/etc/pam.d/system-auth" - regexp: "{{ item.regexp }}" - line: "{{ item.line }}" - insertbefore: "{{ item.before | default(omit)}}" - insertafter: "{{ item.after | default(omit)}}" - loop: - - { 'regexp': '^auth\s+required\s+pam_faillock.so preauth silent deny=.*unlock_time=.*', 'line':'auth required pam_faillock.so preauth silent deny={{ rhel9cis_pam_faillock.deny }} unlock_time={{ rhel9cis_pam_faillock.unlock_time }}', 'before':'^auth\s+sufficient\s+pam_unix.so try_first_pass'} - - { 'regexp': '^auth\s+required\s+pam_faillock.so authfail deny=.*unlock_time=.*', 'line': 'auth required pam_faillock.so authfail deny={{ rhel9cis_pam_faillock.deny }} unlock_time={{ rhel9cis_pam_faillock.unlock_time }}', 'before':'^auth\s+required\s+pam_deny.so'} - - { 'regexp': '^account\s+required\s+pam_faillock.so', 'line': 'account required pam_faillock.so', 'before':'^account required pam_unix.so'} - when: - - rhel9cis_add_faillock_without_authselect - - rhel9cis_5_4_2_risks == 'ACCEPT' - when: - - rhel9cis_rule_5_4_2 - tags: - - level1-server - - level1-workstation - - patch - - authselect - - rule_5.4.2 diff --git a/tasks/section_5/cis_5.5.x.yml b/tasks/section_5/cis_5.5.x.yml deleted file mode 100644 index 57ad96b..0000000 --- a/tasks/section_5/cis_5.5.x.yml +++ /dev/null @@ -1,135 +0,0 @@ ---- - -- name: "5.5.1 | PATCH | Ensure password creation requirements are configured" - block: - - name: "5.5.1 | PATCH | Ensure password creation requirements are configured | Set pwquality config settings" - ansible.builtin.lineinfile: - path: /etc/security/pwquality.conf - regexp: ^{{ item.name }} - line: "{{ item.name }} = {{ item.value }}" - loop: - - { name: minlen, value: "{{ rhel9cis_pam_password.minlen }}" } - - { name: minclass, value: "{{ rhel9cis_pam_password.minclass }}" } - - - name: "5.5.1 | PATCH | Ensure password creation requirements are configured | Set system-auth retry settings | not Authselect" - ansible.builtin.lineinfile: - path: /etc/pam.d/system-auth - regexp: '^password\s*requisite\s*pam_pwquality.so' - line: "password requisite pam_pwquality.so try_first_pass local_users_only enforce_for_root retry=3" - insertbefore: '^#?password ?' - - - name: "5.5.1 | PATCH | Ensure password creation requirements are configured | Set password-auth retry settings | not Authselect" - ansible.builtin.lineinfile: - path: /etc/pam.d/password-auth - regexp: '^password\s*requisite\s*pam_pwquality.so' - line: "password requisite pam_pwquality.so try_first_pass local_users_only enforce_for_root retry=3" - insertbefore: '^#?password ?' - when: - - rhel9cis_rule_5_5_1 - tags: - - level1-server - - level1-workstation - - patch - - rule_5.5.1 - -- name: "5.5.2 | PATCH | Ensure lockout for failed password attempts is configured" - block: - - name: "5.5.2 | PATCH | Ensure lockout for failed password attempts is configured | Set faillock.conf configs" - ansible.builtin.lineinfile: - path: /etc/security/faillock.conf - regexp: "{{ item.regexp }}" - line: "{{ item.line }}" - loop: - - { regexp: '^\s*deny\s*=\s*[1-5]\b', line: 'deny = {{ rhel9cis_pam_faillock.deny }}' } - - { regexp: '^\s*unlock_time\s*=\s*(0|9[0-9][0-9]|[1-9][0-9][0-9][0-9]+)\b', line: 'unlock_time = {{ rhel9cis_pam_faillock.unlock_time }}' } - - - name: "5.5.2 | PATCH | Ensure lockout for failed password attempts is configured | Set preauth" - ansible.builtin.lineinfile: - path: "{{ item }}" - regexp: '^auth\s*(sufficient|required)\s*pam_faillock.so\s*preauth(.*)' - line: "auth required pam_faillock.so preauth silent audit deny={{ rhel9cis_pam_faillock.deny }} unlock_time={{ rhel9cis_pam_faillock.unlock_time}}" - insertafter: 'auth\s*(sufficient|required)\s*pam_env.so$' - loop: - - "/etc/pam.d/system-auth" - - "/etc/pam.d/password-auth" - - - name: "5.5.2 | PATCH | Ensure lockout for failed password attempts is configured | Set authfail" - ansible.builtin.lineinfile: - path: "{{ item }}" - regexp: '^auth\s*(sufficient|required)\s*pam_faillock.so\s*authfail(.*)' - line: "auth required pam_faillock.so authfail audit deny={{ rhel9cis_pam_faillock.deny }} unlock_time={{ rhel9cis_pam_faillock.unlock_time}}" - insertbefore: 'auth\s*(sufficient|required)\s*pam_deny.so$' - loop: - - "/etc/pam.d/system-auth" - - "/etc/pam.d/password-auth" - - - name: "5.5.2 | PATCH | Ensure lockout for failed password attempts is configured | Load account faillock.so" - ansible.builtin.lineinfile: - path: "{{ item }}" - regexp: '^account\s*(sufficient|required)\s*pam_faillock.so$' - line: "account required pam_faillock.so" - insertbefore: '^account\s*(sufficient|required)\s*pam_unix.so$' - loop: - - "/etc/pam.d/system-auth" - - "/etc/pam.d/password-auth" - when: - - rhel9cis_rule_5_5_2 - tags: - - level1-server - - level1-workstation - - patch - - rule_5.5.2 - -- name: "5.5.3 | PATCH | Ensure password reuse is limited | pwquality" - block: - - name: "5.5.3 | PATCH | Ensure password reuse is limited | Set system-auth remember Settings" - ansible.builtin.lineinfile: - path: /etc/pam.d/system-auth - line: "password requisite pam_pwhistory.so try_first_pass enforce_for_root retry=3 remember={{ rhel9cis_pam_faillock.remember }}" - insertafter: '^password\s*requisite\s*pam_pwquality.so' - - - name: "5.5.3 | PATCH | Ensure password reuse is limited | Set password-auth remember Settings" - ansible.builtin.lineinfile: - path: /etc/pam.d/password-auth - line: "password requisite pam_pwhistory.so try_first_pass enforce_for_root retry=3 remember={{ rhel9cis_pam_faillock.remember }}" - insertafter: '^password\s*requisite\s*pam_pwquality.so' - when: - - rhel9cis_rule_5_5_3 - tags: - - level1-server - - level1-workstation - - patch - - rule_5.5.3 - -- name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 or yescrypt" - block: - - name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 | libuser.conf" - ansible.builtin.replace: - path: /etc/libuser.conf - regexp: '^crypt_style\s*=\s*.*$' - replace: 'crypt_style = sha512' - - - name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 | login.defs" - ansible.builtin.replace: - path: /etc/login.defs - regexp: '^ENCRYPT_METHOD.*' - replace: 'ENCRYPT_METHOD SHA512' - - - name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 | password-auth" - ansible.builtin.replace: - path: /etc/pam.d/password-auth - regexp: '^password\s*sufficient\s*pam_unix.so.*$' - replace: 'password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok remember={{ rhel9cis_pam_faillock.remember }}' - - - name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 | system-auth" - ansible.builtin.replace: - path: /etc/pam.d/system-auth - regexp: '^password\s*sufficient\s*pam_unix.so.*$' - replace: 'password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok remember={{ rhel9cis_pam_faillock.remember }}' - when: - - rhel9cis_rule_5_5_4 - tags: - - level1-server - - level1-workstation - - patch - - rule_5.5.4 diff --git a/tasks/section_5/cis_5.5.x_authselect.yml b/tasks/section_5/cis_5.5.x_authselect.yml deleted file mode 100644 index 0d1811b..0000000 --- a/tasks/section_5/cis_5.5.x_authselect.yml +++ /dev/null @@ -1,144 +0,0 @@ ---- - -- name: "5.5.1 | PATCH | Ensure password creation requirements are configured" - block: - - name: "5.5.1 | PATCH | Ensure password creation requirements are configured | Set pwquality config settings" - ansible.builtin.lineinfile: - path: /etc/security/pwquality.conf - regexp: ^{{ item.name }} - line: "{{ item.name }} = {{ item.value }}" - loop: - - { name: minlen, value: "{{ rhel9cis_pam_password.minlen }}" } - - { name: minclass, value: "{{ rhel9cis_pam_password.minclass }}" } - - - name: "5.5.1 | PATCH | Ensure password creation requirements are configured | Set system-auth retry settings | not Authselect" - ansible.builtin.lineinfile: - path: "/etc/authselect/custom/{{ rhel9cis_authselect['custom_profile_name'] }}/system-auth" - regexp: '^password\s*requisite\s*pam_pwquality.so' - line: "password requisite pam_pwquality.so try_first_pass local_users_only enforce_for_root retry=3" - insertbefore: '^#?password ?' - notify: Apply_authselect - - - name: "5.5.1 | PATCH | Ensure password creation requirements are configured | Set password-auth retry settings | not Authselect" - ansible.builtin.lineinfile: - path: "/etc/authselect/custom/{{ rhel9cis_authselect['custom_profile_name'] }}/password-auth" - regexp: '^password\s*requisite\s*pam_pwquality.so' - line: "password requisite pam_pwquality.so try_first_pass local_users_only enforce_for_root retry=3" - insertbefore: '^#?password ?' - notify: Apply_authselect - when: - - rhel9cis_rule_5_5_1 - tags: - - level1-server - - level1-workstation - - patch - - rule_5.5.1 - -- name: "5.5.2 | PATCH | Ensure lockout for failed password attempts is configured" - block: - - name: "5.5.2 | PATCH | Ensure lockout for failed password attempts is configured | Set faillock.conf configs" - ansible.builtin.lineinfile: - path: /etc/security/faillock.conf - regexp: "{{ item.regexp }}" - line: "{{ item.line }}" - loop: - - { regexp: '^\s*deny\s*=\s*[1-5]\b', line: 'deny = {{ rhel9cis_pam_faillock.deny }}' } - - { regexp: '^\s*unlock_time\s*=\s*(0|9[0-9][0-9]|[1-9][0-9][0-9][0-9]+)\b', line: 'unlock_time = {{ rhel9cis_pam_faillock.unlock_time }}' } - - - name: "5.5.2 | PATCH | Ensure lockout for failed password attempts is configured | Set preauth" - ansible.builtin.lineinfile: - path: "{{ item }}" - regexp: '^auth\s*(sufficient|required)\s*pam_faillock.so\s*preauth(.*)' - line: "auth required pam_faillock.so preauth silent audit deny={{ rhel9cis_pam_faillock.deny }} unlock_time={{ rhel9cis_pam_faillock.unlock_time}}" - insertafter: 'auth\s*(sufficient|required)\s*pam_env.so$' - loop: - - "/etc/authselect/custom/{{ rhel9cis_authselect['custom_profile_name'] }}/system-auth" - - "/etc/authselect/custom/{{ rhel9cis_authselect['custom_profile_name'] }}/password-auth" - notify: Apply_authselect - - - name: "5.5.2 | PATCH | Ensure lockout for failed password attempts is configured | Set authfail" - ansible.builtin.lineinfile: - path: "{{ item }}" - regexp: '^auth\s*(sufficient|required)\s*pam_faillock.so\s*authfail(.*)' - line: "auth required pam_faillock.so authfail audit deny={{ rhel9cis_pam_faillock.deny }} unlock_time={{ rhel9cis_pam_faillock.unlock_time}}" - insertbefore: 'auth\s*(sufficient|required)\s*pam_deny.so$' - loop: - - "/etc/authselect/custom/{{ rhel9cis_authselect['custom_profile_name'] }}/system-auth" - - "/etc/authselect/custom/{{ rhel9cis_authselect['custom_profile_name'] }}/password-auth" - notify: Apply_authselect - - - name: "5.5.2 | PATCH | Ensure lockout for failed password attempts is configured | Load account faillock.so" - ansible.builtin.lineinfile: - path: "{{ item }}" - regexp: '^account\s*(sufficient|required)\s*pam_faillock.so$' - line: "account required pam_faillock.so" - insertbefore: '^account\s*(sufficient|required)\s*pam_unix.so$' - loop: - - "/etc/authselect/custom/{{ rhel9cis_authselect['custom_profile_name'] }}/system-auth" - - "/etc/authselect/custom/{{ rhel9cis_authselect['custom_profile_name'] }}/password-auth" - notify: Apply_authselect - when: - - rhel9cis_rule_5_5_2 - tags: - - level1-server - - level1-workstation - - patch - - rule_5.5.2 - -- name: "5.5.3 | PATCH | Ensure password reuse is limited | pwquality" - block: - - name: "5.5.3 | PATCH | Ensure password reuse is limited | Set system-auth remember Settings" - ansible.builtin.lineinfile: - path: "/etc/authselect/custom/{{ rhel9cis_authselect['custom_profile_name'] }}/system-auth" - line: "password requisite pam_pwhistory.so try_first_pass enforce_for_root retry=3 remember={{ rhel9cis_pam_faillock.remember }}" - insertafter: '^password\s*requisite\s*pam_pwquality.so' - notify: Apply_authselect - - - name: "5.5.3 | PATCH | Ensure password reuse is limited | Set password-auth remember Settings" - ansible.builtin.lineinfile: - path: "/etc/authselect/custom/{{ rhel9cis_authselect['custom_profile_name'] }}/password-auth" - line: "password requisite pam_pwhistory.so try_first_pass enforce_for_root retry=3 remember={{ rhel9cis_pam_faillock.remember }}" - insertafter: '^password\s*requisite\s*pam_pwquality.so' - notify: Apply_authselect - when: - - rhel9cis_rule_5_5_3 - tags: - - level1-server - - level1-workstation - - patch - - rule_5.5.3 - -- name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 or yescrypt" - block: - - name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 | libuser.conf" - ansible.builtin.replace: - path: /etc/libuser.conf - regexp: '^crypt_style\s*=\s*.*$' - replace: 'crypt_style = sha512' - - - name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 | login.defs" - ansible.builtin.replace: - path: /etc/login.defs - regexp: '^ENCRYPT_METHOD.*' - replace: 'ENCRYPT_METHOD SHA512' - - - name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 | password-auth" - ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel9cis_authselect['custom_profile_name'] }}/password-auth" - regexp: '^password\s*sufficient\s*pam_unix.so.*$' - replace: 'password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok remember={{ rhel9cis_pam_faillock.remember }}' - notify: Apply_authselect - - - name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 | system-auth" - ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel9cis_authselect['custom_profile_name'] }}/system-auth" - regexp: '^password\s*sufficient\s*pam_unix.so.*$' - replace: 'password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok remember={{ rhel9cis_pam_faillock.remember }}' - notify: Apply_authselect - when: - - rhel9cis_rule_5_5_4 - tags: - - level1-server - - level1-workstation - - patch - - rule_5.5.4 diff --git a/tasks/section_5/cis_5.6.x.yml b/tasks/section_5/cis_5.6.x.yml deleted file mode 100644 index 5271388..0000000 --- a/tasks/section_5/cis_5.6.x.yml +++ /dev/null @@ -1,149 +0,0 @@ ---- - -- name: "5.6.2 | PATCH | Ensure system accounts are secured" - block: - - name: "5.6.2 | PATCH | Ensure system accounts are secured | Set nologin" - ansible.builtin.user: - name: "{{ item.id }}" - shell: /usr/sbin/nologin - loop: "{{ rhel9cis_passwd }}" - when: - - item.id != "root" - - item.id != "sync" - - item.id != "shutdown" - - item.id != "halt" - - item.id != "nfsnobody" - - item.uid < min_int_uid | int - - item.shell != "/bin/false" - - item.shell != "/usr/sbin/nologin" - - item.shell != "/sbin/nologin" - - item.shell != "/dev/null" - loop_control: - label: "{{ item.id }}" - - - name: "5.6.2 | PATCH | Ensure system accounts are secured | Lock accounts" - ansible.builtin.user: - name: "{{ item.id }}" - password_lock: true - loop: "{{ rhel9cis_passwd }}" - when: - - item.id != "halt" - - item.id != "shutdown" - - item.id != "sync" - - item.id != "root" - - item.id != "nfsnobody" - - item.uid < min_int_uid | int - - item.shell != "/bin/false" - - item.shell != "/usr/sbin/nologin" - - item.shell != "/sbin/nologin" - - item.shell != "/dev/null" - loop_control: - label: "{{ item.id }}" - when: - - rhel9cis_rule_5_6_2 - tags: - - level1-server - - level1-workstation - - patch - - accounts - - rule_5.6.2 - -- name: "5.6.3 | PATCH | Ensure default user shell timeout is 900 seconds or less" - ansible.builtin.blockinfile: - path: "{{ item.path }}" - state: "{{ item.state }}" - marker: "# {mark} - CIS benchmark - Ansible-lockdown" - create: true - mode: '0644' - block: | - TMOUT={{ rhel9cis_shell_session_timeout.timeout }} - export TMOUT - readonly TMOUT - loop: - - { path: "{{ rhel9cis_shell_session_timeout.file }}", state: present } - - { path: /etc/profile, state: "{{ (rhel9cis_shell_session_timeout.file == '/etc/profile') | ternary('present', 'absent') }}" } - when: - - rhel9cis_rule_5_6_3 - tags: - - level1-server - - level1-workstation - - patch - - accounts - - rule_5.6.3 - -- name: "5.6.4 | PATCH | Ensure default group for the root account is GID 0" - ansible.builtin.user: - name: root - group: 0 - when: - - rhel9cis_rule_5_6_4 - tags: - - level1-server - - level1-workstation - - patch - - accounts - - rule_5.6.4 - -- name: "5.6.5 | PATCH | Ensure default user umask is 027 or more restrictive" - block: - - name: "5.6.5 | PATCH | Ensure default user umask is 027 or more restrictive | Set umask for /etc/login.defs pam_umask settings" - ansible.builtin.replace: - path: "{{ item.path }}" - regexp: (?i)(umask\s+\d\d\d) - replace: '{{ item.line }} 027' - with_items: - - { path: '/etc/bashrc', line: 'umask' } - - { path: '/etc/profile', line: 'umask' } - - { path: '/etc/login.defs', line: 'UMASK' } - - - name: "5.6.5 | PATCH | Ensure default user umask is 027 or more restrictive | Set umask for /etc/bashrc" - ansible.builtin.lineinfile: - path: /etc/login.defs - regexp: '^USERGROUPS_ENAB' - line: USERGROUPS_ENAB no - - - name: "5.6.5 | PATCH | Ensure default user umask is 027 or more restrictive | Add umask sessions for pamd" - community.general.pamd: - name: "{{ item }}" - type: session - control: required - module_path: pam_limits.so - new_type: session - new_module_path: pam_umask.so - new_control: optional - state: before - register: rhel9cis_pamd_umask_added - loop: - - system-auth - - password-auth - - - name: "5.6.5 | AUDIT | Ensure default user umask is 027 or more restrictive | update umask settings if required" - ansible.builtin.replace: - path: "/etc/pam.d/{{ item }}" - regexp: ^(session\s+)(requisite|required)(\s+pam_umask.so)$ - replace: \1optional\3 - loop: - - system-auth - - password-auth - - when: - - rhel9cis_rule_5_6_5 - tags: - - level1-server - - level1-workstation - - patch - - accounts - - rule_5.6.5 - -- name: "5.6.6 | PATCH | Ensure root password is set" - ansible.builtin.debug: - msg: "The root password has been set as per the assert in early stages" - when: - - rhel9cis_rule_5_6_6 - tags: - - level1-server - - level1-workstation - - patch - - accounts - - root - - rule_5.6.6