diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/ansible/shared.yml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/ansible/shared.yml new file mode 100644 index 00000000000..b44c91cbf4a --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/ansible/shared.yml @@ -0,0 +1,150 @@ +# platform = Red Hat Virtualization 4,multi_platform_fedora,multi_platform_rhel +# reboot = false +# strategy = configure +# complexity = low +# disruption = medium + +- name: Check for existing pam_pwquality.so entry + ansible.builtin.lineinfile: + path: "/etc/pam.d/password-auth" + create: no + regexp: '^password.*pam_pwquality.so.*' + state: absent + check_mode: true + changed_when: false + register: result_pam_pwquality_present + +- name: Check if system relies on authselect + ansible.builtin.stat: + path: /usr/bin/authselect + register: result_authselect_present + +- name: "Remediation where authselect tool is present" + block: + - name: Check the integrity of the current authselect profile + ansible.builtin.command: + cmd: authselect check + register: result_authselect_check_cmd + changed_when: false + ignore_errors: true + + - name: Informative message based on the authselect integrity check result + ansible.builtin.assert: + that: + - result_authselect_check_cmd is success + fail_msg: + - authselect integrity check failed. Remediation aborted! + - This remediation could not be applied because the authselect profile is not intact. + - It is not recommended to manually edit the PAM files when authselect is available. + - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. + success_msg: + - authselect integrity check passed + + - name: Get authselect current profile + ansible.builtin.shell: + cmd: authselect current -r | awk '{ print $1 }' + register: result_authselect_profile + changed_when: false + when: + - result_authselect_check_cmd is success + + - name: Define the current authselect profile as a local fact + ansible.builtin.set_fact: + authselect_current_profile: "{{ result_authselect_profile.stdout }}" + authselect_custom_profile: "{{ result_authselect_profile.stdout }}" + when: + - result_authselect_profile is not skipped + - result_authselect_profile.stdout is match("custom/") + + - name: Define the new authselect custom profile as a local fact + ansible.builtin.set_fact: + authselect_current_profile: "{{ result_authselect_profile.stdout }}" + authselect_custom_profile: "custom/hardening" + when: + - result_authselect_profile is not skipped + - result_authselect_profile.stdout is not match("custom/") + + - name: Get authselect current features to also enable them in the custom profile + ansible.builtin.shell: + cmd: authselect current | tail -n+3 | awk '{ print $2 }' + register: result_authselect_features + changed_when: false + when: + - result_authselect_profile is not skipped + - authselect_current_profile is not match("custom/") + + - name: Check if any custom profile with the same name was already created in the past + ansible.builtin.stat: + path: /etc/authselect/{{ authselect_custom_profile }} + register: result_authselect_custom_profile_present + changed_when: false + when: + - authselect_current_profile is not match("custom/") + + - name: Create a custom profile based on the current profile + ansible.builtin.command: + cmd: authselect create-profile hardening -b sssd + when: + - result_authselect_check_cmd is success + - authselect_current_profile is not match("custom/") + - not result_authselect_custom_profile_present.stat.exists + + - name: Ensure the desired configuration is present in the custom profile + ansible.builtin.lineinfile: + dest: "/etc/authselect/{{ authselect_custom_profile }}/password-auth" + insertbefore: ^password.*sufficient.*pam_unix.so.* + line: "password requisite pam_pwquality.so" + when: + - result_authselect_profile is not skipped + - result_pam_pwquality_present.found == 0 + + - name: Ensure a backup of current authselect profile before selecting the custom profile + ansible.builtin.command: + cmd: authselect apply-changes -b --backup=before-pwquality-hardening.backup + register: result_authselect_backup + when: + - result_authselect_check_cmd is success + - result_authselect_profile is not skipped + - authselect_current_profile is not match("custom/") + - authselect_custom_profile is not match(authselect_current_profile) + + - name: Ensure the custom profile is selected + ansible.builtin.command: + cmd: authselect select {{ authselect_custom_profile }} --force + register: result_pam_authselect_select_profile + when: + - result_authselect_check_cmd is success + - result_authselect_profile is not skipped + - authselect_current_profile is not match("custom/") + - authselect_custom_profile is not match(authselect_current_profile) + + - name: Restore the authselect features in the custom profile + ansible.builtin.command: + cmd: authselect enable-feature {{ item }} + loop: "{{ result_authselect_features.stdout_lines }}" + when: + - result_authselect_profile is not skipped + - result_authselect_features is not skipped + - result_pam_authselect_select_profile is not skipped + + - name: Ensure the custom profile changes are applied + ansible.builtin.command: + cmd: authselect apply-changes -b --backup=after-pwquality-hardening.backup + when: + - result_authselect_check_cmd is success + - result_authselect_profile is not skipped + when: + - result_authselect_present.stat.exists + +# For systems without authselect +- name: "Remediation where authselect tool is not present and PAM files are directly edited" + block: + - name: Ensure the desired configuration is present in the custom profile + ansible.builtin.lineinfile: + dest: "/etc/pam.d/password-auth" + insertbefore: ^password.*sufficient.*pam_unix.so.* + line: "password requisite pam_pwquality.so" + when: + - result_pam_pwquality_present.found == 0 + when: + - not result_authselect_present.stat.exists diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/bash/shared.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/bash/shared.sh new file mode 100644 index 00000000000..d2fca2a79ca --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/bash/shared.sh @@ -0,0 +1,41 @@ +# platform = Red Hat Virtualization 4,multi_platform_fedora,multi_platform_rhel + +PAM_FILE="password-auth" + +if [ -f /usr/bin/authselect ]; then + if authselect check; then + CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }') + # Standard profiles delivered with authselect should not be modified. + # If not already in use, a custom profile is created preserving the enabled features. + if [[ ! $CURRENT_PROFILE == custom/* ]]; then + ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }') + authselect create-profile hardening -b $CURRENT_PROFILE + CURRENT_PROFILE="custom/hardening" + # Ensure a backup before changing the profile + authselect apply-changes -b --backup=before-pwquality-hardening.backup + authselect select $CURRENT_PROFILE + for feature in $ENABLED_FEATURES; do + authselect enable-feature $feature; + done + fi + # Include the desired configuration in the custom profile + CUSTOM_FILE="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE" + # The line should be included on the top password section + if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $CUSTOM_FILE) -eq 0 ]; then + sed -i --follow-symlinks '0,/^password.*/s/^password.*/password requisite pam_pwquality.so\n&/' $CUSTOM_FILE + fi + authselect apply-changes -b --backup=after-pwquality-hardening.backup + else + echo " +authselect integrity check failed. Remediation aborted! +This remediation could not be applied because the authselect profile is not intact. +It is not recommended to manually edit the PAM files when authselect is available. +In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended." + false + fi +else + FILE_PATH="/etc/pam.d/$PAM_FILE" + if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $FILE_PATH) -eq 0 ]; then + sed -i --follow-symlinks '0,/^password.*/s/^password.*/password requisite pam_pwquality.so\n&/' $FILE_PATH + fi +fi diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/oval/shared.xml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/oval/shared.xml new file mode 100644 index 00000000000..84f32456beb --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/oval/shared.xml @@ -0,0 +1,21 @@ + + + {{{ oval_metadata("The PAM module pam_pwquality is used in password-auth") }}} + + + + + + + /etc/pam.d/password-auth + ^password[\s]*requisite[\s]*pam_pwquality\.so + 1 + + + + + + diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/rule.yml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/rule.yml new file mode 100644 index 00000000000..6c7bb1ad7a0 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/rule.yml @@ -0,0 +1,35 @@ +documentation_complete: true + +prodtype: fedora,rhel7,rhel8,rhel9,rhv4 + +title: 'Ensure PAM password complexity module is enabled in password-auth' + +description: |- + To enable PAM password complexity in password-auth file: + Edit the password section in + /etc/pam.d/password-auth to show + password requisite pam_pwquality.so. + +rationale: |- + Enabling PAM password complexity permits to enforce strong passwords and consequently + makes the system less prone to dictionary attacks. + +severity: medium + +identifiers: + cce@rhel7: CCE-85876-1 + cce@rhel8: CCE-85877-9 + cce@rhel9: CCE-85878-7 + +references: + stigid@rhel8: RHEL-08-020100 + +ocil_clause: 'pam_pwquality.so is not enabled in password-auth' + +ocil: |- + To check if pam_pwhistory.so is enabled in password-auth, run the following command: +
$ grep pam_pwquality /etc/pam.d/password-auth
+ The output should be similar to the following: +
password    requisite                                    pam_pwquality.so
+ +platform: pam diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_commented_entry.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_commented_entry.fail.sh new file mode 100644 index 00000000000..3d696c36b76 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_commented_entry.fail.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# packages = authselect +# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora + +authselect create-profile hardening -b sssd +CUSTOM_PROFILE="custom/hardening" +authselect select $CUSTOM_PROFILE --force + +CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/password-auth" +sed -i --follow-symlinks -e '/^password\s*requisite\s*pam_pwquality\.so/ s/^#*/#/g' $CUSTOM_SYSTEM_AUTH +authselect apply-changes -b diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_correct_entry.pass.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_correct_entry.pass.sh new file mode 100644 index 00000000000..0435899262b --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_correct_entry.pass.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# packages = authselect +# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora + +authselect create-profile hardening -b sssd +CUSTOM_PROFILE="custom/hardening" +authselect select $CUSTOM_PROFILE --force + +CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/password-auth" +if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $CUSTOM_SYSTEM_AUTH) -eq 0 ]; then + sed -i --follow-symlinks '0,/^password.*/s/^password.*/password requisite pam_pwquality.so\n&/' $CUSTOM_SYSTEM_AUTH +fi +authselect apply-changes -b diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_missing_entry.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_missing_entry.fail.sh new file mode 100644 index 00000000000..472616a51f6 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_missing_entry.fail.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# packages = authselect +# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora + +authselect create-profile hardening -b sssd +CUSTOM_PROFILE="custom/hardening" +authselect select $CUSTOM_PROFILE --force + +CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/password-auth" +sed -i --follow-symlinks '/^password\s*requisite\s*pam_pwquality\.so/d' $CUSTOM_SYSTEM_AUTH +authselect apply-changes -b diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_modified_pam.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_modified_pam.fail.sh new file mode 100644 index 00000000000..59f9d6f77c4 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/authselect_modified_pam.fail.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# packages = authselect +# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora +# remediation = none + +SYSTEM_AUTH_FILE="/etc/pam.d/password-auth" + +# This modification will break the integrity checks done by authselect. +sed -i --follow-symlinks -e '/^password\s*requisite\s*pam_pwquality\.so/ s/^#*/#/g' $SYSTEM_AUTH_FILE diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/correct_entry.pass.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/correct_entry.pass.sh new file mode 100644 index 00000000000..71f87b19045 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/correct_entry.pass.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# packages = pam +# platform = Red Hat Enterprise Linux 7,Red Hat Virtualization 4,multi_platform_fedora + +config_file=/etc/pam.d/password-auth +if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $config_file) -eq 0 ]; then + sed -i --follow-symlinks '0,/^password.*/s/^password.*/password requisite pam_pwquality.so\n&/' $config_file +fi diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/missing_entry.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/missing_entry.fail.sh new file mode 100644 index 00000000000..95b73b24d26 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_password_auth/tests/missing_entry.fail.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# platform = Red Hat Enterprise Linux 7,Red Hat Virtualization 4,multi_platform_fedora +# packages = pam + +config_file=/etc/pam.d/password-auth + +sed -i --follow-symlinks '/^password\s*requisite\s*pam_pwquality\.so/d' $config_file diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/ansible/shared.yml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/ansible/shared.yml new file mode 100644 index 00000000000..13cd20458ed --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/ansible/shared.yml @@ -0,0 +1,150 @@ +# platform = Red Hat Virtualization 4,multi_platform_fedora,multi_platform_rhel +# reboot = false +# strategy = configure +# complexity = low +# disruption = medium + +- name: Check for existing pam_pwquality.so entry + ansible.builtin.lineinfile: + path: "/etc/pam.d/system-auth" + create: no + regexp: '^password.*pam_pwquality.so.*' + state: absent + check_mode: true + changed_when: false + register: result_pam_pwquality_present + +- name: Check if system relies on authselect + ansible.builtin.stat: + path: /usr/bin/authselect + register: result_authselect_present + +- name: "Remediation where authselect tool is present" + block: + - name: Check the integrity of the current authselect profile + ansible.builtin.command: + cmd: authselect check + register: result_authselect_check_cmd + changed_when: false + ignore_errors: true + + - name: Informative message based on the authselect integrity check result + ansible.builtin.assert: + that: + - result_authselect_check_cmd is success + fail_msg: + - authselect integrity check failed. Remediation aborted! + - This remediation could not be applied because the authselect profile is not intact. + - It is not recommended to manually edit the PAM files when authselect is available. + - In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended. + success_msg: + - authselect integrity check passed + + - name: Get authselect current profile + ansible.builtin.shell: + cmd: authselect current -r | awk '{ print $1 }' + register: result_authselect_profile + changed_when: false + when: + - result_authselect_check_cmd is success + + - name: Define the current authselect profile as a local fact + ansible.builtin.set_fact: + authselect_current_profile: "{{ result_authselect_profile.stdout }}" + authselect_custom_profile: "{{ result_authselect_profile.stdout }}" + when: + - result_authselect_profile is not skipped + - result_authselect_profile.stdout is match("custom/") + + - name: Define the new authselect custom profile as a local fact + ansible.builtin.set_fact: + authselect_current_profile: "{{ result_authselect_profile.stdout }}" + authselect_custom_profile: "custom/hardening" + when: + - result_authselect_profile is not skipped + - result_authselect_profile.stdout is not match("custom/") + + - name: Get authselect current features to also enable them in the custom profile + ansible.builtin.shell: + cmd: authselect current | tail -n+3 | awk '{ print $2 }' + register: result_authselect_features + changed_when: false + when: + - result_authselect_profile is not skipped + - authselect_current_profile is not match("custom/") + + - name: Check if any custom profile with the same name was already created in the past + ansible.builtin.stat: + path: /etc/authselect/{{ authselect_custom_profile }} + register: result_authselect_custom_profile_present + changed_when: false + when: + - authselect_current_profile is not match("custom/") + + - name: Create a custom profile based on the current profile + ansible.builtin.command: + cmd: authselect create-profile hardening -b sssd + when: + - result_authselect_check_cmd is success + - authselect_current_profile is not match("custom/") + - not result_authselect_custom_profile_present.stat.exists + + - name: Ensure the desired configuration is present in the custom profile + ansible.builtin.lineinfile: + dest: "/etc/authselect/{{ authselect_custom_profile }}/system-auth" + insertbefore: ^password.*sufficient.*pam_unix.so.* + line: "password requisite pam_pwquality.so" + when: + - result_authselect_profile is not skipped + - result_pam_pwquality_present.found == 0 + + - name: Ensure a backup of current authselect profile before selecting the custom profile + ansible.builtin.command: + cmd: authselect apply-changes -b --backup=before-pwquality-hardening.backup + register: result_authselect_backup + when: + - result_authselect_check_cmd is success + - result_authselect_profile is not skipped + - authselect_current_profile is not match("custom/") + - authselect_custom_profile is not match(authselect_current_profile) + + - name: Ensure the custom profile is selected + ansible.builtin.command: + cmd: authselect select {{ authselect_custom_profile }} --force + register: result_pam_authselect_select_profile + when: + - result_authselect_check_cmd is success + - result_authselect_profile is not skipped + - authselect_current_profile is not match("custom/") + - authselect_custom_profile is not match(authselect_current_profile) + + - name: Restore the authselect features in the custom profile + ansible.builtin.command: + cmd: authselect enable-feature {{ item }} + loop: "{{ result_authselect_features.stdout_lines }}" + when: + - result_authselect_profile is not skipped + - result_authselect_features is not skipped + - result_pam_authselect_select_profile is not skipped + + - name: Ensure the custom profile changes are applied + ansible.builtin.command: + cmd: authselect apply-changes -b --backup=after-pwquality-hardening.backup + when: + - result_authselect_check_cmd is success + - result_authselect_profile is not skipped + when: + - result_authselect_present.stat.exists + +# For systems without authselect +- name: "Remediation where authselect tool is not present and PAM files are directly edited" + block: + - name: Ensure the desired configuration is present in the custom profile + ansible.builtin.lineinfile: + dest: "/etc/pam.d/system-auth" + insertbefore: ^password.*sufficient.*pam_unix.so.* + line: "password requisite pam_pwquality.so" + when: + - result_pam_pwquality_present.found == 0 + when: + - not result_authselect_present.stat.exists diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/bash/shared.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/bash/shared.sh new file mode 100644 index 00000000000..9a7972a3f93 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/bash/shared.sh @@ -0,0 +1,41 @@ +# platform = Red Hat Virtualization 4,multi_platform_fedora,multi_platform_rhel + +PAM_FILE="system-auth" + +if [ -f /usr/bin/authselect ]; then + if authselect check; then + CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }') + # Standard profiles delivered with authselect should not be modified. + # If not already in use, a custom profile is created preserving the enabled features. + if [[ ! $CURRENT_PROFILE == custom/* ]]; then + ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }') + authselect create-profile hardening -b $CURRENT_PROFILE + CURRENT_PROFILE="custom/hardening" + # Ensure a backup before changing the profile + authselect apply-changes -b --backup=before-pwquality-hardening.backup + authselect select $CURRENT_PROFILE + for feature in $ENABLED_FEATURES; do + authselect enable-feature $feature; + done + fi + # Include the desired configuration in the custom profile + CUSTOM_FILE="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE" + # The line should be included on the top password section + if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $CUSTOM_FILE) -eq 0 ]; then + sed -i --follow-symlinks '0,/^password.*/s/^password.*/password requisite pam_pwquality.so\n&/' $CUSTOM_FILE + fi + authselect apply-changes -b --backup=after-pwquality-hardening.backup + else + echo " +authselect integrity check failed. Remediation aborted! +This remediation could not be applied because the authselect profile is not intact. +It is not recommended to manually edit the PAM files when authselect is available. +In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended." + false + fi +else + FILE_PATH="/etc/pam.d/$PAM_FILE" + if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $FILE_PATH) -eq 0 ]; then + sed -i --follow-symlinks '0,/^password.*/s/^password.*/password requisite pam_pwquality.so\n&/' $FILE_PATH + fi +fi diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/oval/shared.xml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/oval/shared.xml new file mode 100644 index 00000000000..f8d241f1ff2 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/oval/shared.xml @@ -0,0 +1,21 @@ + + + {{{ oval_metadata("The PAM module pam_pwquality is used in system-auth") }}} + + + + + + + /etc/pam.d/system-auth + ^password[\s]*requisite[\s]*pam_pwquality\.so + 1 + + + + + + diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/rule.yml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/rule.yml new file mode 100644 index 00000000000..ea42ff9b07a --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/rule.yml @@ -0,0 +1,35 @@ +documentation_complete: true + +prodtype: fedora,rhel7,rhel8,rhel9,rhv4 + +title: 'Ensure PAM password complexity module is enabled in system-auth' + +description: |- + To enable PAM password complexity in system-auth file: + Edit the password section in + /etc/pam.d/system-auth to show + password requisite pam_pwquality.so. + +rationale: |- + Enabling PAM password complexity permits to enforce strong passwords and consequently + makes the system less prone to dictionary attacks. + +severity: medium + +identifiers: + cce@rhel7: CCE-85874-6 + cce@rhel8: CCE-85872-0 + cce@rhel9: CCE-85873-8 + +references: + stigid@rhel8: RHEL-08-020101 + +ocil_clause: 'pam_pwquality.so is not enabled in system-auth' + +ocil: |- + To check if pam_pwhistory.so is enabled in system-auth, run the following command: +
$ grep pam_pwquality /etc/pam.d/system-auth
+ The output should be similar to the following: +
password    requisite                                    pam_pwquality.so
+ +platform: pam diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_commented_entry.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_commented_entry.fail.sh new file mode 100644 index 00000000000..849f16d0f93 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_commented_entry.fail.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# packages = authselect +# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora + +authselect create-profile hardening -b sssd +CUSTOM_PROFILE="custom/hardening" +authselect select $CUSTOM_PROFILE --force + +CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/system-auth" +sed -i --follow-symlinks -e '/^password\s*requisite\s*pam_pwquality\.so/ s/^#*/#/g' $CUSTOM_SYSTEM_AUTH +authselect apply-changes -b diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_correct_entry.pass.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_correct_entry.pass.sh new file mode 100644 index 00000000000..6a98c244980 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_correct_entry.pass.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# packages = authselect +# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora + +authselect create-profile hardening -b sssd +CUSTOM_PROFILE="custom/hardening" +authselect select $CUSTOM_PROFILE --force + +CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/system-auth" +if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $CUSTOM_SYSTEM_AUTH) -eq 0 ]; then + sed -i --follow-symlinks '0,/^password.*/s/^password.*/password requisite pam_pwquality.so\n&/' $CUSTOM_SYSTEM_AUTH +fi +authselect apply-changes -b diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_missing_entry.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_missing_entry.fail.sh new file mode 100644 index 00000000000..6786f6c13d7 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_missing_entry.fail.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# packages = authselect +# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora + +authselect create-profile hardening -b sssd +CUSTOM_PROFILE="custom/hardening" +authselect select $CUSTOM_PROFILE --force + +CUSTOM_SYSTEM_AUTH="/etc/authselect/$CUSTOM_PROFILE/system-auth" +sed -i --follow-symlinks '/^password\s*requisite\s*pam_pwquality\.so/d' $CUSTOM_SYSTEM_AUTH +authselect apply-changes -b diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_modified_pam.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_modified_pam.fail.sh new file mode 100644 index 00000000000..b3d9e5884f5 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/authselect_modified_pam.fail.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# packages = authselect +# platform = Red Hat Enterprise Linux 8,Red Hat Enterprise Linux 9,multi_platform_fedora +# remediation = none + +SYSTEM_AUTH_FILE="/etc/pam.d/system-auth" + +# This modification will break the integrity checks done by authselect. +sed -i --follow-symlinks -e '/^password\s*requisite\s*pam_pwquality\.so/ s/^#*/#/g' $SYSTEM_AUTH_FILE diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/correct_entry.pass.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/correct_entry.pass.sh new file mode 100644 index 00000000000..71f87b19045 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/correct_entry.pass.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# packages = pam +# platform = Red Hat Enterprise Linux 7,Red Hat Virtualization 4,multi_platform_fedora + +config_file=/etc/pam.d/password-auth +if [ $(grep -c "^\s*password.*requisite.*pam_pwquality.so" $config_file) -eq 0 ]; then + sed -i --follow-symlinks '0,/^password.*/s/^password.*/password requisite pam_pwquality.so\n&/' $config_file +fi diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/missing_entry.fail.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/missing_entry.fail.sh new file mode 100644 index 00000000000..3c8f6f79fe9 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_system_auth/tests/missing_entry.fail.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# platform = Red Hat Enterprise Linux 7,Red Hat Virtualization 4,multi_platform_fedora +# packages = pam + +config_file=/etc/pam.d/system-auth + +sed -i --follow-symlinks '/^password\s*requisite\s*pam_pwquality\.so/d' $config_file diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_retry/rule.yml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_retry/rule.yml index eeb55a6ff5c..6b2219a3eab 100644 --- a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_retry/rule.yml +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_retry/rule.yml @@ -6,13 +6,16 @@ title: 'Ensure PAM Enforces Password Requirements - Authentication Retry Prompts description: |- To configure the number of retry prompts that are permitted per-session: + {{% if product in ['rhel8', 'rhel9'] %}} + Edit the /etc/security/pwquality.conf to include + {{% else %}} Edit the pam_pwquality.so statement in {{% if 'ubuntu' not in product %}} - /etc/pam.d/system-auth {{% if product in ['rhel8', 'rhel9'] %}} and - /etc/pam.d/password-auth {{% endif %}} to show + /etc/pam.d/system-auth to show {{% else %}} /etc/pam.d/common-password to show {{% endif %}} + {{% endif %}} retry={{{xccdf_value("var_password_pam_retry") }}}, or a lower value if site policy is more restrictive. The DoD requirement is a maximum of 3 prompts per session. @@ -48,17 +51,21 @@ references: stigid@ol7: OL07-00-010119 stigid@ol8: OL08-00-020100 stigid@rhel7: RHEL-07-010119 - stigid@rhel8: RHEL-08-020100 + stigid@rhel8: RHEL-08-020104 stigid@ubuntu2004: UBTU-20-010057 ocil_clause: 'it is not the required value' ocil: |- To check how many retry attempts are permitted on a per-session basis, run the following command: + {{% if product in ['rhel8', 'rhel9'] %}} +
$ grep retry /etc/security/pwquality.conf
+ {{% else %}} {{% if 'ubuntu' in product %}}
$ grep pam_pwquality /etc/pam.d/common-password
{{% else %}} -
$ grep pam_pwquality /etc/pam.d/system-auth {{% if product in ['rhel8', 'rhel9'] %}}/etc/pam.d/password-auth{{% endif %}}
+
$ grep pam_pwquality /etc/pam.d/system-auth
+ {{% endif %}} {{% endif %}} The retry parameter will indicate how many attempts are permitted. The DoD required value is less than or equal to 3. diff --git a/products/rhel8/profiles/stig.profile b/products/rhel8/profiles/stig.profile index d92bc72971c..62fc512f05e 100644 --- a/products/rhel8/profiles/stig.profile +++ b/products/rhel8/profiles/stig.profile @@ -523,6 +523,20 @@ selections: - sssd_enable_certmap # RHEL-08-020100 + - accounts_password_pam_pwquality_password_auth + + # RHEL-08-020101 + - accounts_password_pam_pwquality_system_auth + + # RHEL-08-020102 + # This is only required for RHEL8 systems below version 8.4 where the + # retry parameter was not yet available on /etc/security/pwquality.conf. + + # RHEL-08-020103 + # This is only required for RHEL8 systems below version 8.4 where the + # retry parameter was not yet available on /etc/security/pwquality.conf. + + # RHEL-08-020104 - accounts_password_pam_retry # RHEL-08-020110 diff --git a/products/rhel9/profiles/stig.profile b/products/rhel9/profiles/stig.profile index 42c6d0e9aca..ad08a6d3410 100644 --- a/products/rhel9/profiles/stig.profile +++ b/products/rhel9/profiles/stig.profile @@ -524,6 +524,20 @@ selections: - sssd_enable_certmap # RHEL-08-020100 + - accounts_password_pam_pwquality_password_auth + + # RHEL-08-020101 + - accounts_password_pam_pwquality_system_auth + + # RHEL-08-020102 + # This is only required for RHEL8 systems below version 8.4 where the + # retry parameter was not yet available on /etc/security/pwquality.conf. + + # RHEL-08-020103 + # This is only required for RHEL8 systems below version 8.4 where the + # retry parameter was not yet available on /etc/security/pwquality.conf. + + # RHEL-08-020104 - accounts_password_pam_retry # RHEL-08-020110 diff --git a/tests/data/profile_stability/rhel8/stig.profile b/tests/data/profile_stability/rhel8/stig.profile index e4fee44f9f9..33e82401c3d 100644 --- a/tests/data/profile_stability/rhel8/stig.profile +++ b/tests/data/profile_stability/rhel8/stig.profile @@ -53,6 +53,8 @@ selections: - accounts_password_pam_ocredit - accounts_password_pam_pwhistory_remember_password_auth - accounts_password_pam_pwhistory_remember_system_auth +- accounts_password_pam_pwquality_password_auth +- accounts_password_pam_pwquality_system_auth - accounts_password_pam_retry - accounts_password_pam_ucredit - accounts_password_pam_unix_rounds_password_auth diff --git a/tests/data/profile_stability/rhel8/stig_gui.profile b/tests/data/profile_stability/rhel8/stig_gui.profile index 83d04775e3a..5beeb4f28af 100644 --- a/tests/data/profile_stability/rhel8/stig_gui.profile +++ b/tests/data/profile_stability/rhel8/stig_gui.profile @@ -64,6 +64,8 @@ selections: - accounts_password_pam_ocredit - accounts_password_pam_pwhistory_remember_password_auth - accounts_password_pam_pwhistory_remember_system_auth +- accounts_password_pam_pwquality_password_auth +- accounts_password_pam_pwquality_system_auth - accounts_password_pam_retry - accounts_password_pam_ucredit - accounts_password_pam_unix_rounds_password_auth