From 80d107cf431a0f78e079a2310ad5b85e3915478c Mon Sep 17 00:00:00 2001 From: MVladislav Date: Sun, 14 Apr 2024 23:19:44 +0200 Subject: [PATCH] refactor: updating to v2.0.0 - section 5 finished --- .pre-commit-config.yaml | 5 +- README.md | 198 ++--- defaults/main.yml | 195 +++-- tasks/pre.yml | 2 +- tasks/section1.yml | 4 +- tasks/section2.yml | 2 +- tasks/section5.yml | 1411 ++++++++++++++++++++++----------- tasks/section7.yml | 14 +- templates/pam/faillock | 6 + templates/pam/faillock-notify | 9 + templates/pam/pwhistory.j2 | 6 + templates/pam/pwquality | 9 + templates/pam/unix.j2 | 23 + 13 files changed, 1235 insertions(+), 649 deletions(-) create mode 100644 templates/pam/faillock create mode 100644 templates/pam/faillock-notify create mode 100644 templates/pam/pwhistory.j2 create mode 100644 templates/pam/pwquality create mode 100644 templates/pam/unix.j2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1695ee9..757239c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: hooks: - id: codespell args: - - --ignore-words-list=ihs,ro,fo,iif + - --ignore-words-list=ihs,ro,fo,iif,chage - --skip="./.*,*.csv,*.json" - --quiet-level=2 exclude_types: @@ -51,6 +51,9 @@ repos: rev: v1.4.0 hooks: - id: detect-secrets + args: + - --exclude-files=templates/pam/pwquality + - --exclude-files=templates/pam/pwhistory.j2 - repo: https://github.com/gitleaks/gitleaks rev: v8.18.2 diff --git a/README.md b/README.md index 66b3914..b5a7087 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ - [CIS - Ubuntu 22.04](#cis---ubuntu-2204) - [IN WORK update to v2.0.0](#in-work-update-to-v200) - - [TODO](#todo) - [Notes](#notes) - [Requirements](#requirements) - [Role Variables](#role-variables) @@ -47,27 +46,6 @@ If you are **implementing to an existing system** please **review** this role fo Based on **[CIS Ubuntu Linux 22.04 LTS Benchmark v2.0.0](https://downloads.cisecurity.org/#/)**. -## TODO - -- improve grub changes - - make changes for lvm or zfs - - create checker and add for if grub exists with lines like, because we only check for replace in section - - `GRUB_CMDLINE_LINUX` - - make a copy from template if grub not exists - - - - `sudo cp /usr/share/grub/default/grub /etc/default/` -- improve auditd for 32 or 64 system check to add rules -- check ufw sysctl usage -- improve with some variables for section5 -- extend cis_ubuntu2204_rule_5_3_4 - - to also check in subfiles under '/etc/sudoers.d/' -- rules under '5.4', should be more tested - - example for 'cis_ubuntu2204_rule_5_4_2' which fail to use password after performed - - seams error found, but need tests, CIS pdf define success=1 but default value in ubuntu is success=2 -- possible add 'usbguard' for rule 'cis_ubuntu2204_rule_1_1_1_8' when usb-storage should be loaded as alternative security - - -- implement 'cis_ubuntu2204_regex_base_search_post' - ## Notes - section :: 6.2.1.2 **Configure systemd-journal-remote** @@ -76,6 +54,8 @@ Based on **[CIS Ubuntu Linux 22.04 LTS Benchmark v2.0.0](https://downloads.cisec - is configured, but not in deep tested _(default ufw is used from section 4.1)_ - section :: 4.3 **Configure iptables** - is configured, but not in deep tested _(default ufw is used from section 4.1)_ +- section :: 5.3 **Pluggable Authentication Modules** :: 5.4 **User Accounts and Environment** + - could be tested deeper, base tests are performed and for secure only used for fresh os install ## Requirements @@ -118,7 +98,7 @@ cis_ubuntu2204_section7: true ```yaml # additional configs for ssh which not defined set by CIS -cis_ubuntu2204_rule_5_2_23: true +cis_ubuntu2204_rule_5_1_23: true # set auditd log_file as needed to be save in other configs cis_ubuntu2204_rule_6_3_4_0: true @@ -142,9 +122,6 @@ cis_ubuntu2204_disable_boot_pass: true # do not forget set related variables 'cis_ubuntu2204_set_journal_upload_*' cis_ubuntu2204_set_journal_upload: false cis_ubuntu2204_set_journal_upload_url: - -# Ensure lockout for failed password attempts is configured -cis_ubuntu2204_rule_5_4_2: false ``` ### variable special usable between server and client @@ -210,9 +187,12 @@ cis_ubuntu2204_ssh_authentication_methods: "publickey" cis_ubuntu2204_ssh_password_authentication: "no" # pw quality policies -cis_ubuntu2204_pwquality: - - key: "minlen" - value: "14" +cis_ubuntu2204_faillock_deny: 5 +cis_ubuntu2204_faillock_unlock_time: 900 +cis_ubuntu2204_faillock_minlen: 14 +cis_ubuntu2204_password_complexity: + - key: "minclass" + value: "3" - key: "dcredit" value: "-1" - key: "ucredit" @@ -222,14 +202,6 @@ cis_ubuntu2204_pwquality: - key: "lcredit" value: "-1" -cis_ubuntu2204_faillock_unlock_time: 600 -# NOTE: check the two success values, in CIS-pdf they are defined with '1' -# but on ubuntu-23.04 it is set per default as '2' -cis_ubuntu2204_remember_reuse: 5 -cis_ubuntu2204_encrypt_method: yescrypt # yescrypt | sha512 -cis_ubuntu2204_common_auth_success: 2 -cis_ubuntu2204_common_password_success: 2 - # AIDE cron settings (cis_ubuntu2204_rule_6_1_2) cis_ubuntu2204_aide_cron: cron_user: root @@ -308,8 +280,6 @@ example usage you can find also [here](https://github.com/MVladislav/ansible-env cis_ubuntu2204_set_boot_pass: false # bootloader password (disabled) cis_ubuntu2204_disable_boot_pass: true # bootloader password (disabled) # ------------------------- - cis_ubuntu2204_rule_5_4_2: false # lockout for failed password attempts # NOTE: will fail to use password - # ------------------------- cis_ubuntu2204_rule_3_1_3: false # bluetooth service cis_ubuntu2204_rule_3_1_3_remove: false # bluetooth service # ------------------------- @@ -346,9 +316,13 @@ example usage you can find also [here](https://github.com/MVladislav/ansible-env - root cis_ubuntu2204_at_allow_users: - root - cis_ubuntu2204_pwquality: - - key: "minlen" - value: "8" + # ------------------------- + cis_ubuntu2204_faillock_deny: 5 + cis_ubuntu2204_faillock_unlock_time: 900 + cis_ubuntu2204_faillock_minlen: 8 + cis_ubuntu2204_password_complexity: + - key: "minclass" + value: "3" - key: "dcredit" value: "-1" - key: "ucredit" @@ -587,6 +561,92 @@ For more specific description see the **CIS pdf** file on **page 18**. | 4.3.3.2 | Ensure ip6tables loopback traffic is configured (Automated) | 🟢 | | | | 4.3.3.3 | Ensure ip6tables outbound and established connections are configured (Manual) | 🟢 | | | | 4.3.3.4 | Ensure ip6tables firewall rules exist for all open ports (Automated) | 🟢 | | | +| 5 | **Access Control** | | 🟡 | | +| 5.1 | **Configure SSH Server** | 🟢 | | | +| 5.1.1 | Ensure permissions on /etc/ssh/sshd_config are configured (Automated) | 🟢 | | | +| 5.1.2 | Ensure permissions on SSH private host key files are configured (Automated) | 🟢 | | | +| 5.1.3 | Ensure permissions on SSH public host key files are configured (Automated) | 🟢 | | | +| 5.1.4 | Ensure sshd access is configured (Automated) | 🟢 | | | +| 5.1.5 | Ensure sshd Banner is configured (Automated) | 🟢 | | | +| 5.1.6 | Ensure sshd Ciphers are configured (Automated) | 🟢 | | | +| 5.1.7 | Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured (Automated) | 🟢 | | | +| 5.1.8 | Ensure sshd DisableForwarding is enabled (Automated) | 🟢 | | | +| 5.1.9 | Ensure sshd GSSAPIAuthentication is disabled (Automated) | 🟢 | | | +| 5.1.10 | Ensure sshd HostbasedAuthentication is disabled (Automated) | 🟢 | | | +| 5.1.11 | Ensure sshd IgnoreRhosts is enabled (Automated) | 🟢 | | | +| 5.1.12 | Ensure sshd KexAlgorithms is configured (Automated) | 🟢 | | | +| 5.1.13 | Ensure sshd LoginGraceTime is configured (Automated) | 🟢 | | | +| 5.1.14 | Ensure sshd LogLevel is configured (Automated) | 🟢 | | | +| 5.1.15 | Ensure sshd MACs are configured (Automated) | 🟢 | | | +| 5.1.16 | Ensure sshd MaxAuthTries is configured (Automated) | 🟢 | | | +| 5.1.17 | Ensure sshd MaxSessions is configured (Automated) | 🟢 | | | +| 5.1.18 | Ensure sshd MaxStartups is configured (Automated) | 🟢 | | | +| 5.1.19 | Ensure sshd PermitEmptyPasswords is disabled (Automated) | 🟢 | | | +| 5.1.20 | Ensure sshd PermitRootLogin is disabled (Automated) | 🟢 | | | +| 5.1.21 | Ensure sshd PermitUserEnvironment is disabled (Automated) | 🟢 | | | +| 5.1.22 | Ensure sshd UsePAM is enabled (Automated) | 🟢 | | | +| 5.2 | **Configure privilege escalation** | 🟢 | | | +| 5.2.1 | Ensure sudo is installed (Automated) | 🟢 | | | +| 5.2.2 | Ensure sudo commands use pty (Automated) | 🟢 | | | +| 5.2.3 | Ensure sudo log file exists (Automated) | 🟢 | | | +| 5.2.4 | Ensure users must provide password for privilege escalation (Automated) | 🟢 | | | +| 5.2.5 | Ensure re-authentication for privilege escalation is not disabled globally (Automated) | 🟢 | | | +| 5.2.6 | Ensure sudo authentication timeout is configured correctly (Automated) | 🟢 | | | +| 5.2.7 | Ensure access to the su command is restricted (Automated) | 🟢 | | | +| 5.3 | **Pluggable Authentication Modules** | 🟢 | | | +| 5.3.1 | **Configure PAM software packages** | 🟢 | | | +| 5.3.1.1 | Ensure latest version of pam is installed (Automated) | 🟢 | | | +| 5.3.1.2 | Ensure libpam-modules is installed (Automated) | 🟢 | | | +| 5.3.1.3 | Ensure libpam-pwquality is installed (Automated) | 🟢 | | | +| 5.3.2 | **Configure pam-auth-update profiles** | 🟢 | | | +| 5.3.2.1 | Ensure pam_unix module is enabled (Automated) | 🟢 | | | +| 5.3.2.2 | Ensure pam_faillock module is enabled (Automated) | 🟢 | | | +| 5.3.2.3 | Ensure pam_pwquality module is enabled (Automated) | 🟢 | | | +| 5.3.2.4 | Ensure pam_pwhistory module is enabled (Automated) | 🟢 | | | +| 5.3.3 | **Configure PAM Arguments** | 🟢 | | | +| 5.3.3.1 | **Configure pam_faillock module** | 🟢 | | | +| 5.3.3.1.1 | Ensure password failed attempts lockout is configured (Automated) | 🟢 | | | +| 5.3.3.1.2 | Ensure password unlock time is configured (Automated) | 🟢 | | | +| 5.3.3.1.3 | Ensure password failed attempts lockout includes root account (Automated) | 🟢 | | | +| 5.3.3.2 | **Configure pam_pwquality module** | 🟢 | | | +| 5.3.3.2.1 | Ensure password number of changed characters is configured (Automated) | 🟢 | | | +| 5.3.3.2.2 | Ensure minimum password length is configured (Automated) | 🟢 | | | +| 5.3.3.2.3 | Ensure password complexity is configured (Automated) | 🟢 | | | +| 5.3.3.2.4 | Ensure password same consecutive characters is configured (Automated) | 🟢 | | | +| 5.3.3.2.5 | Ensure password maximum sequential characters is configured (Automated) | 🟢 | | | +| 5.3.3.2.6 | Ensure password dictionary check is enabled (Automated) | 🟢 | | | +| 5.3.3.2.7 | Ensure password quality checking is enforced (Automated) | 🟢 | | | +| 5.3.3.2.8 | Ensure password quality is enforced for the root user (Automated) | 🟢 | | | +| 5.3.3.3 | **Configure pam_pwhistory module** | 🟢 | | | +| 5.3.3.3.1 | Ensure password history remember is configured (Automated) | 🟢 | | | +| 5.3.3.3.2 | Ensure password history is enforced for the root user (Automated) | 🟢 | | | +| 5.3.3.3.3 | Ensure pam_pwhistory includes use_authtok (Automated) | 🟢 | | | +| 5.3.3.4 | **Configure pam_unix module** | 🟢 | | | +| 5.3.3.4.1 | Ensure pam_unix does not include nullok (Automated) | 🟢 | | | +| 5.3.3.4.2 | Ensure pam_unix does not include remember (Automated) | 🟢 | | | +| 5.3.3.4.3 | Ensure pam_unix includes a strong password hashing algorithm (Automated) | 🟢 | | | +| 5.3.3.4.4 | Ensure pam_unix includes use_authtok (Automated) | 🟢 | | | +| 5.4 | **User Accounts and Environment** | | 🟡 | | +| 5.4.1 | **Configure shadow password suite parameters** | 🟢 | | | +| 5.4.1.1 | Ensure password expiration is configured (Automated) | 🟢 | | | +| 5.4.1.2 | Ensure minimum password age is configured (Automated) | 🟢 | | | +| 5.4.1.3 | Ensure password expiration warning days is configured (Automated) | 🟢 | | | +| 5.4.1.4 | Ensure strong password hashing algorithm is configured (Automated) | 🟢 | | | +| 5.4.1.5 | Ensure inactive password lock is configured (Automated) | | 🟡 | | +| 5.4.1.6 | Ensure all users last password change date is in the past (Manual) | | 🟡 | | +| 5.4.2 | **Configure root and system accounts and environment** | | 🟡 | | +| 5.4.2.1 | Ensure root is the only UID 0 account (Automated) | 🟢 | | | +| 5.4.2.2 | Ensure root is the only GID 0 account (Automated) | 🟢 | | | +| 5.4.2.3 | Ensure group root is the only GID 0 group (Automated) | 🟢 | | | +| 5.4.2.4 | Ensure root password is set (Automated) | | | 🔴 | +| 5.4.2.5 | Ensure root path integrity (Automated) | | 🟡 | | +| 5.4.2.6 | Ensure root user umask is configured (Automated) | 🟢 | | | +| 5.4.2.7 | Ensure system accounts do not have a valid login shell (Automated) | | 🟡 | | +| 5.4.2.8 | Ensure accounts without a valid login shell are locked (Automated) | 🟢 | | | +| 5.4.3 | **Configure user default environment** | 🟢 | | | +| 5.4.3.1 | Ensure nologin is not listed in /etc/shells (Automated) | 🟢 | | | +| 5.4.3.2 | Ensure default user shell timeout is configured (Automated) | 🟢 | | | +| 5.4.3.3 | Ensure default user umask is configured (Automated) | 🟢 | | | | 6 | **Logging and Auditing** | 🟢 | | | | 6.1 | **Configure Filesystem Integrity Checking** | 🟢 | | | | 6.1.1 | Ensure AIDE is installed (Automated) | 🟢 | | | @@ -679,62 +739,8 @@ For more specific description see the **CIS pdf** file on **page 18**. | 7.2.9 | Ensure local interactive user home directories are configured (Automated) | 🟢 | | | | 7.2.10 | Ensure local interactive user dot files access is configured (Automated) | 🟢 | | | -| # | CIS Benchmark Recommendation Set | Yes | Y/N | No | -| :------ | :------------------------------------------------------------------------------------- | :-: | :-: | :-: | -| 5 | **Access Control** | | | | -| 5.1 | **Configure SSH Server** | x | | | -| 5.1.1 | Ensure permissions on /etc/ssh/sshd_config are configured (Automated) | x | | | -| 5.1.2 | Ensure permissions on SSH private host key files are configured (Automated) | x | | | -| 5.1.3 | Ensure permissions on SSH public host key files are configured (Automated) | x | | | -| 5.1.4 | Ensure SSH access is limited (Automated) | x | | | -| 5.1.5 | Ensure SSH LogLevel is appropriate (Automated) | x | | | -| 5.1.6 | Ensure SSH PAM is enabled (Automated) | x | | | -| 5.1.7 | Ensure SSH root login is disabled (Automated) | x | | | -| 5.1.8 | Ensure SSH HostbasedAuthentication is disabled (Automated) | x | | | -| 5.1.9 | Ensure SSH PermitEmptyPasswords is disabled (Automated) | x | | | -| 5.1.10 | Ensure SSH PermitUserEnvironment is disabled (Automated) | x | | | -| 5.1.11 | Ensure SSH IgnoreRhosts is enabled (Automated) | x | | | -| 5.1.12 | Ensure SSH X11 forwarding is disabled (Automated) | x | | | -| 5.1.13 | Ensure only strong Ciphers are used (Automated) | x | | | -| 5.1.14 | Ensure only strong MAC algorithms are used (Automated) | x | | | -| 5.1.15 | Ensure only strong Key Exchange algorithms are used (Automated) | x | | | -| 5.1.16 | Ensure SSH AllowTcpForwarding is disabled (Automated) | x | | | -| 5.1.17 | Ensure SSH warning banner is configured (Automated) | x | | | -| 5.1.18 | Ensure SSH MaxAuthTries is set to 4 or less (Automated) | x | | | -| 5.1.19 | Ensure SSH MaxStartups is configured (Automated) | x | | | -| 5.1.20 | Ensure SSH MaxSessions is set to 10 or less (Automated) | x | | | -| 5.1.21 | Ensure SSH LoginGraceTime is set to one minute or less (Automated) | x | | | -| 5.1.22 | Ensure SSH Idle Timeout Interval is configured (Automated) | x | | | -| 5.2 | **Configure privilege escalation** | x | | | -| 5.2.1 | Ensure sudo is installed (Automated) | x | | | -| 5.2.2 | Ensure sudo commands use pty (Automated) | x | | | -| 5.2.3 | Ensure sudo log file exists (Automated) | x | | | -| 5.2.4 | Ensure users must provide password for privilege escalation (Automated) | x | | | -| 5.2.5 | Ensure re-authentication for privilege escalation is not disabled globally (Automated) | x | | | -| 5.2.6 | Ensure sudo authentication timeout is configured correctly (Automated) | x | | | -| 5.2.7 | Ensure access to the su command is restricted (Automated) | x | | | -| 5.4 | **Configure PAM** | | x | | -| 5.4.1 | Ensure password creation requirements are configured (Automated) | x | | | -| 5.4.2 | Ensure lockout for failed password attempts is configured (Automated) | x | | | -| 5.4.3 | Ensure password reuse is limited (Automated) | x | | | -| 5.4.4 | Ensure password hashing algorithm is up to date with the latest standards (Automated) | x | | | -| 5.4.5 | Ensure all current passwords uses the configured hashing algorithm (Manual) | | | x | -| 5.5 | **User Accounts and Environment** | | x | | -| 5.5.1 | **Set Shadow Password Suite Parameters** | | x | | -| 5.5.1.1 | Ensure minimum days between password changes is configured (Automated) | x | | | -| 5.5.1.2 | Ensure password expiration is 365 days or less (Automated) | x | | | -| 5.5.1.3 | Ensure password expiration warning days is 7 or more (Automated) | x | | | -| 5.5.1.4 | Ensure inactive password lock is 30 days or less (Automated) | x | | | -| 5.5.1.5 | Ensure all users last password change date is in the past (Automated) | | | x | -| 5.5.2 | Ensure system accounts are secured (Automated) | x | | | -| 5.5.3 | Ensure default group for the root account is GID 0 (Automated) | x | | | -| 5.5.4 | Ensure default user umask is 027 or more restrictive (Automated) | x | | | -| 5.5.5 | Ensure default user shell timeout is 900 seconds or less (Automated) | x | | | - | # | CIS Benchmark Recommendation Set | Yes | Y/N | No | | :------ | :-------------------------------------------------------------------------------- | :-: | :-: | :-: | -| 7.2.9 | Ensure root PATH Integrity (Automated) | | | 🟣 | -| 7.2.10 | Ensure root is the only UID 0 account (Automated) | | | 🟣 | | 7.2.14 | Ensure no local interactive user has .netrc files (Automated) | | | 🟣 | | 7.2.15 | Ensure no local interactive user has .forward files (Automated) | | | 🟣 | | 7.2.16 | Ensure no local interactive user has .rhosts files (Automated) | | | 🟣 | diff --git a/defaults/main.yml b/defaults/main.yml index a245416..f7994a6 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -183,6 +183,29 @@ cis_ubuntu2204_rule_4_3_3_2: true # NOTE: 'cis_ubuntu2204_firewall == iptables' cis_ubuntu2204_rule_4_3_3_3: true # NOTE: 'cis_ubuntu2204_firewall == iptables' cis_ubuntu2204_rule_4_3_3_4: true # NOTE: 'cis_ubuntu2204_firewall == iptables' ## SECTION 5 rules +cis_ubuntu2204_rule_5_1_1: true +cis_ubuntu2204_rule_5_1_2: true +cis_ubuntu2204_rule_5_1_3: true +cis_ubuntu2204_rule_5_1_4: true +cis_ubuntu2204_rule_5_1_5: true +cis_ubuntu2204_rule_5_1_6: true +cis_ubuntu2204_rule_5_1_7: true +cis_ubuntu2204_rule_5_1_8: true +cis_ubuntu2204_rule_5_1_9: true +cis_ubuntu2204_rule_5_1_10: true +cis_ubuntu2204_rule_5_1_11: true +cis_ubuntu2204_rule_5_1_12: true +cis_ubuntu2204_rule_5_1_13: true +cis_ubuntu2204_rule_5_1_14: true +cis_ubuntu2204_rule_5_1_15: true +cis_ubuntu2204_rule_5_1_16: true +cis_ubuntu2204_rule_5_1_17: true +cis_ubuntu2204_rule_5_1_18: true +cis_ubuntu2204_rule_5_1_19: true +cis_ubuntu2204_rule_5_1_20: true +cis_ubuntu2204_rule_5_1_21: true +cis_ubuntu2204_rule_5_1_22: true +cis_ubuntu2204_rule_5_1_23: true # EXTENDED: own added, not included in CIS cis_ubuntu2204_rule_5_2_1: true cis_ubuntu2204_rule_5_2_2: true cis_ubuntu2204_rule_5_2_3: true @@ -190,43 +213,47 @@ cis_ubuntu2204_rule_5_2_4: true cis_ubuntu2204_rule_5_2_5: true cis_ubuntu2204_rule_5_2_6: true cis_ubuntu2204_rule_5_2_7: true -cis_ubuntu2204_rule_5_2_8: true -cis_ubuntu2204_rule_5_2_9: true -cis_ubuntu2204_rule_5_2_10: true -cis_ubuntu2204_rule_5_2_11: true -cis_ubuntu2204_rule_5_2_12: true -cis_ubuntu2204_rule_5_2_13: true -cis_ubuntu2204_rule_5_2_14: true -cis_ubuntu2204_rule_5_2_15: true -cis_ubuntu2204_rule_5_2_16: true -cis_ubuntu2204_rule_5_2_17: true -cis_ubuntu2204_rule_5_2_18: true -cis_ubuntu2204_rule_5_2_19: true -cis_ubuntu2204_rule_5_2_20: true -cis_ubuntu2204_rule_5_2_21: true -cis_ubuntu2204_rule_5_2_22: true -cis_ubuntu2204_rule_5_2_23: true # EXTENDED: own added, not included in CIS -cis_ubuntu2204_rule_5_3_1: true -cis_ubuntu2204_rule_5_3_2: true -cis_ubuntu2204_rule_5_3_3: true -cis_ubuntu2204_rule_5_3_4: true -cis_ubuntu2204_rule_5_3_5: true -cis_ubuntu2204_rule_5_3_6: true -cis_ubuntu2204_rule_5_3_7: true -cis_ubuntu2204_rule_5_4_1: true -cis_ubuntu2204_rule_5_4_2: false # NOTE: disabled -cis_ubuntu2204_rule_5_4_3: true -cis_ubuntu2204_rule_5_4_4: true -cis_ubuntu2204_rule_5_4_5: true -cis_ubuntu2204_rule_5_5_1_1: true -cis_ubuntu2204_rule_5_5_1_2: true -cis_ubuntu2204_rule_5_5_1_3: true -cis_ubuntu2204_rule_5_5_1_4: true -cis_ubuntu2204_rule_5_5_1_5: true -cis_ubuntu2204_rule_5_5_2: true -cis_ubuntu2204_rule_5_5_3: true -cis_ubuntu2204_rule_5_5_4: true -cis_ubuntu2204_rule_5_5_5: true +cis_ubuntu2204_rule_5_3_1_1: true +cis_ubuntu2204_rule_5_3_1_2: true +cis_ubuntu2204_rule_5_3_1_3: true +cis_ubuntu2204_rule_5_3_2_1: true +cis_ubuntu2204_rule_5_3_2_2: true +cis_ubuntu2204_rule_5_3_2_3: true +cis_ubuntu2204_rule_5_3_2_4: true +cis_ubuntu2204_rule_5_3_3_1_1: true +cis_ubuntu2204_rule_5_3_3_1_2: true +cis_ubuntu2204_rule_5_3_3_1_3: true +cis_ubuntu2204_rule_5_3_3_2_1: true +cis_ubuntu2204_rule_5_3_3_2_2: true +cis_ubuntu2204_rule_5_3_3_2_3: true +cis_ubuntu2204_rule_5_3_3_2_4: true +cis_ubuntu2204_rule_5_3_3_2_5: true +cis_ubuntu2204_rule_5_3_3_2_6: true +cis_ubuntu2204_rule_5_3_3_2_7: true +cis_ubuntu2204_rule_5_3_3_2_8: true +cis_ubuntu2204_rule_5_3_3_3_1: true +cis_ubuntu2204_rule_5_3_3_3_2: true +cis_ubuntu2204_rule_5_3_3_3_3: true +cis_ubuntu2204_rule_5_3_3_4_1: true +cis_ubuntu2204_rule_5_3_3_4_2: true +cis_ubuntu2204_rule_5_3_3_4_3: true +cis_ubuntu2204_rule_5_3_3_4_4: true +cis_ubuntu2204_rule_5_4_1_1: true +cis_ubuntu2204_rule_5_4_1_2: true +cis_ubuntu2204_rule_5_4_1_3: true +cis_ubuntu2204_rule_5_4_1_4: true +cis_ubuntu2204_rule_5_4_1_5: true +cis_ubuntu2204_rule_5_4_1_6: true +cis_ubuntu2204_rule_5_4_2_1: true +cis_ubuntu2204_rule_5_4_2_2: true +cis_ubuntu2204_rule_5_4_2_3: true +cis_ubuntu2204_rule_5_4_2_5: true +cis_ubuntu2204_rule_5_4_2_6: true +cis_ubuntu2204_rule_5_4_2_7: true +cis_ubuntu2204_rule_5_4_2_8: true +cis_ubuntu2204_rule_5_4_3_1: true +cis_ubuntu2204_rule_5_4_3_2: true +cis_ubuntu2204_rule_5_4_3_3: true ## SECTION 6 rules cis_ubuntu2204_rule_6_1_1: true # NOTE: depends also on 'cis_ubuntu2204_install_aide|cis_ubuntu2204_config_aide' cis_ubuntu2204_rule_6_1_2: true # NOTE: depends also on 'cis_ubuntu2204_install_aide|cis_ubuntu2204_config_aide' @@ -310,7 +337,9 @@ cis_ubuntu2204_rule_7_2_10: true # ------------------------------------------------------------------------------ cis_ubuntu2204_regex_base_search: '^(#(\s)*)?' # cis_ubuntu2204_regex_base_search_post: '((.*)?=|\s|$)' +cis_ubuntu2204_regex_base_search_equals: '\s*=.*$' cis_ubuntu2204_shell_executable: /bin/bash +cis_ubuntu2204_print_info_join_by: ", " # SPECIAL options rule overview # --------------------------------------- @@ -373,68 +402,62 @@ cis_ubuntu2204_firewall_rules_exist_open_ports: # comment: "allow http in" # ssh conf's -# allows/denies for users/groups (cis_ubuntu2204_rule_5_2_4) +# allows/denies for users/groups (cis_ubuntu2204_rule_5_1_4) # 'optional:' cis_ubuntu2204_ssh_allow_users: root,user # 'optional:' cis_ubuntu2204_ssh_allow_groups: root,ssh # 'optional:' cis_ubuntu2204_ssh_deny_users: root,user # 'optional:' cis_ubuntu2204_ssh_deny_groups: root,ssh -# log level (cis_ubuntu2204_rule_5_2_5) +# (cis_ubuntu2204_rule_5_1_7) +cis_ubuntu2204_ssh_client_alive_interval: 15 +cis_ubuntu2204_ssh_client_alive_count_max: 3 +# log level (cis_ubuntu2204_rule_5_1_14) cis_ubuntu2204_ssh_log_level: VERBOSE # VERBOSE | INFO -# (cis_ubuntu2204_rule_5_2_7) +# (cis_ubuntu2204_rule_5_1_16) +cis_ubuntu2204_ssh_max_auth_tries: 4 +# (cis_ubuntu2204_rule_5_1_17) +cis_ubuntu2204_ssh_max_sessions: 10 +# (cis_ubuntu2204_rule_5_1_20) cis_ubuntu2204_ssh_permit_root_login: "no" -# (cis_ubuntu2204_rule_5_2_18) -cis_ubuntu2204_ssh_max_auth_tries: 3 -# (cis_ubuntu2204_rule_5_2_20) -cis_ubuntu2204_ssh_max_sessions: 2 -# (cis_ubuntu2204_rule_5_2_22) -cis_ubuntu2204_ssh_client_alive_interval: 15 -cis_ubuntu2204_ssh_client_alive_count_max: 2 -# (cis_ubuntu2204_rule_5_2_23) +# (cis_ubuntu2204_rule_5_1_23) cis_ubuntu2204_ssh_port: 22 +cis_ubuntu2204_ssh_address_family: "inet" cis_ubuntu2204_ssh_authentication_methods: "publickey" cis_ubuntu2204_ssh_password_authentication: "no" -cis_ubuntu2204_ssh_tcp_keep_alive: "yes" cis_ubuntu2204_ssh_allow_agent_forwarding: "yes" -# Ciphers (cis_ubuntu2204_rule_5_2_13) +cis_ubuntu2204_ssh_tcp_keep_alive: "yes" +cis_ubuntu2204_ssh_x11_forwarding: "no" +cis_ubuntu2204_ssh_allow_tcp_forwarding: "no" +# Ciphers (cis_ubuntu2204_rule_5_1_6) cis_ubuntu2204_ssh_ciphers: - - chacha20-poly1305@openssh.com + # - chacha20-poly1305@openssh.com # NOTE: (CVE-2023-48795) - aes256-gcm@openssh.com - aes128-gcm@openssh.com - aes256-ctr - aes192-ctr - aes128-ctr -# MACs (cis_ubuntu2204_rule_5_2_14) +# MACs (cis_ubuntu2204_rule_5_1_15) cis_ubuntu2204_ssh_macs: - - hmac-sha2-512-etm@openssh.com - - hmac-sha2-256-etm@openssh.com + # - hmac-sha2-512-etm@openssh.com # NOTE: (CVE-2023-48795) + # - hmac-sha2-256-etm@openssh.com # NOTE: (CVE-2023-48795) - hmac-sha2-512 - hmac-sha2-256 -# KexAlgorithms (cis_ubuntu2204_rule_5_2_15) + - umac-128@openssh.com +# KexAlgorithms (cis_ubuntu2204_rule_5_1_12) cis_ubuntu2204_ssh_kex_algorithms: - curve25519-sha256@libssh.org - ecdh-sha2-nistp521 - ecdh-sha2-nistp384 - ecdh-sha2-nistp256 - diffie-hellman-group-exchange-sha256 -# address family, key alg, accept key types (cis_ubuntu2204_rule_5_2_23) -cis_ubuntu2204_ssh_address_family: "inet" -cis_ubuntu2204_ssh_host_key_algorithms: - - ssh-ed25519-cert-v01@openssh.com - - ssh-rsa-cert-v01@openssh.com - - ssh-ed25519 - - ssh-rsa - - ecdsa-sha2-nistp521-cert-v01@openssh.com - - ecdsa-sha2-nistp384-cert-v01@openssh.com - - ecdsa-sha2-nistp256-cert-v01@openssh.com - - ecdsa-sha2-nistp521 - - ecdsa-sha2-nistp384 - - ecdsa-sha2-nistp256 -cis_ubuntu2204_ssh_pubkey_accepted_key_types: - - ssh-ed25519 -# pw quality policies (cis_ubuntu2204_rule_5_4_1) -cis_ubuntu2204_pwquality: - - key: "minlen" - value: "14" + +# (cis_ubuntu2204_rule_5_3_*) +cis_ubuntu2204_faillock_deny: 5 +cis_ubuntu2204_faillock_unlock_time: 900 +cis_ubuntu2204_faillock_difok: 2 +cis_ubuntu2204_faillock_minlen: 14 +cis_ubuntu2204_password_complexity: + - key: "minclass" + value: "3" - key: "dcredit" value: "-1" - key: "ucredit" @@ -443,12 +466,22 @@ cis_ubuntu2204_pwquality: value: "-1" - key: "lcredit" value: "-1" -# (cis_ubuntu2204_rule_5_4_2) -cis_ubuntu2204_faillock_unlock_time: 600 -cis_ubuntu2204_remember_reuse: 5 -cis_ubuntu2204_encrypt_method: yescrypt # yescrypt | sha512 -cis_ubuntu2204_common_auth_success: 2 -cis_ubuntu2204_common_password_success: 2 +cis_ubuntu2204_faillock_maxrepeat: 3 +cis_ubuntu2204_faillock_maxsequence: 3 + +# in file (pwhistory.j2) +cis_ubuntu2204_pwhistory_remember: remember=24 +cis_ubuntu2204_pwhistory_enforce_for_root: enforce_for_root +cis_ubuntu2204_pwhistory_use_authtok: use_authtok + +# in file (unix.j2) and (cis_ubuntu2204_rule_5_3_3_4_3|cis_ubuntu2204_rule_5_4_1_4) +cis_ubuntu2204_unix_encrypt_method: yescrypt # yescrypt | sha512 +# in file (unix.j2) and (cis_ubuntu2204_rule_5_3_3_4_4) +cis_ubuntu2204_unix_use_authtok: "{{ cis_ubuntu2204_pwhistory_use_authtok }}" + +cis_ubuntu2204_password_pass_max_days: 365 +cis_ubuntu2204_password_pass_min_days: 1 +cis_ubuntu2204_password_pass_warn_age: 7 # AIDE cron settings (cis_ubuntu2204_rule_6_1_2) cis_ubuntu2204_aide_cron: @@ -485,7 +518,7 @@ cis_ubuntu2204_audit_admin_space_left_action: single # single | halt cis_ubuntu2204_audit_log_path: /var/log/audit # auditd group (cis_ubuntu2204_rule_6_3_4_3) cis_ubuntu2204_audit_log_group: adm -# in file (cis_6_3_3_3.rules.j2) +# in file (cis_6_3_3_3.rules.j2) and (cis_ubuntu2204_rule_5_2_3) cis_ubuntu2204_audit_sudo_log_file: /var/log/sudo.log # in file (cis_6_3_3_6.rules.j2|cis_6_3_3_7.rules.j2|cis_6_3_3_9.rules.j2|cis_6_3_3_10.rules.j2|cis_6_3_3_13.rules.j2) # in file (cis_6_3_3_15.rules.j2|cis_6_3_3_16.rules.j2|cis_6_3_3_17.rules.j2|cis_6_3_3_18.rules.j2|cis_6_3_3_19.rules.j2) diff --git a/tasks/pre.yml b/tasks/pre.yml index a7040c2..f939bd3 100644 --- a/tasks/pre.yml +++ b/tasks/pre.yml @@ -74,7 +74,7 @@ changed_when: false check_mode: false -- name: "PRE | 5.2 | check for 'ssh' service" +- name: "PRE | 5.1 | check for 'ssh' service" ansible.builtin.shell: | set -o pipefail && systemctl show ssh | grep LoadState | cut -d = -f 2 diff --git a/tasks/section1.yml b/tasks/section1.yml index 3e26855..c317cc5 100644 --- a/tasks/section1.yml +++ b/tasks/section1.yml @@ -426,7 +426,7 @@ ############################################################################################# Ensure GPG keys are configured. ############################################################################################# - {{ cis_ubuntu2204_apt_key_list.stdout_lines | join(', ') }} + {{ cis_ubuntu2204_apt_key_list.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} ############################################################################################# when: - cis_ubuntu2204_apt_key_list.stdout_lines is defined @@ -454,7 +454,7 @@ ############################################################################################# Ensure package manager repositories are configured. ############################################################################################# - {{ cis_ubuntu2204_apt_key_list.stdout_lines | join(', ') }} + {{ cis_ubuntu2204_apt_key_list.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} ############################################################################################# when: - cis_ubuntu2204_apt_key_list.stdout_lines is defined diff --git a/tasks/section2.yml b/tasks/section2.yml index d83b9e8..72f64e0 100644 --- a/tasks/section2.yml +++ b/tasks/section2.yml @@ -63,7 +63,7 @@ - Remove the package containing the service - -IF- the service's package is required for a dependency, stop and mask the service and/or socket ############################################################################################# - {{ cis_ubuntu2204_services_listening_on_network_interface.stdout_lines | join(', ') }} + {{ cis_ubuntu2204_services_listening_on_network_interface.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} ############################################################################################# when: - cis_ubuntu2204_services_listening_on_network_interface.stdout_lines is defined diff --git a/tasks/section5.yml b/tasks/section5.yml index 49d191b..050adb6 100644 --- a/tasks/section5.yml +++ b/tasks/section5.yml @@ -3,36 +3,37 @@ # ------------------------------------------------------------------------------ -- name: "SECTION5 | 5.2.1 | Ensure permissions on /etc/ssh/sshd_config are configured" +- name: "SECTION5 | 5.1.1 | Ensure permissions on /etc/ssh/sshd_config are configured (Automated)" ansible.builtin.file: dest: /etc/ssh/sshd_config owner: root group: root mode: "0600" when: - - cis_ubuntu2204_rule_5_2_1 + - cis_ubuntu2204_rule_5_1_1 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 - molecule-idempotence-notest -- name: "SECTION5 | 5.2.2 | Ensure permissions on SSH private host key files are configured" +- name: "SECTION5 | 5.1.2 | Ensure permissions on SSH private host key files are configured (Automated)" when: - - cis_ubuntu2204_rule_5_2_2 + - cis_ubuntu2204_rule_5_1_2 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 block: - - name: "SECTION5 | 5.2.2 | Ensure permissions on SSH private host key files are configured | find ssh_host_*_key" + - name: "SECTION5 | 5.1.2 | Ensure permissions on SSH private host key files are configured | find ssh_host_*_key" ansible.builtin.find: paths: /etc/ssh + file_type: file patterns: "ssh_host_*_key" register: cis_ubuntu2204_find_ssh_private_host_keys - - name: "SECTION5 | 5.2.2 | Ensure permissions on SSH private host key files are configured | set permissions" + - name: "SECTION5 | 5.1.2 | Ensure permissions on SSH private host key files are configured | set permissions" ansible.builtin.file: dest: "{{ item.path }}" owner: root @@ -40,21 +41,21 @@ mode: "0600" with_items: "{{ cis_ubuntu2204_find_ssh_private_host_keys.files }}" -- name: "SECTION5 | 5.2.3 | Ensure permissions on SSH public host key files are configured" +- name: "SECTION5 | 5.1.3 | Ensure permissions on SSH public host key files are configured (Automated)" when: - - cis_ubuntu2204_rule_5_2_3 + - cis_ubuntu2204_rule_5_1_3 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 block: - - name: "SECTION5 | 5.2.3 | Ensure permissions on SSH public host key files are configured | find ssh_host_*_key.pub" + - name: "SECTION5 | 5.1.3 | Ensure permissions on SSH public host key files are configured | find ssh_host_*_key.pub" ansible.builtin.find: paths: /etc/ssh patterns: "ssh_host_*_key.pub" register: cis_ubuntu2204_find_ssh_public_host_keys - - name: "SECTION5 | 5.2.3 | Ensure permissions on SSH public host key files are configured | set permissions" + - name: "SECTION5 | 5.1.3 | Ensure permissions on SSH public host key files are configured | set permissions" ansible.builtin.file: dest: "{{ item.path }}" owner: root @@ -62,17 +63,17 @@ mode: "0644" with_items: "{{ cis_ubuntu2204_find_ssh_public_host_keys.files }}" -- name: "SECTION5 | 5.2.4 | Ensure SSH access is limited" +- name: "SECTION5 | 5.1.4 | Ensure sshd access is configured (Automated)" when: - - cis_ubuntu2204_rule_5_2_4 + - cis_ubuntu2204_rule_5_1_4 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 - molecule-idempotence-notest block: - - name: "SECTION5 | 5.2.4 | Ensure SSH access is limited | AllowUsers" + - name: "SECTION5 | 5.1.4 | Ensure sshd access is configured | AllowUsers" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config regexp: "{{ cis_ubuntu2204_regex_base_search }}AllowUsers" @@ -82,7 +83,7 @@ mode: "0644" when: - cis_ubuntu2204_ssh_allow_users is defined - - name: "SECTION5 | 5.2.4 | Ensure SSH access is limited | AllowGroups" + - name: "SECTION5 | 5.1.4 | Ensure sshd access is configured | AllowGroups" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config regexp: "{{ cis_ubuntu2204_regex_base_search }}AllowGroups" @@ -92,7 +93,7 @@ mode: "0644" when: - cis_ubuntu2204_ssh_allow_groups is defined - - name: "SECTION5 | 5.2.4 | Ensure SSH access is limited | DenyUsers" + - name: "SECTION5 | 5.1.4 | Ensure sshd access is configured | DenyUsers" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config regexp: "{{ cis_ubuntu2204_regex_base_search }}DenyUsers" @@ -102,7 +103,7 @@ mode: "0644" when: - cis_ubuntu2204_ssh_deny_users is defined - - name: "SECTION5 | 5.2.4 | Ensure SSH access is limited | DenyGroups" + - name: "SECTION5 | 5.1.4 | Ensure sshd access is configured | DenyGroups" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config regexp: "{{ cis_ubuntu2204_regex_base_search }}DenyGroups" @@ -113,103 +114,113 @@ when: - cis_ubuntu2204_ssh_deny_groups is defined -- name: "SECTION5 | 5.2.5 | Ensure SSH LogLevel is appropriate" +- name: "SECTION5 | 5.1.5 | Ensure sshd Banner is configured (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}LogLevel" - line: "LogLevel {{ cis_ubuntu2204_ssh_log_level }}" + regexp: "{{ cis_ubuntu2204_regex_base_search }}Banner" + line: "Banner /etc/issue.net" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_5 + - cis_ubuntu2204_rule_5_1_5 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.6 | Ensure SSH PAM is enabled" +- name: "SECTION5 | 5.1.6 | Ensure sshd Ciphers are configured (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}UsePAM" - line: "UsePAM yes" + regexp: "{{ cis_ubuntu2204_regex_base_search }}Ciphers" + line: "Ciphers {{ cis_ubuntu2204_ssh_ciphers | join(',') }}" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_6 + - cis_ubuntu2204_rule_5_1_6 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.7 | Ensure SSH root login is disabled" - ansible.builtin.lineinfile: - dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}PermitRootLogin" - line: "PermitRootLogin {{ cis_ubuntu2204_ssh_permit_root_login }}" - state: present - create: true - mode: "0644" +- name: "SECTION5 | 5.1.7 | Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured (Automated)" when: - - cis_ubuntu2204_rule_5_2_7 + - cis_ubuntu2204_rule_5_1_7 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 + block: + - name: "SECTION5 | 5.1.7 | Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured | ClientAliveInterval" + ansible.builtin.lineinfile: + dest: /etc/ssh/sshd_config + regexp: "{{ cis_ubuntu2204_regex_base_search }}ClientAliveInterval" + line: "ClientAliveInterval {{ cis_ubuntu2204_ssh_client_alive_interval }}" + state: present + create: true + mode: "0644" + - name: "SECTION5 | 5.1.7 | Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured | ClientAliveCountMax" + ansible.builtin.lineinfile: + dest: /etc/ssh/sshd_config + regexp: "{{ cis_ubuntu2204_regex_base_search }}ClientAliveCountMax" + line: "ClientAliveCountMax {{ cis_ubuntu2204_ssh_client_alive_count_max }}" + state: present + create: true + mode: "0644" -- name: "SECTION5 | 5.2.8 | Ensure SSH HostbasedAuthentication is disabled" +- name: "SECTION5 | 5.1.8 | Ensure sshd DisableForwarding is enabled (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}HostbasedAuthentication" - line: "HostbasedAuthentication no" + regexp: "{{ cis_ubuntu2204_regex_base_search }}DisableForwarding" + line: "DisableForwarding yes" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_8 + - cis_ubuntu2204_rule_5_1_8 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 - - server_l1 + - rule_5_1 + - server_l2 - workstation_l1 -- name: "SECTION5 | 5.2.9 | Ensure SSH PermitEmptyPasswords is disabled" +- name: "SECTION5 | 5.1.9 | Ensure sshd GSSAPIAuthentication is disabled (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}PermitEmptyPasswords" - line: "PermitEmptyPasswords no" + regexp: "{{ cis_ubuntu2204_regex_base_search }}GSSAPIAuthentication" + line: "GSSAPIAuthentication no" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_9 + - cis_ubuntu2204_rule_5_1_9 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 - - server_l1 + - rule_5_1 + - server_l2 - workstation_l1 -- name: "SECTION5 | 5.2.10 | Ensure SSH PermitUserEnvironment is disabled" +- name: "SECTION5 | 5.1.10 | Ensure sshd HostbasedAuthentication is disabled (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}PermitUserEnvironment" - line: "PermitUserEnvironment no" + regexp: "{{ cis_ubuntu2204_regex_base_search }}HostbasedAuthentication" + line: "HostbasedAuthentication no" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_10 + - cis_ubuntu2204_rule_5_1_10 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.11 | Ensure SSH IgnoreRhosts is enabled" +- name: "SECTION5 | 5.1.11 | Ensure sshd IgnoreRhosts is enabled (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config regexp: "{{ cis_ubuntu2204_regex_base_search }}IgnoreRhosts" @@ -218,200 +229,192 @@ create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_11 + - cis_ubuntu2204_rule_5_1_11 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.12 | Ensure SSH X11 forwarding is disabled" +- name: "SECTION5 | 5.1.12 | Ensure sshd KexAlgorithms is configured (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}X11Forwarding" - line: "X11Forwarding no" + regexp: "{{ cis_ubuntu2204_regex_base_search }}KexAlgorithms" + line: "KexAlgorithms {{ cis_ubuntu2204_ssh_kex_algorithms | join(',') }}" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_12 + - cis_ubuntu2204_rule_5_1_12 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.13 | Ensure only strong Ciphers are used" +- name: "SECTION5 | 5.1.13 | Ensure sshd LoginGraceTime is configured (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}Ciphers" - line: "Ciphers {{ cis_ubuntu2204_ssh_ciphers | join(',') }}" + regexp: "{{ cis_ubuntu2204_regex_base_search }}LoginGraceTime" + line: "LoginGraceTime 60" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_13 + - cis_ubuntu2204_rule_5_1_13 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.14 | Ensure only strong MAC algorithms are used" +- name: "SECTION5 | 5.1.14 | Ensure sshd LogLevel is configured (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}MACs" - line: "MACs {{ cis_ubuntu2204_ssh_macs | join(',') }}" + regexp: "{{ cis_ubuntu2204_regex_base_search }}LogLevel" + line: "LogLevel {{ cis_ubuntu2204_ssh_log_level }}" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_14 + - cis_ubuntu2204_rule_5_1_14 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.15 | Ensure only strong Key Exchange algorithms are used" +- name: "SECTION5 | 5.1.15 | Ensure sshd MACs are configured (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}KexAlgorithms" - line: "KexAlgorithms {{ cis_ubuntu2204_ssh_kex_algorithms | join(',') }}" + regexp: "{{ cis_ubuntu2204_regex_base_search }}MACs" + line: "MACs {{ cis_ubuntu2204_ssh_macs | join(',') }}" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_15 + - cis_ubuntu2204_rule_5_1_15 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.16 | Ensure SSH AllowTcpForwarding is disabled" +- name: "SECTION5 | 5.1.16 | Ensure sshd MaxAuthTries is configured (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}AllowTcpForwarding" - line: "AllowTcpForwarding no" + regexp: "{{ cis_ubuntu2204_regex_base_search }}MaxAuthTries" + line: "MaxAuthTries {{ cis_ubuntu2204_ssh_max_auth_tries }}" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_16 + - cis_ubuntu2204_rule_5_1_16 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.17 | Ensure SSH warning banner is configured" +- name: "SECTION5 | 5.1.17 | Ensure sshd MaxSessions is configured (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}Banner" - line: "Banner /etc/issue.net" + regexp: "{{ cis_ubuntu2204_regex_base_search }}MaxSessions" + line: "MaxSessions {{ cis_ubuntu2204_ssh_max_sessions }}" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_17 + - cis_ubuntu2204_rule_5_1_17 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.18 | Ensure SSH MaxAuthTries is set to 4 or less" +- name: "SECTION5 | 5.1.18 | Ensure sshd MaxStartups is configured (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}MaxAuthTries" - line: "MaxAuthTries {{ cis_ubuntu2204_ssh_max_auth_tries }}" + regexp: "{{ cis_ubuntu2204_regex_base_search }}MaxStartups" + line: "MaxStartups 10:30:60" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_18 + - cis_ubuntu2204_rule_5_1_18 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.19 | Ensure SSH MaxStartups is configured" +- name: "SECTION5 | 5.1.19 | Ensure sshd PermitEmptyPasswords is disabled (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}MaxStartups" - line: "MaxStartups 10:30:60" + regexp: "{{ cis_ubuntu2204_regex_base_search }}PermitEmptyPasswords" + line: "PermitEmptyPasswords no" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_19 + - cis_ubuntu2204_rule_5_1_19 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.20 | Ensure SSH MaxSessions is set to 10 or less" +- name: "SECTION5 | 5.1.20 | Ensure sshd PermitRootLogin is disabled (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}MaxSessions" - line: "MaxSessions {{ cis_ubuntu2204_ssh_max_sessions }}" + regexp: "{{ cis_ubuntu2204_regex_base_search }}PermitRootLogin" + line: "PermitRootLogin {{ cis_ubuntu2204_ssh_permit_root_login }}" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_20 + - cis_ubuntu2204_rule_5_1_20 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.21 | Ensure SSH LoginGraceTime is set to one minute or less" +- name: "SECTION5 | 5.1.21 | Ensure sshd PermitUserEnvironment is disabled (Automated)" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}LoginGraceTime" - line: "LoginGraceTime 60" + regexp: "{{ cis_ubuntu2204_regex_base_search }}PermitUserEnvironment" + line: "PermitUserEnvironment no" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_2_21 + - cis_ubuntu2204_rule_5_1_21 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.2.22 | Ensure SSH Idle Timeout Interval is configured" +- name: "SECTION5 | 5.1.22 | Ensure sshd UsePAM is enabled (Automated)" + ansible.builtin.lineinfile: + dest: /etc/ssh/sshd_config + regexp: "{{ cis_ubuntu2204_regex_base_search }}UsePAM" + line: "UsePAM yes" + state: present + create: true + mode: "0644" when: - - cis_ubuntu2204_rule_5_2_22 + - cis_ubuntu2204_rule_5_1_22 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 - block: - - name: "SECTION5 | 5.2.22 | Ensure SSH Idle Timeout Interval is configured | ClientAliveInterval" - ansible.builtin.lineinfile: - dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}ClientAliveInterval" - line: "ClientAliveInterval {{ cis_ubuntu2204_ssh_client_alive_interval }}" - state: present - create: true - mode: "0644" - - name: "SECTION5 | 5.2.22 | Ensure SSH Idle Timeout Interval is configured | ClientAliveCountMax" - ansible.builtin.lineinfile: - dest: /etc/ssh/sshd_config - regexp: "{{ cis_ubuntu2204_regex_base_search }}ClientAliveCountMax" - line: "ClientAliveCountMax {{ cis_ubuntu2204_ssh_client_alive_count_max }}" - state: present - create: true - mode: "0644" -- name: "SECTION5 | 5.2.23 | Ensure SSH additional variables are configured" +# ------------------------------------------------------------------------------ + +- name: "SECTION5 | 5.1.23 | Ensure SSH additional variables are configured" ansible.builtin.lineinfile: dest: /etc/ssh/sshd_config regexp: "{{ item.reg }}" @@ -440,12 +443,14 @@ line: "PasswordAuthentication {{ cis_ubuntu2204_ssh_password_authentication }}" - reg: "{{ cis_ubuntu2204_regex_base_search }}ChallengeResponseAuthentication" line: "ChallengeResponseAuthentication no" - - reg: "{{ cis_ubuntu2204_regex_base_search }}GSSAPIAuthentication" - line: "GSSAPIAuthentication no" - reg: "{{ cis_ubuntu2204_regex_base_search }}GSSAPICleanupCredentials" line: "GSSAPICleanupCredentials yes" - reg: "{{ cis_ubuntu2204_regex_base_search }}AllowAgentForwarding" line: "AllowAgentForwarding {{ cis_ubuntu2204_ssh_allow_agent_forwarding }}" + - reg: "{{ cis_ubuntu2204_regex_base_search }}X11Forwarding" + line: "X11Forwarding {{ cis_ubuntu2204_ssh_x11_forwarding }}" + - reg: "{{ cis_ubuntu2204_regex_base_search }}AllowTcpForwarding" + line: "AllowTcpForwarding {{ cis_ubuntu2204_ssh_allow_tcp_forwarding }}" - reg: "{{ cis_ubuntu2204_regex_base_search }}PrintMotd" line: "PrintMotd no" - reg: "{{ cis_ubuntu2204_regex_base_search }}TCPKeepAlive" @@ -465,95 +470,143 @@ - reg: "{{ cis_ubuntu2204_regex_base_search }}HostKey /etc/ssh/ssh_host_rsa_key" line: "HostKey /etc/ssh/ssh_host_rsa_key" when: - - cis_ubuntu2204_rule_5_2_23 + - cis_ubuntu2204_rule_5_1_23 - service_status_ssh.stdout == "loaded" tags: - - rule_5_2 + - rule_5_1 - server_l1 - workstation_l1 # ------------------------------------------------------------------------------ -- name: "SECTION5 | 5.3.1 | Ensure sudo is installed" +- name: "SECTION5 | 5.2.1 | Ensure sudo is installed" ansible.builtin.apt: name: sudo state: present force_apt_get: true when: - - cis_ubuntu2204_rule_5_3_1 + - cis_ubuntu2204_rule_5_2_1 tags: - - rule_5_3 + - rule_5_2 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.3.2 | Ensure sudo commands use pty" - ansible.builtin.lineinfile: - dest: /etc/sudoers - regexp: '{{ cis_ubuntu2204_regex_base_search }}Defaults\s+use_pty' - line: "Defaults use_pty" - state: present - create: true - mode: "0400" - validate: "visudo -cf %s" +- name: "SECTION5 | 5.2.2 | Ensure sudo commands use pty" when: - - cis_ubuntu2204_rule_5_3_2 + - cis_ubuntu2204_rule_5_2_2 tags: - - rule_5_3 + - rule_5_2 - server_l1 - workstation_l1 + block: + - name: "SECTION5 | 5.2.2 | Ensure sudo commands use pty | update /etc/sudoers" + ansible.builtin.lineinfile: + dest: /etc/sudoers + regexp: '{{ cis_ubuntu2204_regex_base_search }}Defaults\s+use_pty' + line: "Defaults use_pty" + state: present + create: true + mode: "0400" + validate: "visudo -cf %s" + - name: "SECTION5 | 5.2.2 | Ensure sudo commands use pty | search files inside '/etc/sudoers.d/*'" + ansible.builtin.find: + paths: /etc/sudoers.d/ + patterns: "*" + recurse: yes + register: cis_ubuntu2204_sudoers_d_files + - name: "SECTION5 | 5.2.2 | Ensure sudo commands use pty | update '/etc/sudoers.d/*'" + ansible.builtin.lineinfile: + dest: "{{ item.path }}" + regexp: "!use_pty" + state: absent + validate: "visudo -cf %s" + with_items: "{{ cis_ubuntu2204_sudoers_d_files.files }}" -- name: "SECTION5 | 5.3.3 | Ensure sudo log file exists" +- name: "SECTION5 | 5.2.3 | Ensure sudo log file exists" ansible.builtin.lineinfile: dest: /etc/sudoers regexp: '{{ cis_ubuntu2204_regex_base_search }}Defaults\s+logfile.*' - line: 'Defaults logfile="/var/log/sudo.log"' + line: 'Defaults logfile="{{ cis_ubuntu2204_audit_sudo_log_file }}"' state: present create: true mode: "0400" validate: "visudo -cf %s" when: - - cis_ubuntu2204_rule_5_3_3 + - cis_ubuntu2204_rule_5_2_3 tags: - - rule_5_3 + - rule_5_2 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.3.4 | Ensure users must provide password for privilege escalation" - ansible.builtin.replace: - dest: /etc/sudoers - regexp: "(.*NOPASSWD.*)" - replace: '#\1' - validate: "visudo -cf %s" +- name: "SECTION5 | 5.2.4 | Ensure users must provide password for privilege escalation" when: - - cis_ubuntu2204_rule_5_3_4 + - cis_ubuntu2204_rule_5_2_4 tags: - - rule_5_3 + - rule_5_2 - server_l2 - workstation_l2 - - molecule-idempotence-notest + block: + - name: "SECTION5 | 5.2.4 | Ensure users must provide password for privilege escalation | update /etc/sudoers" + ansible.builtin.replace: + dest: /etc/sudoers + regexp: "(.*NOPASSWD.*)" + replace: '#\1' + validate: "visudo -cf %s" -- name: "SECTION5 | 5.3.5 | Ensure re-authentication for privilege escalation is not disabled globally" - ansible.builtin.replace: - dest: /etc/sudoers - regexp: "(.*!authenticate.*)" - replace: '# \1' - validate: "visudo -cf %s" + - name: "SECTION5 | 5.2.4 | Ensure users must provide password for privilege escalation | search files inside '/etc/sudoers.d/*'" + ansible.builtin.find: + paths: /etc/sudoers.d/ + patterns: "*" + recurse: yes + register: cis_ubuntu2204_sudoers_d_files + + - name: "SECTION5 | 5.2.4 | Ensure users must provide password for privilege escalation | update '/etc/sudoers.d/*'" + ansible.builtin.replace: + dest: "{{ item.path }}" + regexp: "(.*NOPASSWD.*)" + replace: '#\1' + validate: "visudo -cf %s" + with_items: "{{ cis_ubuntu2204_sudoers_d_files.files }}" + +- name: "SECTION5 | 5.2.5 | Ensure re-authentication for privilege escalation is not disabled globally" when: - - cis_ubuntu2204_rule_5_3_5 + - cis_ubuntu2204_rule_5_2_5 tags: - - rule_5_3 + - rule_5_2 - server_l1 - workstation_l1 + block: + - name: "SECTION5 | 5.2.5 | Ensure re-authentication for privilege escalation is not disabled globally | update /etc/sudoers" + ansible.builtin.replace: + dest: /etc/sudoers + regexp: "(.*!authenticate.*)" + replace: '# \1' + validate: "visudo -cf %s" + + - name: "SECTION5 | 5.2.5 | Ensure re-authentication for privilege escalation is not disabled globally | search files inside '/etc/sudoers.d/*'" + ansible.builtin.find: + paths: /etc/sudoers.d/ + patterns: "*" + recurse: yes + register: cis_ubuntu2204_sudoers_d_files + + - name: "SECTION5 | 5.2.5 | Ensure re-authentication for privilege escalation is not disabled globally | update '/etc/sudoers.d/*'" + ansible.builtin.replace: + dest: "{{ item.path }}" + regexp: "(.*!authenticate.*)" + replace: '# \1' + validate: "visudo -cf %s" + with_items: "{{ cis_ubuntu2204_sudoers_d_files.files }}" -- name: "SECTION5 | 5.3.6 | Ensure sudo authentication timeout is configured correctly" +- name: "SECTION5 | 5.2.6 | Ensure sudo authentication timeout is configured correctly" when: - - cis_ubuntu2204_rule_5_3_6 + - cis_ubuntu2204_rule_5_2_6 tags: - - rule_5_3 + - rule_5_2 - server_l1 - workstation_l1 block: - - name: "SECTION5 | 5.3.6 | Ensure sudo authentication timeout is configured correctly | env_reset, timestamp_timeout" + - name: "SECTION5 | 5.2.6 | Ensure sudo authentication timeout is configured correctly | env_reset, timestamp_timeout" ansible.builtin.lineinfile: dest: /etc/sudoers regexp: '{{ cis_ubuntu2204_regex_base_search }}Defaults\s+env_reset,\s+timestamp_timeout=.*' @@ -562,38 +615,38 @@ create: true mode: "0400" validate: "visudo -cf %s" - - name: "SECTION5 | 5.3.6 | Ensure sudo authentication timeout is configured correctly | timestamp_timeout" + - name: "SECTION5 | 5.2.6 | Ensure sudo authentication timeout is configured correctly | timestamp_timeout" ansible.builtin.lineinfile: dest: /etc/sudoers regexp: '{{ cis_ubuntu2204_regex_base_search }}Defaults\s+timestamp_timeout=.*' - line: "Defaults timestamp_timeout=15" - state: present + line: "#Defaults timestamp_timeout=15" + state: absent create: true mode: "0400" validate: "visudo -cf %s" - - name: "SECTION5 | 5.3.6 | Ensure sudo authentication timeout is configured correctly | env_reset" + - name: "SECTION5 | 5.2.6 | Ensure sudo authentication timeout is configured correctly | env_reset" ansible.builtin.lineinfile: dest: /etc/sudoers regexp: '{{ cis_ubuntu2204_regex_base_search }}Defaults\s+env_reset$' - line: "Defaults env_reset" - state: present + line: "#Defaults env_reset" + state: absent create: true mode: "0400" validate: "visudo -cf %s" -- name: "SECTION5 | 5.3.7 | Ensure access to the su command is restricted" +- name: "SECTION5 | 5.2.7 | Ensure access to the su command is restricted" when: - - cis_ubuntu2204_rule_5_3_7 + - cis_ubuntu2204_rule_5_2_7 tags: - - rule_5_3 + - rule_5_2 - server_l1 - workstation_l1 block: - - name: "SECTION5 | 5.3.7 | Ensure access to the su command is restricted | create group" + - name: "SECTION5 | 5.2.7 | Ensure access to the su command is restricted | create group" ansible.builtin.group: name: sugroup state: present - - name: "SECTION5 | 5.3.7 | Ensure access to the su command is restricted | set pam su" + - name: "SECTION5 | 5.2.7 | Ensure access to the su command is restricted | set pam su" ansible.builtin.lineinfile: dest: /etc/pam.d/su regexp: '{{ cis_ubuntu2204_regex_base_search }}auth\s+required\s+pam_wheel\.so\s+use_uid\s+group=' @@ -604,365 +657,803 @@ # ------------------------------------------------------------------------------ -- name: "SECTION5 | 5.4.1 | Ensure password creation requirements are configured" +- name: "SECTION5 | 5.3.1.1 | Ensure latest version of pam is installed" + ansible.builtin.apt: + name: libpam-runtime + state: latest + only_upgrade: true + force_apt_get: true when: - - cis_ubuntu2204_rule_5_4_1 + - cis_ubuntu2204_rule_5_3_1_1 tags: - - rule_5_4 + - rule_5_3_1 - server_l1 - workstation_l1 - block: - - name: "SECTION5 | 5.4.1 | Ensure password creation requirements are configured | install libpam-pwquality" - ansible.builtin.apt: - name: - - libpam-pwquality - - cracklib-runtime - state: present - force_apt_get: true - - name: "SECTION5 | 5.4.1 | Ensure password creation requirements are configured | set policy" - ansible.builtin.lineinfile: - dest: /etc/security/pwquality.conf - regexp: "{{ cis_ubuntu2204_regex_base_search }}{{ item.key }}" - line: "{{ item.key }} = {{ item.value }}" - state: present - create: true - mode: "0644" - loop: "{{ cis_ubuntu2204_pwquality | flatten(levels=1) }}" -- name: "SECTION5 | 5.4.2 | Ensure lockout for failed password attempts is configured" +- name: "SECTION5 | 5.3.1.2 | Ensure libpam-modules is installed" + ansible.builtin.apt: + name: libpam-modules + state: latest + only_upgrade: true + force_apt_get: true when: - - cis_ubuntu2204_rule_5_4_2 + - cis_ubuntu2204_rule_5_3_1_2 tags: - - rule_5_4 + - rule_5_3_1 - server_l1 - workstation_l1 - block: - - name: "SECTION5 | 5.4.2 | Ensure lockout for failed password attempts is configured | common-auth" - ansible.builtin.lineinfile: - dest: /etc/pam.d/common-auth - regexp: '{{ cis_ubuntu2204_regex_base_search }}auth(.*?)pam_faillock\.so preauth' - line: "auth required pam_faillock.so preauth" - state: present - create: true - mode: "0644" - insertbefore: "BOF" - - name: "SECTION5 | 5.4.2 | Ensure lockout for failed password attempts is configured | common-auth" - ansible.builtin.lineinfile: - dest: /etc/pam.d/common-auth - regexp: "{{ item.reg }}" - line: "{{ item.line }}" - state: present - create: true - mode: "0644" - insertafter: "{{ item.insertafter }}" - with_items: - - reg: '{{ cis_ubuntu2204_regex_base_search }}auth(.*?)pam_unix\.so nullok' - line: "auth [success={{ cis_ubuntu2204_common_auth_success }} default=ignore] pam_unix.so nullok" - insertafter: 'auth(.*?)pam_faillock\.so preauth' - - reg: '{{ cis_ubuntu2204_regex_base_search }}auth(.*?)pam_faillock\.so authfail ' - line: "auth [default=die] pam_faillock.so authfail " - insertafter: 'auth(.*?)pam_unix\.so nullok' - - reg: '{{ cis_ubuntu2204_regex_base_search }}auth(.*?)pam_faillock\.so authsucc ' - line: "auth sufficient pam_faillock.so authsucc " - insertafter: 'auth(.*?)pam_faillock\.so authfail ' - - reg: '{{ cis_ubuntu2204_regex_base_search }}auth(.*?)pam_deny\.so' - line: "auth requisite pam_deny.so" - insertafter: 'auth(.*?)pam_faillock\.so authsucc ' - - reg: '{{ cis_ubuntu2204_regex_base_search }}auth(.*?)pam_permit\.so' - line: "auth required pam_permit.so" - insertafter: 'auth(.*?)pam_deny\.so' - - reg: '{{ cis_ubuntu2204_regex_base_search }}auth(.*?)pam_cap\.so' - line: "auth optional pam_cap.so" - insertafter: 'auth(.*?)pam_permit\.so' - - name: "SECTION5 | 5.4.2 | Ensure lockout for failed password attempts is configured | common-auth" - ansible.builtin.lineinfile: - dest: /etc/pam.d/common-account - regexp: '{{ cis_ubuntu2204_regex_base_search }}account(.*?)pam_faillock\.so' - line: "account required pam_faillock.so" - state: present - create: true - mode: "0644" - insertafter: "EOF" - - name: "SECTION5 | 5.4.2 | Ensure lockout for failed password attempts is configured | faillock.conf" - ansible.builtin.lineinfile: - dest: /etc/security/faillock.conf - regexp: "{{ item.reg }}" - line: "{{ item.line }}" - state: present - create: true - mode: "0644" - with_items: - - reg: "{{ cis_ubuntu2204_regex_base_search }}deny" - line: "deny = 4" - - reg: "{{ cis_ubuntu2204_regex_base_search }}fail_interval" - line: "fail_interval = 900" - - reg: "{{ cis_ubuntu2204_regex_base_search }}unlock time" - line: "unlock time = {{ cis_ubuntu2204_faillock_unlock_time }}" -- name: "SECTION5 | 5.4.3 | Ensure password reuse is limited" - ansible.builtin.lineinfile: - dest: /etc/pam.d/common-password - regexp: '{{ cis_ubuntu2204_regex_base_search }}password(.*?)pam_unix\.so ' - line: > - password [success={{ cis_ubuntu2204_common_password_success }} default=ignore] pam_unix.so obscure - use_authtok try_first_pass {{ cis_ubuntu2204_encrypt_method | lower }} remember={{ cis_ubuntu2204_remember_reuse }} - state: present - create: true - mode: "0644" - insertafter: 'pam_pwquality\.so' +- name: "SECTION5 | 5.3.1.3 | Ensure libpam-pwquality is installed" + ansible.builtin.apt: + name: libpam-pwquality + state: latest + only_upgrade: true + force_apt_get: true when: - - cis_ubuntu2204_rule_5_4_3 + - cis_ubuntu2204_rule_5_3_1_3 tags: - - rule_5_4 + - rule_5_3_1 - server_l1 - workstation_l1 - - molecule-idempotence-notest -- name: "SECTION5 | 5.4.4 | Ensure password hashing algorithm is up to date with the latest standards" +# ------------------------------------------------------------------------------ + +- name: "SECTION5 | 5.3.2.1 | Ensure pam_unix module is enabled" + ansible.builtin.command: pam-auth-update --package --enable unix + changed_when: false + failed_when: false + check_mode: false when: - - cis_ubuntu2204_rule_5_4_4 + - cis_ubuntu2204_rule_5_3_2_1 tags: - - rule_5_4 + - rule_5_3_2 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.3.2.2 | Ensure pam_faillock module is enabled" + when: + - cis_ubuntu2204_rule_5_3_2_2 + tags: + - rule_5_3_2 - server_l1 - workstation_l1 - - molecule-idempotence-notest block: - - name: "SECTION5 | 5.4.4 | Ensure password hashing algorithm is up to date with the latest standards | common-password" - ansible.builtin.lineinfile: - dest: /etc/pam.d/common-password - regexp: '{{ cis_ubuntu2204_regex_base_search }}password(.*?)pam_unix\.so ' - line: > - password [success={{ cis_ubuntu2204_common_password_success }} default=ignore] pam_unix.so obscure - use_authtok try_first_pass {{ cis_ubuntu2204_encrypt_method | lower }} remember={{ cis_ubuntu2204_remember_reuse }} - state: present - create: true + - name: "SECTION5 | 5.3.2.2 | Ensure pam_faillock module is enabled | file faillock" + ansible.builtin.template: + src: pam/faillock + dest: /usr/share/pam-configs/faillock + owner: root + group: root mode: "0644" - insertafter: 'pam_pwquality\.so' - - name: "SECTION5 | 5.4.4 | Ensure password hashing algorithm is up to date with the latest standards | login.defs" - ansible.builtin.lineinfile: - dest: /etc/login.defs - regexp: "{{ cis_ubuntu2204_regex_base_search }}ENCRYPT_METHOD" - line: "ENCRYPT_METHOD {{ cis_ubuntu2204_encrypt_method | upper }}" - state: present - create: true + - name: "SECTION5 | 5.3.2.2 | Ensure pam_faillock module is enabled | file faillock-notify" + ansible.builtin.template: + src: pam/faillock-notify + dest: /usr/share/pam-configs/faillock-notify + owner: root + group: root mode: "0644" + - name: "SECTION5 | 5.3.2.2 | Ensure pam_faillock module is enabled | update profiles" + ansible.builtin.command: pam-auth-update --package --enable {{ item }} + with_items: + - faillock + - faillock-notify + changed_when: false + failed_when: false + check_mode: false -# NOTE: is need to implement something? -# - name: "SECTION5 | 5.4.5 | Ensure all current passwords uses the configured hashing algorithm" -# when: -# - cis_ubuntu2204_rule_5_4_5 -# tags: -# - rule_5_4 -# - server_l1 -# - workstation_l1 - -# ------------------------------------------------------------------------------ - -- name: "SECTION5 | 5.5.1.1 | Ensure minimum days between password changes is configured" - ansible.builtin.lineinfile: - dest: /etc/login.defs - regexp: "{{ cis_ubuntu2204_regex_base_search }}PASS_MIN_DAYS" - line: "PASS_MIN_DAYS 1" - state: present - create: true - mode: "0644" +- name: "SECTION5 | 5.3.2.3 | Ensure pam_pwquality module is enabled" when: - - cis_ubuntu2204_rule_5_5_1_1 + - cis_ubuntu2204_rule_5_3_2_3 tags: - - rule_5_5_1 + - rule_5_3_2 - server_l1 - workstation_l1 - -- name: "SECTION5 | 5.5.1.2 | Ensure password expiration is 365 days or less" - ansible.builtin.lineinfile: + block: + - name: "SECTION5 | 5.3.2.3 | Ensure pam_pwquality module is enabled | file pwquality" + ansible.builtin.template: + src: pam/pwquality + dest: /usr/share/pam-configs/pwquality + owner: root + group: root + mode: "0644" + - name: "SECTION5 | 5.3.2.3 | Ensure pam_pwquality module is enabled | update profiles" + ansible.builtin.command: pam-auth-update --package --enable pwquality + changed_when: false + failed_when: false + check_mode: false + +- name: "SECTION5 | 5.3.2.4 | Ensure pam_pwhistory module is enabled" + when: + - cis_ubuntu2204_rule_5_3_2_4 + tags: + - rule_5_3_2 + - server_l1 + - workstation_l1 + block: + - name: "SECTION5 | 5.3.2.4 | Ensure pam_pwhistory module is enabled | file pwhistory" + ansible.builtin.template: + src: pam/pwhistory.j2 + dest: /usr/share/pam-configs/pwhistory + owner: root + group: root + mode: "0644" + - name: "SECTION5 | 5.3.2.4 | Ensure pam_pwhistory module is enabled | update profiles" + ansible.builtin.command: pam-auth-update --package --enable pwhistory + changed_when: false + failed_when: false + check_mode: false + +# ------------------------------------------------------------------------------ + +- name: "SECTION5 | 5.3.3.1.1 | Ensure password failed attempts lockout is configured" + ansible.builtin.lineinfile: + dest: /etc/security/faillock.conf + regexp: "{{ cis_ubuntu2204_regex_base_search }}deny{{ cis_ubuntu2204_regex_base_search_equals }}" + line: "deny = {{ cis_ubuntu2204_faillock_deny }}" + state: present + create: true + mode: "0644" + when: + - cis_ubuntu2204_rule_5_3_3_1_1 + tags: + - rule_5_3_3_1 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.3.3.1.2 | Ensure password unlock time is configured" + ansible.builtin.lineinfile: + dest: /etc/security/faillock.conf + regexp: "{{ cis_ubuntu2204_regex_base_search }}unlock_time{{ cis_ubuntu2204_regex_base_search_equals }}" + line: "unlock_time = {{ cis_ubuntu2204_faillock_unlock_time }}" + state: present + create: true + mode: "0644" + when: + - cis_ubuntu2204_rule_5_3_3_1_2 + tags: + - rule_5_3_3_1 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.3.3.1.3 | Ensure password failed attempts lockout includes root account" + when: + - cis_ubuntu2204_rule_5_3_3_1_3 + tags: + - rule_5_3_3_1 + - server_l1 + - workstation_l1 + block: + - name: "SECTION5 | 5.3.3.1.3 | Ensure password failed attempts lockout includes root account | root_unlock_time" + ansible.builtin.lineinfile: + dest: /etc/security/faillock.conf + regexp: "{{ cis_ubuntu2204_regex_base_search }}root_unlock_time{{ cis_ubuntu2204_regex_base_search_equals }}" + line: "root_unlock_time = {{ cis_ubuntu2204_faillock_unlock_time }}" + state: present + create: true + mode: "0644" + - name: "SECTION5 | 5.3.3.1.3 | Ensure password failed attempts lockout includes root account | even_deny_root" + ansible.builtin.lineinfile: + dest: /etc/security/faillock.conf + regexp: "{{ cis_ubuntu2204_regex_base_search }}even_deny_root" + line: "even_deny_root" + state: present + create: true + mode: "0644" + +# ------------------------------------------------------------------------------ + +- name: "SECTION5 | 5.3.3.2.1 | Ensure password number of changed characters is configured" + ansible.builtin.lineinfile: + dest: /etc/security/pwquality.conf + regexp: "{{ cis_ubuntu2204_regex_base_search }}difok{{ cis_ubuntu2204_regex_base_search_equals }}" + line: "difok = {{ cis_ubuntu2204_faillock_difok }}" + state: present + create: true + mode: "0644" + when: + - cis_ubuntu2204_rule_5_3_3_2_1 + tags: + - rule_5_3_3_2 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.3.3.2.2 | Ensure password number of changed characters is configured" + ansible.builtin.lineinfile: + dest: /etc/security/pwquality.conf + regexp: "{{ cis_ubuntu2204_regex_base_search }}minlen{{ cis_ubuntu2204_regex_base_search_equals }}" + line: "minlen = {{ cis_ubuntu2204_faillock_minlen }}" + state: present + create: true + mode: "0644" + when: + - cis_ubuntu2204_rule_5_3_3_2_2 + tags: + - rule_5_3_3_2 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.3.3.2.3 | Ensure password complexity is configured" + ansible.builtin.lineinfile: + dest: /etc/security/pwquality.conf + regexp: "{{ cis_ubuntu2204_regex_base_search }}{{ item.key }}{{ cis_ubuntu2204_regex_base_search_equals }}" + line: "{{ item.key }} = {{ item.value }}" + state: present + create: true + mode: "0644" + loop: "{{ cis_ubuntu2204_password_complexity | flatten(levels=1) }}" + when: + - cis_ubuntu2204_rule_5_3_3_2_3 + tags: + - rule_5_3_3_2 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.3.3.2.4 | Ensure password same consecutive characters is configured" + ansible.builtin.lineinfile: + dest: /etc/security/pwquality.conf + regexp: "{{ cis_ubuntu2204_regex_base_search }}maxrepeat{{ cis_ubuntu2204_regex_base_search_equals }}" + line: "maxrepeat = {{ cis_ubuntu2204_faillock_maxrepeat }}" + state: present + create: true + mode: "0644" + when: + - cis_ubuntu2204_rule_5_3_3_2_4 + tags: + - rule_5_3_3_2 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.3.3.2.5 | Ensure password maximum sequential characters is configured" + ansible.builtin.lineinfile: + dest: /etc/security/pwquality.conf + regexp: "{{ cis_ubuntu2204_regex_base_search }}maxsequence{{ cis_ubuntu2204_regex_base_search_equals }}" + line: "maxsequence = {{ cis_ubuntu2204_faillock_maxsequence }}" + state: present + create: true + mode: "0644" + when: + - cis_ubuntu2204_rule_5_3_3_2_5 + tags: + - rule_5_3_3_2 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.3.3.2.6 | Ensure password dictionary check is enabled" + ansible.builtin.lineinfile: + dest: /etc/security/pwquality.conf + regexp: "{{ cis_ubuntu2204_regex_base_search }}dictcheck{{ cis_ubuntu2204_regex_base_search_equals }}" + line: "# dictcheck = 1" + state: present + create: true + mode: "0644" + when: + - cis_ubuntu2204_rule_5_3_3_2_6 + tags: + - rule_5_3_3_2 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.3.3.2.7 | Ensure password quality checking is enforced" + ansible.builtin.lineinfile: + dest: /etc/security/pwquality.conf + regexp: "{{ cis_ubuntu2204_regex_base_search }}enforcing{{ cis_ubuntu2204_regex_base_search_equals }}" + line: "# enforcing = 1" + state: present + create: true + mode: "0644" + when: + - cis_ubuntu2204_rule_5_3_3_2_7 + tags: + - rule_5_3_3_2 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.3.3.2.8 | Ensure password quality is enforced for the root user" + ansible.builtin.lineinfile: + dest: /etc/security/pwquality.conf + regexp: "{{ cis_ubuntu2204_regex_base_search }}enforce_for_root" + line: "enforce_for_root" + state: present + create: true + mode: "0644" + when: + - cis_ubuntu2204_rule_5_3_3_2_8 + tags: + - rule_5_3_3_2 + - server_l1 + - workstation_l1 + +# ------------------------------------------------------------------------------ + +- name: "SECTION5 | 5.3.3.3.1 | Ensure password history remember is configured" + when: + - cis_ubuntu2204_rule_5_3_3_3_1 + tags: + - rule_5_3_3_3 + - server_l1 + - workstation_l1 + block: + - name: "SECTION5 | 5.3.3.3.1 | Ensure password history remember is configured | file pwhistory" + ansible.builtin.template: + src: pam/pwhistory.j2 + dest: /usr/share/pam-configs/pwhistory + owner: root + group: root + mode: "0644" + - name: "SECTION5 | 5.3.3.3.1 | Ensure password history remember is configured | update profiles" + ansible.builtin.command: pam-auth-update --package --enable pwhistory + changed_when: false + failed_when: false + check_mode: false + +- name: "SECTION5 | 5.3.3.3.2 | Ensure password history is enforced for the root user" + when: + - cis_ubuntu2204_rule_5_3_3_3_2 + tags: + - rule_5_3_3_3 + - server_l1 + - workstation_l1 + block: + - name: "SECTION5 | 5.3.3.3.2 | Ensure password history is enforced for the root user | file pwhistory" + ansible.builtin.template: + src: pam/pwhistory.j2 + dest: /usr/share/pam-configs/pwhistory + owner: root + group: root + mode: "0644" + - name: "SECTION5 | 5.3.3.3.2 | Ensure password history is enforced for the root user | update profiles" + ansible.builtin.command: pam-auth-update --package --enable pwhistory + changed_when: false + failed_when: false + check_mode: false + +- name: "SECTION5 | 5.3.3.3.3 | Ensure pam_pwhistory includes use_authtok" + when: + - cis_ubuntu2204_rule_5_3_3_3_3 + tags: + - rule_5_3_3_3 + - server_l1 + - workstation_l1 + block: + - name: "SECTION5 | 5.3.3.3.3 | Ensure pam_pwhistory includes use_authtok | file pwhistory" + ansible.builtin.template: + src: pam/pwhistory.j2 + dest: /usr/share/pam-configs/pwhistory + owner: root + group: root + mode: "0644" + - name: "SECTION5 | 5.3.3.3.3 | Ensure pam_pwhistory includes use_authtok | update profiles" + ansible.builtin.command: pam-auth-update --package --enable pwhistory + changed_when: false + failed_when: false + check_mode: false + +# ------------------------------------------------------------------------------ + +- name: "SECTION5 | 5.3.3.4.1 | Ensure pam_unix does not include nullok" + when: + - cis_ubuntu2204_rule_5_3_3_4_1 + tags: + - rule_5_3_3_4 + - server_l1 + - workstation_l1 + block: + - name: "SECTION5 | 5.3.3.4.1 | Ensure pam_unix does not include nullok | file unix" + ansible.builtin.lineinfile: + path: /usr/share/pam-configs/unix + regexp: "^(.*)nullok(.*)$" + line: '\1\2' + backrefs: yes + - name: "SECTION5 | 5.3.3.4.1 | Ensure pam_unix does not include nullok | update profiles" + ansible.builtin.command: pam-auth-update --package --enable unix + changed_when: false + failed_when: false + check_mode: false + +- name: "SECTION5 | 5.3.3.4.2 | Ensure pam_unix does not include remember" + when: + - cis_ubuntu2204_rule_5_3_3_4_2 + tags: + - rule_5_3_3_4 + - server_l1 + - workstation_l1 + block: + - name: "SECTION5 | 5.3.3.4.2 | Ensure pam_unix does not include remember | file unix" + ansible.builtin.lineinfile: + path: /usr/share/pam-configs/unix + regexp: '^(.*)remember=\d+(.*)$' + line: '\1\2' + backrefs: yes + - name: "SECTION5 | 5.3.3.4.2 | Ensure pam_unix does not include remember | update profiles" + ansible.builtin.command: pam-auth-update --package --enable unix + changed_when: false + failed_when: false + check_mode: false + +- name: "SECTION5 | 5.3.3.4.3 | Ensure pam_unix includes a strong password hashing algorithm" + when: + - cis_ubuntu2204_rule_5_3_3_4_3 + tags: + - rule_5_3_3_4 + - server_l1 + - workstation_l1 + block: + - name: "SECTION5 | 5.3.3.4.3 | Ensure pam_unix includes a strong password hashing algorithm | file unix" + ansible.builtin.template: + src: pam/unix.j2 + dest: /usr/share/pam-configs/unix + owner: root + group: root + mode: "0644" + - name: "SECTION5 | 5.3.3.4.3 | Ensure pam_unix includes a strong password hashing algorithm | update profiles" + ansible.builtin.command: pam-auth-update --package --enable unix + changed_when: false + failed_when: false + check_mode: false + +- name: "SECTION5 | 5.3.3.4.4 | Ensure pam_unix includes use_authtok" + when: + - cis_ubuntu2204_rule_5_3_3_4_4 + tags: + - rule_5_3_3_4 + - server_l1 + - workstation_l1 + block: + - name: "SECTION5 | 5.3.3.4.4 | Ensure pam_unix includes use_authtok | file unix" + ansible.builtin.template: + src: pam/unix.j2 + dest: /usr/share/pam-configs/unix + owner: root + group: root + mode: "0644" + - name: "SECTION5 | 5.3.3.4.4 | Ensure pam_unix includes use_authtok | update profiles" + ansible.builtin.command: pam-auth-update --package --enable unix + changed_when: false + failed_when: false + check_mode: false + +# ------------------------------------------------------------------------------ + +- name: "SECTION5 | 5.4.1.1 | Ensure password expiration is configured" + ansible.builtin.lineinfile: dest: /etc/login.defs regexp: "{{ cis_ubuntu2204_regex_base_search }}PASS_MAX_DAYS" - line: "PASS_MAX_DAYS 365" + line: "PASS_MAX_DAYS {{ cis_ubuntu2204_password_pass_max_days }}" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_5_1_2 + - cis_ubuntu2204_rule_5_4_1_1 tags: - - rule_5_5_1 + - rule_5_4_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.5.1.3 | Ensure password expiration warning days is 7 or more" +- name: "SECTION5 | 5.4.1.2 | Ensure minimum password age is configured" + ansible.builtin.lineinfile: + dest: /etc/login.defs + regexp: "{{ cis_ubuntu2204_regex_base_search }}PASS_MIN_DAYS" + line: "PASS_MIN_DAYS {{ cis_ubuntu2204_password_pass_min_days }}" + state: present + create: true + mode: "0644" + when: + - cis_ubuntu2204_rule_5_4_1_2 + tags: + - rule_5_4_1 + - server_l2 + - workstation_l2 + +- name: "SECTION5 | 5.4.1.3 | Ensure password expiration warning days is configured" ansible.builtin.lineinfile: dest: /etc/login.defs regexp: "{{ cis_ubuntu2204_regex_base_search }}PASS_WARN_AGE" - line: "PASS_WARN_AGE 7" + line: "PASS_WARN_AGE {{ cis_ubuntu2204_password_pass_warn_age }}" + state: present + create: true + mode: "0644" + when: + - cis_ubuntu2204_rule_5_4_1_3 + tags: + - rule_5_4_1 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.4.1.4 | Ensure strong password hashing algorithm is configured" + ansible.builtin.lineinfile: + dest: /etc/login.defs + regexp: "{{ cis_ubuntu2204_regex_base_search }}ENCRYPT_METHOD" + line: "ENCRYPT_METHOD {{ cis_ubuntu2204_unix_encrypt_method | upper }}" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_5_1_3 + - cis_ubuntu2204_rule_5_4_1_4 tags: - - rule_5_5_1 + - rule_5_4_1 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.5.1.4 | Ensure inactive password lock is 30 days or less" +- name: "SECTION5 | 5.4.1.5 | Ensure inactive password lock is configured" ansible.builtin.lineinfile: dest: /etc/default/useradd - regexp: "{{ cis_ubuntu2204_regex_base_search }}INACTIVE" + regexp: "{{ cis_ubuntu2204_regex_base_search }}INACTIVE{{ cis_ubuntu2204_regex_base_search_equals }}" line: "INACTIVE=30" state: present create: true mode: "0644" when: - - cis_ubuntu2204_rule_5_5_1_4 + - cis_ubuntu2204_rule_5_4_1_5 + tags: + - rule_5_4_1 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.4.1.6 | Ensure all users last password change date is in the past" + when: + - cis_ubuntu2204_rule_5_4_1_6 + tags: + - rule_5_4_1 + - server_l1 + - workstation_l1 + block: + - name: "SECTION5 | 5.4.1.6 | Ensure all users last password change date is in the past | check last password changes" + ansible.builtin.shell: | + set -o pipefail + { + while IFS= read -r l_user; do + l_change=$(date -d "$(chage --list "$l_user" | grep '^Last password change' | cut -d: -f2 | grep -v 'never$')" +%s) + if [[ "$l_change" -gt "$(date +%s)" ]]; then + echo "User: \"$l_user\" last password change was \"$(chage --list "$l_user" | grep '^Last password change' | cut -d: -f2)\"" + fi + done < <(awk -F: '$2~/^\$.+\$/{print $1}' /etc/shadow) + } + args: + executable: /bin/bash + register: cis_ubuntu2204_user_last_pw_change + changed_when: false + failed_when: false + check_mode: false + - name: "SECTION5 | 5.4.1.6 | Ensure all users last password change date is in the past | print info" + ansible.builtin.debug: + msg: | + ############################################################################################# + Investigate any users with a password change date in the future and correct them. + Locking the account, expiring the password, or resetting the password manually may be appropriate. + ############################################################################################# + {{ cis_ubuntu2204_user_last_pw_change.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} + ############################################################################################# + when: + - cis_ubuntu2204_user_last_pw_change.stdout_lines is defined + - cis_ubuntu2204_user_last_pw_change.stdout_lines | length > 0 + +# ------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ + +- name: "SECTION5 | 5.4.2.1 | Ensure root is the only UID 0 account" + ansible.builtin.user: + name: root + uid: 0 + when: + - cis_ubuntu2204_rule_5_4_2_1 + tags: + - rule_5_4_2 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.4.2.2 | Ensure root is the only GID 0 account" + when: + - cis_ubuntu2204_rule_5_4_2_2 + tags: + - rule_5_4_2 + - server_l1 + - workstation_l1 + block: + - name: "SECTION5 | 5.4.2.2 | Ensure root is the only GID 0 account | user group" + ansible.builtin.user: + name: root + group: root + - name: "SECTION5 | 5.4.2.2 | Ensure root is the only GID 0 account | group gid" + ansible.builtin.group: + name: root + gid: 0 + +- name: "SECTION5 | 5.4.2.3 | Ensure group root is the only GID 0 group" + ansible.builtin.group: + name: root + gid: 0 + when: + - cis_ubuntu2204_rule_5_4_2_3 tags: - - rule_5_5_1 + - rule_5_4_2 - server_l1 - workstation_l1 -# - name: "SECTION5 | 5.5.1.5 | Ensure all users last password change date is in the past" -# when: -# - cis_ubuntu2204_rule_5_5_1_5 -# tags: -# - rule_5_5_1 -# - server_l1 -# - workstation_l1 +# - name: "SECTION5 | 5.4.2.4 | Ensure root password is set" -- name: "SECTION5 | 5.5.2 | Ensure system accounts are secured" +- name: "SECTION5 | 5.4.2.5 | Ensure root path integrity" when: - - cis_ubuntu2204_rule_5_5_2 + - cis_ubuntu2204_rule_5_4_2_5 tags: - - rule_5_5_1 + - rule_5_4_2 - server_l1 - workstation_l1 block: - - name: "SECTION5 | 5.5.2 | Ensure system accounts are secured | usermod -s" - ansible.builtin.shell: > - set -o pipefail && - awk -F: '$1!~/(root|sync|shutdown|halt|^\+)/ - && $3<'"$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)"' - && $7!~/((\/usr)?\/sbin\/nologin)/ - && $7!~/(\/bin)?\/false/ {print $1}' /etc/passwd - | while read -r user; do - usermod -s "$(which nologin)" "$user" - done + - name: "SECTION5 | 5.4.2.5 | Ensure root path integrity | get list for root path Integrity" + ansible.builtin.shell: | + set -o pipefail + { + l_output2="" + l_pmask="0022" + l_maxperm="$(printf '%o' $((0777 & ~$l_pmask)))" + l_root_path="$(sudo -Hiu root env | grep '^PATH' | cut -d= -f2)" + unset a_path_loc && IFS=":" read -ra a_path_loc <<<"$l_root_path" + grep -q "::" <<<"$l_root_path" && l_output2="$l_output2\n - root's path contains a empty directory (::)" + grep -Pq ":\h*$" <<<"$l_root_path" && l_output2="$l_output2\n - root's path contains a trailing (:)" + grep -Pq '(\h+|:)\.(:|\h*$)' <<<"$l_root_path" && l_output2="$l_output2\n - root's path contains current working directory (.)" + while read -r l_path; do + if [ -d "$l_path" ]; then + while read -r l_fmode l_fown; do + [ "$l_fown" != "root" ] && l_output2="$l_output2\n - Directory: \"$l_path\" is owned by: \"$l_fown\" should be owned by \"root\"" + [ $(($l_fmode & $l_pmask)) -gt 0 ] && l_output2="$l_output2\n - Directory: \"$l_path\" is mode: \"$l_fmode\" and should be mode: \"$l_maxperm\" or more restrictive" + done <<<"$(stat -Lc '%#a %U' "$l_path")" + else + l_output2="$l_output2\n - \"$l_path\" is not a directory" + fi + done <<<"$(printf "%s\n" "${a_path_loc[@]}")" + if [ -z "$l_output2" ]; then + echo -e "\n- Audit Result:\n *** PASS ***\n - Root's path is correctly configured\n" + else + echo -e "\n- Audit Result:\n ** FAIL **\n - * Reasons for audit failure * :\n$l_output2\n" + fi + } args: executable: "{{ cis_ubuntu2204_shell_executable }}" + register: cis_ubuntu2204_root_path_integrity changed_when: false - - name: "SECTION5 | 5.5.2 | Ensure system accounts are secured | usermod -L" - ansible.builtin.shell: > - set -o pipefail && - awk -F: '($1!~/(root|^\+)/ - && $3<'"$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)"') {print $1}' /etc/passwd - | xargs -I '{}' passwd -S '{}' - | awk '($2!~/LK?/) {print $1}' - | while read -r user; do - usermod -L "$user" - done + failed_when: false + check_mode: false + - name: "SECTION5 | 5.4.2.5 | Ensure root path integrity | print info" + ansible.builtin.debug: + msg: | + ############################################################################################# + Correct or justify any: + + - Locations that are not directories + - Empty directories (::) + - Trailing (:) + - Current working directory (.) + - Non root owned directories + - Directories that less restrictive than mode 0755 + ############################################################################################# + {{ cis_ubuntu2204_root_path_integrity.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} + ############################################################################################# + when: + - cis_ubuntu2204_root_path_integrity.stdout_lines is defined + - cis_ubuntu2204_root_path_integrity.stdout_lines | length > 0 + +- name: "SECTION5 | 5.4.2.6 | Ensure root user umask is configured" + ansible.builtin.lineinfile: + dest: "{{ item }}" + regexp: "{{ cis_ubuntu2204_regex_base_search }}UMASK" + line: "UMASK 0027" + state: present + create: true + mode: "0640" + with_items: + - /root/.bash_profile + - /root/.bashrc + when: + - cis_ubuntu2204_rule_5_4_2_6 + tags: + - rule_5_4_2 + - server_l1 + - workstation_l1 + +- name: "SECTION5 | 5.4.2.7 | Ensure system accounts do not have a valid login shell" + when: + - cis_ubuntu2204_rule_5_4_2_7 + tags: + - rule_5_4_2 + - server_l1 + - workstation_l1 + block: + - name: "SECTION5 | 5.4.2.7 | Ensure system accounts do not have a valid login shell | gather information" + ansible.builtin.shell: | + set -o pipefail + { + l_valid_shells="^($(awk -F\/ '$NF != "nologin" {print}' /etc/shells | sed -rn '/^\//{s,/,\\\\/,g;p}' | paste -s -d '|' -))$" + awk -v pat="$l_valid_shells" -F: '($1!~/^(root|halt|sync|shutdown|nfsnobody)$/ && ($3<'"$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)"' || $3 == 65534) && $(NF) ~ pat) {system ("usermod -s '"$(command -v nologin)"' " $1)}' /etc/passwd + } args: executable: "{{ cis_ubuntu2204_shell_executable }}" + register: cis_ubuntu2204_system_accounts_do_not_have_valid_login_shell changed_when: false + failed_when: false + check_mode: false + - name: "SECTION5 | 5.4.2.7 | Ensure system accounts do not have a valid login shell | print info" + ansible.builtin.debug: + msg: | + ############################################################################################# + Verify system accounts, except for root, halt, sync, shutdown or nfsnobody, do not have a valid login shell + ############################################################################################# + {{ cis_ubuntu2204_system_accounts_do_not_have_valid_login_shell.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} + ############################################################################################# + when: + - cis_ubuntu2204_system_accounts_do_not_have_valid_login_shell.stdout_lines is defined + - cis_ubuntu2204_system_accounts_do_not_have_valid_login_shell.stdout_lines | length > 0 -- name: "SECTION5 | 5.5.3 | Ensure default group for the root account is GID 0" - ansible.builtin.command: usermod -g 0 root +- name: "SECTION5 | 5.4.2.8 | Ensure accounts without a valid login shell are locked" + ansible.builtin.shell: | + set -o pipefail + { + l_valid_shells="^($(awk -F\/ '$NF != "nologin" {print}' /etc/shells | sed -rn '/^\//{s,/,\\\\/,g;p}' | paste -s -d '|' - ))$" + while IFS= read -r l_user; do + passwd -S "$l_user" | awk '$2 !~ /^L/ {system ("usermod -L " $1)}' + done < <(awk -v pat="$l_valid_shells" -F: '($1 != "root" && $(NF) !~ pat) {print $1}' /etc/passwd) + } + args: + executable: "{{ cis_ubuntu2204_shell_executable }}" changed_when: false - failed_when: false when: - - cis_ubuntu2204_rule_5_5_3 + - cis_ubuntu2204_rule_5_4_2_8 tags: - - rule_5_5_1 + - rule_5_4_2 - server_l1 - workstation_l1 -- name: "SECTION5 | 5.5.4 | Ensure default user umask is 027 or more restrictive" +# ------------------------------------------------------------------------------ + +- name: "SECTION5 | 5.4.3.1 | Ensure nologin is not listed in /etc/shells" + ansible.builtin.lineinfile: + path: /etc/shells + state: absent + regexp: "^.*nologin.*$" + when: + - cis_ubuntu2204_rule_5_4_3_1 + tags: + - rule_5_4_3 + - server_l2 + - workstation_l2 + +- name: "SECTION5 | 5.4.3.2 | Ensure default user shell timeout is configured" + ansible.builtin.lineinfile: + dest: "{{ item }}" + regexp: '{{ cis_ubuntu2204_regex_base_search }}readonly\s+TMOUT=\d+\s+;\s+export\sTMOUT' + line: "readonly TMOUT=900 ; export TMOUT" + state: present + create: true + mode: "0644" + with_items: + - /etc/bash.bashrc + - /etc/profile + - /etc/bashrc + - /etc/profile.d/99-tmout.sh when: - - cis_ubuntu2204_rule_5_5_4 + - cis_ubuntu2204_rule_5_4_3_2 tags: - - rule_5_5_1 + - rule_5_4_3 - server_l1 - workstation_l1 - block: - - name: "SECTION5 | 5.5.4 | Ensure default user umask is 027 or more restrictive | login.defs" - ansible.builtin.lineinfile: - dest: /etc/login.defs - regexp: "{{ cis_ubuntu2204_regex_base_search }}UMASK" - line: "UMASK 027" - state: present - create: true - mode: "0644" - - name: "SECTION5 | 5.5.4 | Ensure default user umask is 027 or more restrictive | bash.bashrc" - ansible.builtin.lineinfile: - dest: /etc/bash.bashrc - regexp: "{{ cis_ubuntu2204_regex_base_search }}umask" - line: "umask 027" - state: present - create: true - mode: "0644" - - name: "SECTION5 | 5.5.4 | Ensure default user umask is 027 or more restrictive | profile" - ansible.builtin.lineinfile: - dest: /etc/profile - regexp: "{{ cis_ubuntu2204_regex_base_search }}umask" - line: "umask 027" - state: present - create: true - mode: "0644" - - name: "SECTION5 | 5.5.4 | Ensure default user umask is 027 or more restrictive | 99-umask.sh" - ansible.builtin.lineinfile: - dest: /etc/profile.d/99-umask.sh - regexp: "{{ cis_ubuntu2204_regex_base_search }}umask" - line: "umask 027" - state: present - create: true - mode: "0644" -- name: "SECTION5 | 5.5.5 | Ensure default user shell timeout is 900 seconds or less" +- name: "SECTION5 | 5.4.3.3 | Ensure default user umask is configured" + ansible.builtin.lineinfile: + dest: "{{ item }}" + regexp: "{{ cis_ubuntu2204_regex_base_search }}UMASK" + line: "UMASK 0027" + state: present + create: true + mode: "0644" + with_items: + - /etc/profile + - /etc/bash.bashrc + # - /etc/pam.d/postlogin + - /etc/login.defs + # - /etc/default/login + - /etc/profile.d/99-umask.sh when: - - cis_ubuntu2204_rule_5_5_5 + - cis_ubuntu2204_rule_5_4_3_3 tags: - - rule_5_5_1 + - rule_5_4_3 - server_l1 - workstation_l1 - block: - - name: "SECTION5 | 5.5.5 | Ensure default user shell timeout is 900 seconds or less | bash.bashrc" - ansible.builtin.lineinfile: - dest: /etc/bash.bashrc - regexp: "{{ item.reg }}" - line: "{{ item.line }}" - state: present - create: true - mode: "0644" - with_items: - - reg: "{{ cis_ubuntu2204_regex_base_search }}TMOUT=" - line: "TMOUT=900" - - reg: "{{ cis_ubuntu2204_regex_base_search }}readonly TMOUT" - line: "readonly TMOUT" - - reg: "{{ cis_ubuntu2204_regex_base_search }}export TMOUT" - line: "export TMOUT" - - name: "SECTION5 | 5.5.5 | Ensure default user shell timeout is 900 seconds or less | profile" - ansible.builtin.lineinfile: - dest: /etc/profile - regexp: "{{ item.reg }}" - line: "{{ item.line }}" - state: present - create: true - mode: "0644" - with_items: - - reg: "{{ cis_ubuntu2204_regex_base_search }}TMOUT=" - line: "TMOUT=900" - - reg: "{{ cis_ubuntu2204_regex_base_search }}readonly TMOUT" - line: "readonly TMOUT" - - reg: "{{ cis_ubuntu2204_regex_base_search }}export TMOUT" - line: "export TMOUT" - - name: "SECTION5 | 5.5.5 | Ensure default user shell timeout is 900 seconds or less | 99-tmout.sh" - ansible.builtin.lineinfile: - dest: /etc/profile.d/99-tmout.sh - regexp: "{{ item.reg }}" - line: "{{ item.line }}" - state: present - create: true - mode: "0644" - with_items: - - reg: "{{ cis_ubuntu2204_regex_base_search }}TMOUT=" - line: "TMOUT=900" - - reg: "{{ cis_ubuntu2204_regex_base_search }}readonly TMOUT" - line: "readonly TMOUT" - - reg: "{{ cis_ubuntu2204_regex_base_search }}export TMOUT" - line: "export TMOUT" diff --git a/tasks/section7.yml b/tasks/section7.yml index 09bd3b7..32333be 100644 --- a/tasks/section7.yml +++ b/tasks/section7.yml @@ -209,7 +209,7 @@ ############################################################################################# Remove or set ownership and group ownership of these files and/or directories to an active user on the system as appropriate. ############################################################################################# - {{ cis_ubuntu2204_unowned_or_ungrouped_files_and_directories.stdout_lines | join(', ') }} + {{ cis_ubuntu2204_unowned_or_ungrouped_files_and_directories.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} ############################################################################################# when: - cis_ubuntu2204_unowned_or_ungrouped_files_and_directories.stdout_lines is defined @@ -244,7 +244,7 @@ Ensure that no rogue SUID or SGID programs have been introduced into the system. Review the files returned by the action in the Audit section and confirm the integrity of these binaries. ############################################################################################# - {{ cis_ubuntu2204_suid_executables.stdout_lines | join(', ') }} + {{ cis_ubuntu2204_suid_executables.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} ############################################################################################# when: - cis_ubuntu2204_suid_executables.stdout_lines is defined @@ -318,7 +318,7 @@ Analyze the output of the Audit step above and perform the appropriate action to correct any discrepancies found. ############################################################################################# - {{ cis_ubuntu2204_groups_for_passwd_exists_in_group.stdout_lines | join(', ') }} + {{ cis_ubuntu2204_groups_for_passwd_exists_in_group.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} ############################################################################################# when: - cis_ubuntu2204_groups_for_passwd_exists_in_group.stdout_lines is defined @@ -385,7 +385,7 @@ Based on the results of the audit script, establish unique UIDs and review all files owned by the shared UIDs to determine which UID they are supposed to belong to. ############################################################################################# - {{ cis_ubuntu2204_duplicate_uids.stdout_lines | join(', ') }} + {{ cis_ubuntu2204_duplicate_uids.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} ############################################################################################# when: - cis_ubuntu2204_duplicate_uids.stdout_lines is defined @@ -421,7 +421,7 @@ Based on the results of the audit script, establish unique GIDs and review all files owned by the shared GID to determine which group they are supposed to belong to. ############################################################################################# - {{ cis_ubuntu2204_duplicate_gids.stdout_lines | join(', ') }} + {{ cis_ubuntu2204_duplicate_gids.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} ############################################################################################# when: - cis_ubuntu2204_duplicate_gids.stdout_lines is defined @@ -457,7 +457,7 @@ Based on the results of the audit script, establish unique user names for the users. File ownerships will automatically reflect the change as long as the users have unique UIDs. ############################################################################################# - {{ cis_ubuntu2204_duplicate_user_names.stdout_lines | join(', ') }} + {{ cis_ubuntu2204_duplicate_user_names.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} ############################################################################################# when: - cis_ubuntu2204_duplicate_user_names.stdout_lines is defined @@ -493,7 +493,7 @@ Based on the results of the audit script, establish unique names for the user groups. File group ownerships will automatically reflect the change as long as the groups have unique GIDs. ############################################################################################# - {{ cis_ubuntu2204_duplicate_group_names.stdout_lines | join(', ') }} + {{ cis_ubuntu2204_duplicate_group_names.stdout_lines | join(cis_ubuntu2204_print_info_join_by) }} ############################################################################################# when: - cis_ubuntu2204_duplicate_group_names.stdout_lines is defined diff --git a/templates/pam/faillock b/templates/pam/faillock new file mode 100644 index 0000000..2423ace --- /dev/null +++ b/templates/pam/faillock @@ -0,0 +1,6 @@ +Name: Enable pam_faillock to deny access +Default: yes +Priority: 0 +Auth-Type: Primary +Auth: + [default=die] pam_faillock.so authfail diff --git a/templates/pam/faillock-notify b/templates/pam/faillock-notify new file mode 100644 index 0000000..20e294b --- /dev/null +++ b/templates/pam/faillock-notify @@ -0,0 +1,9 @@ +Name: Notify of failed login attempts and reset count upon success +Default: yes +Priority: 1024 +Auth-Type: Primary +Auth: + requisite pam_faillock.so preauth +Account-Type: Primary +Account: + required pam_faillock.so diff --git a/templates/pam/pwhistory.j2 b/templates/pam/pwhistory.j2 new file mode 100644 index 0000000..c7a2086 --- /dev/null +++ b/templates/pam/pwhistory.j2 @@ -0,0 +1,6 @@ +Name: pwhistory password history checking +Default: yes +Priority: 1024 +Password-Type: Primary +Password: + requisite pam_pwhistory.so {{ cis_ubuntu2204_pwhistory_remember }} {{ cis_ubuntu2204_pwhistory_enforce_for_root }} try_first_pass {{ cis_ubuntu2204_pwhistory_use_authtok }} diff --git a/templates/pam/pwquality b/templates/pam/pwquality new file mode 100644 index 0000000..493fcad --- /dev/null +++ b/templates/pam/pwquality @@ -0,0 +1,9 @@ +Name: Pwquality password strength checking +Default: yes +Priority: 1024 +Conflicts: cracklib +Password-Type: Primary +Password: + requisite pam_pwquality.so retry=3 +Password-Initial: + requisite pam_pwquality.so retry=3 diff --git a/templates/pam/unix.j2 b/templates/pam/unix.j2 new file mode 100644 index 0000000..8587c46 --- /dev/null +++ b/templates/pam/unix.j2 @@ -0,0 +1,23 @@ +Name: Unix authentication +Default: yes +Priority: 256 +Auth-Type: Primary +Auth: + [success=end default=ignore] pam_unix.so{{ ' nullok' if cis_ubuntu2204_rule_5_3_3_4_1 else '' }} try_first_pass +Auth-Initial: + [success=end default=ignore] pam_unix.so{{ ' nullok' if cis_ubuntu2204_rule_5_3_3_4_1 else '' }} +Account-Type: Primary +Account: + [success=end new_authtok_reqd=done default=ignore] pam_unix.so +Account-Initial: + [success=end new_authtok_reqd=done default=ignore] pam_unix.so +Session-Type: Additional +Session: + required pam_unix.so +Session-Initial: + required pam_unix.so +Password-Type: Primary +Password: + [success=end default=ignore] pam_unix.so obscure {{ cis_ubuntu2204_unix_use_authtok }} try_first_pass {{ cis_ubuntu2204_unix_encrypt_method | lower }} +Password-Initial: + [success=end default=ignore] pam_unix.so obscure {{ cis_ubuntu2204_unix_encrypt_method | lower }}