-
Notifications
You must be signed in to change notification settings - Fork 671
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update faillock related macros #9139
Update faillock related macros #9139
Conversation
Hi @Xeicker. Thanks for your PR. I'm waiting for a ComplianceAsCode member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
This datastream diff is auto generated by the check Click here to see the trimmed diffbash remediation for rule 'xccdf_org.ssgproject.content_rule_display_login_attempts' differs:
--- old datastream
+++ new datastream
@@ -84,7 +84,7 @@
authselect apply-changes -b
fi
-if grep -qP '^\s*session\s.*\bpam_lastlog.so\s.*\bsilent[=\s$]' "$PAM_FILE_PATH"; then
+if grep -qP '^\s*session\s.*\bpam_lastlog.so\s.*\bsilent\b' "$PAM_FILE_PATH"; then
sed -i -E --follow-symlinks 's/(.*session.*pam_lastlog.so.*)\bsilent\b=?[[:alnum:]]*(.*)/\1\2/g' "$PAM_FILE_PATH"
fi
if [ -f /usr/bin/authselect ]; then
bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny' differs:
--- old datastream
+++ new datastream
@@ -28,6 +28,7 @@
sed -Ei 's/(auth.*)(\[default=die\])(.*pam_faillock.so)/\1required \3/g' "$pam_file"
done
fi
+AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
FAILLOCK_CONF="/etc/security/faillock.conf"
if [ -f $FAILLOCK_CONF ]; then
regex="^\s*deny\s*="
@@ -35,10 +36,54 @@
if ! grep -q $regex $FAILLOCK_CONF; then
echo $line >> $FAILLOCK_CONF
else
- sed -i --follow-symlinks 's/^\s*\(deny\s*=\s*\)\([0-9]\+\)/\1'"$var_accounts_passwords_pam_faillock_deny"'/g' $FAILLOCK_CONF
+ sed -i --follow-symlinks 's|^\s*\(deny\s*=\s*\)\(\S\+\)|\1'"$var_accounts_passwords_pam_faillock_deny"'|g' $FAILLOCK_CONF
fi
+ for pam_file in "${AUTH_FILES[@]}"
+ do
+ if [ -e "$pam_file" ] ; then
+ PAM_FILE_PATH="$pam_file"
+ if [ -f /usr/bin/authselect ]; then
+ if ! authselect check; then
+ echo "
+ authselect integrity check failed. Remediation aborted!
+ This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
+ It is not recommended to manually edit the PAM files when authselect tool is available.
+ In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
+ exit 1
+ fi
+ CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
+ # 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"
+
+ authselect apply-changes -b --backup=before-hardening-custom-profile
+ authselect select $CURRENT_PROFILE
+ for feature in $ENABLED_FEATURES; do
+ authselect enable-feature $feature;
+ done
+
+ authselect apply-changes -b --backup=after-hardening-custom-profile
+ fi
+ PAM_FILE_NAME=$(basename "$pam_file")
+ PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
+
+ authselect apply-changes -b
+ fi
+
+ if grep -qP '^\s*auth\s.*\bpam_faillock.so\s.*\bdeny\b' "$PAM_FILE_PATH"; then
+ sed -i -E --follow-symlinks 's/(.*auth.*pam_faillock.so.*)\bdeny\b=?[[:alnum:]]*(.*)/\1\2/g' "$PAM_FILE_PATH"
+ fi
+ if [ -f /usr/bin/authselect ]; then
+
+ authselect apply-changes -b
+ fi
+ else
+ echo "$pam_file was not found" >&2
+ fi
+ done
else
- AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
for pam_file in "${AUTH_FILES[@]}"
do
if ! grep -qE '^\s*auth.*pam_faillock.so (preauth|authfail).*deny' "$pam_file"; then
ansible remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny' differs:
--- old datastream
+++ new datastream
@@ -229,6 +229,369 @@
- restrict_strategy
- name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so
+ deny parameter not in PAM files
+ block:
+
+ - name: Lock Accounts After Failed Password Attempts - Check if /etc/pam.d/system-auth
+ file is present
+ ansible.builtin.stat:
+ path: /etc/pam.d/system-auth
+ register: result_pam_file_present
+
+ - name: Lock Accounts After Failed Password Attempts - Check the proper remediation
+ for the system
+ block:
+
+ - name: Lock Accounts After Failed Password Attempts - Define the PAM file to
+ be edited as a local fact
+ ansible.builtin.set_fact:
+ pam_file_path: /etc/pam.d/system-auth
+
+ - name: Lock Accounts After Failed Password Attempts - Check if system relies
+ on authselect
+ ansible.builtin.stat:
+ path: /usr/bin/authselect
+ register: result_authselect_present
+
+ - name: Lock Accounts After Failed Password Attempts - Remediate using authselect
+ block:
+
+ - name: Lock Accounts After Failed Password Attempts - Check integrity of authselect
+ current profile
+ ansible.builtin.command:
+ cmd: authselect check
+ register: result_authselect_check_cmd
+ changed_when: false
+ ignore_errors: true
+
+ - name: Lock Accounts After Failed Password Attempts - 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 an authselect profile was
+ not selected or the selected profile is not intact.
+ - It is not recommended to manually edit the PAM files when authselect tool
+ 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: Lock Accounts After Failed Password Attempts - 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: Lock Accounts After Failed Password Attempts - 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: Lock Accounts After Failed Password Attempts - 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: Lock Accounts After Failed Password Attempts - 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: Lock Accounts After Failed Password Attempts - Check if any custom profile
+ with the same name was already created
+ 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: Lock Accounts After Failed Password Attempts - Create an authselect
+ custom profile based on the current profile
+ ansible.builtin.command:
+ cmd: authselect create-profile hardening -b {{ authselect_current_profile
+ }}
+ when:
+ - result_authselect_check_cmd is success
+ - authselect_current_profile is not match("custom/")
+ - not result_authselect_custom_profile_present.stat.exists
+
+ - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
+ are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b --backup=before-hardening-custom-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: Lock Accounts After Failed Password Attempts - Ensure the authselect
+ custom profile is selected
+ ansible.builtin.command:
+ cmd: authselect select {{ authselect_custom_profile }}
+ 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: Lock Accounts After Failed Password Attempts - Restore the authselect
+ features in the custom profile
+ ansible.builtin.command:
+ cmd: authselect enable-feature {{ item }}
+ loop: '{{ result_authselect_features.stdout_lines }}'
+ register: result_pam_authselect_restore_features
+ when:
+ - result_authselect_profile is not skipped
+ - result_authselect_features is not skipped
+ - result_pam_authselect_select_profile is not skipped
+
+ - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
+ are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
+ when:
+ - result_authselect_check_cmd is success
+ - result_authselect_profile is not skipped
+ - result_pam_authselect_restore_features is not skipped
+
+ - name: Lock Accounts After Failed Password Attempts - Change the PAM file to
+ be edited according to the custom authselect profile
+ ansible.builtin.set_fact:
+ pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
+ | basename }}
+ when:
+ - result_authselect_present.stat.exists
+
+ - name: Lock Accounts After Failed Password Attempts - Ensure the "deny" option
+ from "pam_faillock.so" is not present in {{ pam_file_path }}
+ ansible.builtin.replace:
+ dest: '{{ pam_file_path }}'
+ regexp: (.*auth.*pam_faillock.so.*)\bdeny\b=?[0-9a-zA-Z]*(.*)
+ replace: \1\2
+ register: result_pam_option_removal
+
+ - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
+ are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b
+ when:
+ - result_authselect_present.stat.exists
+ - result_pam_option_removal is changed
+ when:
+ - result_pam_file_present.stat.exists
+
+ - name: Lock Accounts After Failed Password Attempts - Check if /etc/pam.d/password-auth
+ file is present
+ ansible.builtin.stat:
+ path: /etc/pam.d/password-auth
+ register: result_pam_file_present
+
+ - name: Lock Accounts After Failed Password Attempts - Check the proper remediation
+ for the system
+ block:
+
+ - name: Lock Accounts After Failed Password Attempts - Define the PAM file to
+ be edited as a local fact
+ ansible.builtin.set_fact:
+ pam_file_path: /etc/pam.d/password-auth
+
+ - name: Lock Accounts After Failed Password Attempts - Check if system relies
+ on authselect
+ ansible.builtin.stat:
+ path: /usr/bin/authselect
+ register: result_authselect_present
+
+ - name: Lock Accounts After Failed Password Attempts - Remediate using authselect
+ block:
+
+ - name: Lock Accounts After Failed Password Attempts - Check integrity of authselect
+ current profile
+ ansible.builtin.command:
+ cmd: authselect check
+ register: result_authselect_check_cmd
+ changed_when: false
+ ignore_errors: true
+
+ - name: Lock Accounts After Failed Password Attempts - 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 an authselect profile was
+ not selected or the selected profile is not intact.
+ - It is not recommended to manually edit the PAM files when authselect tool
+ 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: Lock Accounts After Failed Password Attempts - 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: Lock Accounts After Failed Password Attempts - 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: Lock Accounts After Failed Password Attempts - 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: Lock Accounts After Failed Password Attempts - 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: Lock Accounts After Failed Password Attempts - Check if any custom profile
+ with the same name was already created
+ 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: Lock Accounts After Failed Password Attempts - Create an authselect
+ custom profile based on the current profile
+ ansible.builtin.command:
+ cmd: authselect create-profile hardening -b {{ authselect_current_profile
+ }}
+ when:
+ - result_authselect_check_cmd is success
+ - authselect_current_profile is not match("custom/")
+ - not result_authselect_custom_profile_present.stat.exists
+
+ - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
+ are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b --backup=before-hardening-custom-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: Lock Accounts After Failed Password Attempts - Ensure the authselect
+ custom profile is selected
+ ansible.builtin.command:
+ cmd: authselect select {{ authselect_custom_profile }}
+ 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: Lock Accounts After Failed Password Attempts - Restore the authselect
+ features in the custom profile
+ ansible.builtin.command:
+ cmd: authselect enable-feature {{ item }}
+ loop: '{{ result_authselect_features.stdout_lines }}'
+ register: result_pam_authselect_restore_features
+ when:
+ - result_authselect_profile is not skipped
+ - result_authselect_features is not skipped
+ - result_pam_authselect_select_profile is not skipped
+
+ - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
+ are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
+ when:
+ - result_authselect_check_cmd is success
+ - result_authselect_profile is not skipped
+ - result_pam_authselect_restore_features is not skipped
+
+ - name: Lock Accounts After Failed Password Attempts - Change the PAM file to
+ be edited according to the custom authselect profile
+ ansible.builtin.set_fact:
+ pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
+ | basename }}
+ when:
+ - result_authselect_present.stat.exists
+
+ - name: Lock Accounts After Failed Password Attempts - Ensure the "deny" option
+ from "pam_faillock.so" is not present in {{ pam_file_path }}
+ ansible.builtin.replace:
+ dest: '{{ pam_file_path }}'
+ regexp: (.*auth.*pam_faillock.so.*)\bdeny\b=?[0-9a-zA-Z]*(.*)
+ replace: \1\2
+ register: result_pam_option_removal
+
+ - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
+ are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b
+ when:
+ - result_authselect_present.stat.exists
+ - result_pam_option_removal is changed
+ when:
+ - result_pam_file_present.stat.exists
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ tags:
+ - CCE-80667-9
+ - CJIS-5.5.3
+ - DISA-STIG-RHEL-08-020010
+ - NIST-800-171-3.1.8
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - PCI-DSS-Req-8.1.6
+ - accounts_passwords_pam_faillock_deny
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so
deny parameter in PAM files
block:
bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny_root' differs:
--- old datastream
+++ new datastream
@@ -25,6 +25,7 @@
sed -Ei 's/(auth.*)(\[default=die\])(.*pam_faillock.so)/\1required \3/g' "$pam_file"
done
fi
+AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
FAILLOCK_CONF="/etc/security/faillock.conf"
if [ -f $FAILLOCK_CONF ]; then
regex="^\s*even_deny_root"
@@ -32,8 +33,52 @@
if ! grep -q $regex $FAILLOCK_CONF; then
echo $line >> $FAILLOCK_CONF
fi
+ for pam_file in "${AUTH_FILES[@]}"
+ do
+ if [ -e "$pam_file" ] ; then
+ PAM_FILE_PATH="$pam_file"
+ if [ -f /usr/bin/authselect ]; then
+ if ! authselect check; then
+ echo "
+ authselect integrity check failed. Remediation aborted!
+ This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
+ It is not recommended to manually edit the PAM files when authselect tool is available.
+ In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
+ exit 1
+ fi
+ CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
+ # 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"
+
+ authselect apply-changes -b --backup=before-hardening-custom-profile
+ authselect select $CURRENT_PROFILE
+ for feature in $ENABLED_FEATURES; do
+ authselect enable-feature $feature;
+ done
+
+ authselect apply-changes -b --backup=after-hardening-custom-profile
+ fi
+ PAM_FILE_NAME=$(basename "$pam_file")
+ PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
+
+ authselect apply-changes -b
+ fi
+
+ if grep -qP '^\s*auth\s.*\bpam_faillock.so\s.*\beven_deny_root\b' "$PAM_FILE_PATH"; then
+ sed -i -E --follow-symlinks 's/(.*auth.*pam_faillock.so.*)\beven_deny_root\b=?[[:alnum:]]*(.*)/\1\2/g' "$PAM_FILE_PATH"
+ fi
+ if [ -f /usr/bin/authselect ]; then
+
+ authselect apply-changes -b
+ fi
+ else
+ echo "$pam_file was not found" >&2
+ fi
+ done
else
- AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
for pam_file in "${AUTH_FILES[@]}"
do
if ! grep -qE '^\s*auth.*pam_faillock.so (preauth|authfail).*even_deny_root' "$pam_file"; then
ansible remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny_root' differs:
--- old datastream
+++ new datastream
@@ -213,6 +213,369 @@
- restrict_strategy
- name: Configure the root Account for Failed Password Attempts - Ensure the pam_faillock.so
+ even_deny_root parameter not in PAM files
+ block:
+
+ - name: Configure the root Account for Failed Password Attempts - Check if /etc/pam.d/system-auth
+ file is present
+ ansible.builtin.stat:
+ path: /etc/pam.d/system-auth
+ register: result_pam_file_present
+
+ - name: Configure the root Account for Failed Password Attempts - Check the proper
+ remediation for the system
+ block:
+
+ - name: Configure the root Account for Failed Password Attempts - Define the PAM
+ file to be edited as a local fact
+ ansible.builtin.set_fact:
+ pam_file_path: /etc/pam.d/system-auth
+
+ - name: Configure the root Account for Failed Password Attempts - Check if system
+ relies on authselect
+ ansible.builtin.stat:
+ path: /usr/bin/authselect
+ register: result_authselect_present
+
+ - name: Configure the root Account for Failed Password Attempts - Remediate using
+ authselect
+ block:
+
+ - name: Configure the root Account for Failed Password Attempts - Check integrity
+ of authselect current profile
+ ansible.builtin.command:
+ cmd: authselect check
+ register: result_authselect_check_cmd
+ changed_when: false
+ ignore_errors: true
+
+ - name: Configure the root Account for Failed Password Attempts - 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 an authselect profile was
+ not selected or the selected profile is not intact.
+ - It is not recommended to manually edit the PAM files when authselect tool
+ 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: Configure the root Account for Failed Password Attempts - 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: Configure the root Account for Failed Password Attempts - 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: Configure the root Account for Failed Password Attempts - 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: Configure the root Account for Failed Password Attempts - 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: Configure the root Account for Failed Password Attempts - Check if any
+ custom profile with the same name was already created
+ 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: Configure the root Account for Failed Password Attempts - Create an
+ authselect custom profile based on the current profile
+ ansible.builtin.command:
+ cmd: authselect create-profile hardening -b {{ authselect_current_profile
+ }}
+ when:
+ - result_authselect_check_cmd is success
+ - authselect_current_profile is not match("custom/")
+ - not result_authselect_custom_profile_present.stat.exists
+
+ - name: Configure the root Account for Failed Password Attempts - Ensure authselect
+ changes are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b --backup=before-hardening-custom-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: Configure the root Account for Failed Password Attempts - Ensure the
+ authselect custom profile is selected
+ ansible.builtin.command:
+ cmd: authselect select {{ authselect_custom_profile }}
+ 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: Configure the root Account for Failed Password Attempts - Restore the
+ authselect features in the custom profile
+ ansible.builtin.command:
+ cmd: authselect enable-feature {{ item }}
+ loop: '{{ result_authselect_features.stdout_lines }}'
+ register: result_pam_authselect_restore_features
+ when:
+ - result_authselect_profile is not skipped
+ - result_authselect_features is not skipped
+ - result_pam_authselect_select_profile is not skipped
+
+ - name: Configure the root Account for Failed Password Attempts - Ensure authselect
+ changes are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
+ when:
+ - result_authselect_check_cmd is success
+ - result_authselect_profile is not skipped
+ - result_pam_authselect_restore_features is not skipped
+
+ - name: Configure the root Account for Failed Password Attempts - Change the
+ PAM file to be edited according to the custom authselect profile
+ ansible.builtin.set_fact:
+ pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
+ | basename }}
+ when:
+ - result_authselect_present.stat.exists
+
+ - name: Configure the root Account for Failed Password Attempts - Ensure the "even_deny_root"
+ option from "pam_faillock.so" is not present in {{ pam_file_path }}
+ ansible.builtin.replace:
+ dest: '{{ pam_file_path }}'
+ regexp: (.*auth.*pam_faillock.so.*)\beven_deny_root\b=?[0-9a-zA-Z]*(.*)
+ replace: \1\2
+ register: result_pam_option_removal
+
+ - name: Configure the root Account for Failed Password Attempts - Ensure authselect
+ changes are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b
+ when:
+ - result_authselect_present.stat.exists
+ - result_pam_option_removal is changed
+ when:
+ - result_pam_file_present.stat.exists
+
+ - name: Configure the root Account for Failed Password Attempts - Check if /etc/pam.d/password-auth
+ file is present
+ ansible.builtin.stat:
+ path: /etc/pam.d/password-auth
+ register: result_pam_file_present
+
+ - name: Configure the root Account for Failed Password Attempts - Check the proper
+ remediation for the system
+ block:
+
+ - name: Configure the root Account for Failed Password Attempts - Define the PAM
+ file to be edited as a local fact
+ ansible.builtin.set_fact:
+ pam_file_path: /etc/pam.d/password-auth
+
+ - name: Configure the root Account for Failed Password Attempts - Check if system
+ relies on authselect
+ ansible.builtin.stat:
+ path: /usr/bin/authselect
+ register: result_authselect_present
+
+ - name: Configure the root Account for Failed Password Attempts - Remediate using
+ authselect
+ block:
+
+ - name: Configure the root Account for Failed Password Attempts - Check integrity
+ of authselect current profile
+ ansible.builtin.command:
+ cmd: authselect check
+ register: result_authselect_check_cmd
+ changed_when: false
+ ignore_errors: true
+
+ - name: Configure the root Account for Failed Password Attempts - 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 an authselect profile was
+ not selected or the selected profile is not intact.
+ - It is not recommended to manually edit the PAM files when authselect tool
+ 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: Configure the root Account for Failed Password Attempts - 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: Configure the root Account for Failed Password Attempts - 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: Configure the root Account for Failed Password Attempts - 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: Configure the root Account for Failed Password Attempts - 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: Configure the root Account for Failed Password Attempts - Check if any
+ custom profile with the same name was already created
+ 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: Configure the root Account for Failed Password Attempts - Create an
+ authselect custom profile based on the current profile
+ ansible.builtin.command:
+ cmd: authselect create-profile hardening -b {{ authselect_current_profile
+ }}
+ when:
+ - result_authselect_check_cmd is success
+ - authselect_current_profile is not match("custom/")
+ - not result_authselect_custom_profile_present.stat.exists
+
+ - name: Configure the root Account for Failed Password Attempts - Ensure authselect
+ changes are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b --backup=before-hardening-custom-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: Configure the root Account for Failed Password Attempts - Ensure the
+ authselect custom profile is selected
+ ansible.builtin.command:
+ cmd: authselect select {{ authselect_custom_profile }}
+ 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: Configure the root Account for Failed Password Attempts - Restore the
+ authselect features in the custom profile
+ ansible.builtin.command:
+ cmd: authselect enable-feature {{ item }}
+ loop: '{{ result_authselect_features.stdout_lines }}'
+ register: result_pam_authselect_restore_features
+ when:
+ - result_authselect_profile is not skipped
+ - result_authselect_features is not skipped
+ - result_pam_authselect_select_profile is not skipped
+
+ - name: Configure the root Account for Failed Password Attempts - Ensure authselect
+ changes are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
+ when:
+ - result_authselect_check_cmd is success
+ - result_authselect_profile is not skipped
+ - result_pam_authselect_restore_features is not skipped
+
+ - name: Configure the root Account for Failed Password Attempts - Change the
+ PAM file to be edited according to the custom authselect profile
+ ansible.builtin.set_fact:
+ pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
+ | basename }}
+ when:
+ - result_authselect_present.stat.exists
+
+ - name: Configure the root Account for Failed Password Attempts - Ensure the "even_deny_root"
+ option from "pam_faillock.so" is not present in {{ pam_file_path }}
+ ansible.builtin.replace:
+ dest: '{{ pam_file_path }}'
+ regexp: (.*auth.*pam_faillock.so.*)\beven_deny_root\b=?[0-9a-zA-Z]*(.*)
+ replace: \1\2
+ register: result_pam_option_removal
+
+ - name: Configure the root Account for Failed Password Attempts - Ensure authselect
+ changes are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b
+ when:
+ - result_authselect_present.stat.exists
+ - result_pam_option_removal is changed
+ when:
+ - result_pam_file_present.stat.exists
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ tags:
+ - CCE-80668-7
+ - DISA-STIG-RHEL-08-020022
+ - NIST-800-53-AC-7(b)
+ - NIST-800-53-CM-6(a)
+ - NIST-800-53-IA-5(c)
+ - accounts_passwords_pam_faillock_deny_root
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Configure the root Account for Failed Password Attempts - Ensure the pam_faillock.so
even_deny_root parameter in PAM files
block:
bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_enforce_local' differs:
--- old datastream
+++ new datastream
@@ -25,6 +25,7 @@
sed -Ei 's/(auth.*)(\[default=die\])(.*pam_faillock.so)/\1required \3/g' "$pam_file"
done
fi
+AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
FAILLOCK_CONF="/etc/security/faillock.conf"
if [ -f $FAILLOCK_CONF ]; then
regex="^\s*local_users_only"
@@ -32,8 +33,52 @@
if ! grep -q $regex $FAILLOCK_CONF; then
echo $line >> $FAILLOCK_CONF
fi
+ for pam_file in "${AUTH_FILES[@]}"
+ do
+ if [ -e "$pam_file" ] ; then
+ PAM_FILE_PATH="$pam_file"
+ if [ -f /usr/bin/authselect ]; then
+ if ! authselect check; then
+ echo "
+ authselect integrity check failed. Remediation aborted!
+ This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
+ It is not recommended to manually edit the PAM files when authselect tool is available.
+ In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
+ exit 1
+ fi
+ CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
+ # 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"
+
+ authselect apply-changes -b --backup=before-hardening-custom-profile
+ authselect select $CURRENT_PROFILE
+ for feature in $ENABLED_FEATURES; do
+ authselect enable-feature $feature;
+ done
+
+ authselect apply-changes -b --backup=after-hardening-custom-profile
+ fi
+ PAM_FILE_NAME=$(basename "$pam_file")
+ PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
+
+ authselect apply-changes -b
+ fi
+
+ if grep -qP '^\s*auth\s.*\bpam_faillock.so\s.*\blocal_users_only\b' "$PAM_FILE_PATH"; then
+ sed -i -E --follow-symlinks 's/(.*auth.*pam_faillock.so.*)\blocal_users_only\b=?[[:alnum:]]*(.*)/\1\2/g' "$PAM_FILE_PATH"
+ fi
+ if [ -f /usr/bin/authselect ]; then
+
+ authselect apply-changes -b
+ fi
+ else
+ echo "$pam_file was not found" >&2
+ fi
+ done
else
- AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
for pam_file in "${AUTH_FILES[@]}"
do
if ! grep -qE '^\s*auth.*pam_faillock.so (preauth|authfail).*local_users_only' "$pam_file"; then
ansible remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_enforce_local' differs:
--- old datastream
+++ new datastream
@@ -194,6 +194,364 @@
- restrict_strategy
- name: Enforce pam_faillock for Local Accounts Only - Ensure the pam_faillock.so
+ local_users_only parameter not in PAM files
+ block:
+
+ - name: Enforce pam_faillock for Local Accounts Only - Check if /etc/pam.d/system-auth
+ file is present
+ ansible.builtin.stat:
+ path: /etc/pam.d/system-auth
+ register: result_pam_file_present
+
+ - name: Enforce pam_faillock for Local Accounts Only - Check the proper remediation
+ for the system
+ block:
+
+ - name: Enforce pam_faillock for Local Accounts Only - Define the PAM file to
+ be edited as a local fact
+ ansible.builtin.set_fact:
+ pam_file_path: /etc/pam.d/system-auth
+
+ - name: Enforce pam_faillock for Local Accounts Only - Check if system relies
+ on authselect
+ ansible.builtin.stat:
+ path: /usr/bin/authselect
+ register: result_authselect_present
+
+ - name: Enforce pam_faillock for Local Accounts Only - Remediate using authselect
+ block:
+
+ - name: Enforce pam_faillock for Local Accounts Only - Check integrity of authselect
+ current profile
+ ansible.builtin.command:
+ cmd: authselect check
+ register: result_authselect_check_cmd
+ changed_when: false
+ ignore_errors: true
+
+ - name: Enforce pam_faillock for Local Accounts Only - 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 an authselect profile was
+ not selected or the selected profile is not intact.
+ - It is not recommended to manually edit the PAM files when authselect tool
+ 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: Enforce pam_faillock for Local Accounts Only - 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: Enforce pam_faillock for Local Accounts Only - 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: Enforce pam_faillock for Local Accounts Only - 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: Enforce pam_faillock for Local Accounts Only - 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: Enforce pam_faillock for Local Accounts Only - Check if any custom profile
+ with the same name was already created
+ 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: Enforce pam_faillock for Local Accounts Only - Create an authselect
+ custom profile based on the current profile
+ ansible.builtin.command:
+ cmd: authselect create-profile hardening -b {{ authselect_current_profile
+ }}
+ when:
+ - result_authselect_check_cmd is success
+ - authselect_current_profile is not match("custom/")
+ - not result_authselect_custom_profile_present.stat.exists
+
+ - name: Enforce pam_faillock for Local Accounts Only - Ensure authselect changes
+ are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b --backup=before-hardening-custom-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: Enforce pam_faillock for Local Accounts Only - Ensure the authselect
+ custom profile is selected
+ ansible.builtin.command:
+ cmd: authselect select {{ authselect_custom_profile }}
+ 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: Enforce pam_faillock for Local Accounts Only - Restore the authselect
+ features in the custom profile
+ ansible.builtin.command:
+ cmd: authselect enable-feature {{ item }}
+ loop: '{{ result_authselect_features.stdout_lines }}'
+ register: result_pam_authselect_restore_features
+ when:
+ - result_authselect_profile is not skipped
+ - result_authselect_features is not skipped
+ - result_pam_authselect_select_profile is not skipped
+
+ - name: Enforce pam_faillock for Local Accounts Only - Ensure authselect changes
+ are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
+ when:
+ - result_authselect_check_cmd is success
+ - result_authselect_profile is not skipped
+ - result_pam_authselect_restore_features is not skipped
+
+ - name: Enforce pam_faillock for Local Accounts Only - Change the PAM file to
+ be edited according to the custom authselect profile
+ ansible.builtin.set_fact:
+ pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
+ | basename }}
+ when:
+ - result_authselect_present.stat.exists
+
+ - name: Enforce pam_faillock for Local Accounts Only - Ensure the "local_users_only"
+ option from "pam_faillock.so" is not present in {{ pam_file_path }}
+ ansible.builtin.replace:
+ dest: '{{ pam_file_path }}'
+ regexp: (.*auth.*pam_faillock.so.*)\blocal_users_only\b=?[0-9a-zA-Z]*(.*)
+ replace: \1\2
+ register: result_pam_option_removal
+
+ - name: Enforce pam_faillock for Local Accounts Only - Ensure authselect changes
+ are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b
+ when:
+ - result_authselect_present.stat.exists
+ - result_pam_option_removal is changed
+ when:
+ - result_pam_file_present.stat.exists
+
+ - name: Enforce pam_faillock for Local Accounts Only - Check if /etc/pam.d/password-auth
+ file is present
+ ansible.builtin.stat:
+ path: /etc/pam.d/password-auth
+ register: result_pam_file_present
+
+ - name: Enforce pam_faillock for Local Accounts Only - Check the proper remediation
+ for the system
+ block:
+
+ - name: Enforce pam_faillock for Local Accounts Only - Define the PAM file to
+ be edited as a local fact
+ ansible.builtin.set_fact:
+ pam_file_path: /etc/pam.d/password-auth
+
+ - name: Enforce pam_faillock for Local Accounts Only - Check if system relies
+ on authselect
+ ansible.builtin.stat:
+ path: /usr/bin/authselect
+ register: result_authselect_present
+
+ - name: Enforce pam_faillock for Local Accounts Only - Remediate using authselect
+ block:
+
+ - name: Enforce pam_faillock for Local Accounts Only - Check integrity of authselect
+ current profile
+ ansible.builtin.command:
+ cmd: authselect check
+ register: result_authselect_check_cmd
+ changed_when: false
+ ignore_errors: true
+
+ - name: Enforce pam_faillock for Local Accounts Only - 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 an authselect profile was
+ not selected or the selected profile is not intact.
+ - It is not recommended to manually edit the PAM files when authselect tool
+ 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: Enforce pam_faillock for Local Accounts Only - 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: Enforce pam_faillock for Local Accounts Only - 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: Enforce pam_faillock for Local Accounts Only - 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: Enforce pam_faillock for Local Accounts Only - 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: Enforce pam_faillock for Local Accounts Only - Check if any custom profile
+ with the same name was already created
+ 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: Enforce pam_faillock for Local Accounts Only - Create an authselect
+ custom profile based on the current profile
+ ansible.builtin.command:
+ cmd: authselect create-profile hardening -b {{ authselect_current_profile
+ }}
+ when:
+ - result_authselect_check_cmd is success
+ - authselect_current_profile is not match("custom/")
+ - not result_authselect_custom_profile_present.stat.exists
+
+ - name: Enforce pam_faillock for Local Accounts Only - Ensure authselect changes
+ are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b --backup=before-hardening-custom-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: Enforce pam_faillock for Local Accounts Only - Ensure the authselect
+ custom profile is selected
+ ansible.builtin.command:
+ cmd: authselect select {{ authselect_custom_profile }}
+ 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: Enforce pam_faillock for Local Accounts Only - Restore the authselect
+ features in the custom profile
+ ansible.builtin.command:
+ cmd: authselect enable-feature {{ item }}
+ loop: '{{ result_authselect_features.stdout_lines }}'
+ register: result_pam_authselect_restore_features
+ when:
+ - result_authselect_profile is not skipped
+ - result_authselect_features is not skipped
+ - result_pam_authselect_select_profile is not skipped
+
+ - name: Enforce pam_faillock for Local Accounts Only - Ensure authselect changes
+ are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
+ when:
+ - result_authselect_check_cmd is success
+ - result_authselect_profile is not skipped
+ - result_pam_authselect_restore_features is not skipped
+
+ - name: Enforce pam_faillock for Local Accounts Only - Change the PAM file to
+ be edited according to the custom authselect profile
+ ansible.builtin.set_fact:
+ pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
+ | basename }}
+ when:
+ - result_authselect_present.stat.exists
+
+ - name: Enforce pam_faillock for Local Accounts Only - Ensure the "local_users_only"
+ option from "pam_faillock.so" is not present in {{ pam_file_path }}
+ ansible.builtin.replace:
+ dest: '{{ pam_file_path }}'
+ regexp: (.*auth.*pam_faillock.so.*)\blocal_users_only\b=?[0-9a-zA-Z]*(.*)
+ replace: \1\2
+ register: result_pam_option_removal
+
+ - name: Enforce pam_faillock for Local Accounts Only - Ensure authselect changes
+ are applied
+ ansible.builtin.command:
+ cmd: authselect apply-changes -b
+ when:
+ - result_authselect_present.stat.exists
+ - result_pam_option_removal is changed
+ when:
+ - result_pam_file_present.stat.exists
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ tags:
+ - CCE-83401-0
+ - NIST-800-53-AC-2(1)
+ - accounts_passwords_pam_faillock_enforce_local
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Enforce pam_faillock for Local Accounts Only - Ensure the pam_faillock.so
local_users_only parameter in PAM files
block:
bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_interval' differs:
--- old datastream
+++ new datastream
@@ -28,6 +28,7 @@
sed -Ei 's/(auth.*)(\[default=die\])(.*pam_faillock.so)/\1required \3/g' "$pam_file"
done
fi
+AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
FAILLOCK_CONF="/etc/security/faillock.conf"
if [ -f $FAILLOCK_CONF ]; then
regex="^\s*fail_interval\s*="
@@ -35,10 +36,54 @@
if ! grep -q $regex $FAILLOCK_CONF; then
echo $line >> $FAILLOCK_CONF
else
- sed -i --follow-symlinks 's/^\s*\(fail_interval\s*=\s*\)\([0-9]\+\)/\1'"$var_accounts_passwords_pam_faillock_fail_interval"'/g' $FAILLOCK_CONF
+ sed -i --follow-symlinks 's|^\s*\(fail_interval\s*=\s*\)\(\S\+\)|\1'"$var_accounts_passwords_pam_faillock_fail_interval"'|g' $FAILLOCK_CONF
fi
+ for pam_file in "${AUTH_FILES[@]}"
+ do
+ if [ -e "$pam_file" ] ; then
+ PAM_FILE_PATH="$pam_file"
+ if [ -f /usr/bin/authselect ]; then
+ if ! authselect check; then
+ echo "
+ authselect integrity check failed. Remediation aborted!
+ This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
+ It is not recommended to manually edit the PAM files when authselect tool is available.
+ In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
+ exit 1
+ fi
+ CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
+ # 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"
+
+ authselect apply-changes -b --backup=before-hardening-custom-profile
+ authselect select $CURRENT_PROFILE
+ for feature in $ENABLED_FEATURES; do
+ authselect enable-feature $feature;
+ done
+
+ authselect apply-changes -b --backup=after-hardening-custom-profile
+ fi
+ PAM_FILE_NAME=$(basename "$pam_file")
+ PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
+
+ authselect apply-changes -b
+ fi
+
+ if grep -qP '^\s*auth\s.*\bpam_faillock.so\s.*\bfail_interval\b' "$PAM_FILE_PATH"; then
+ sed -i -E --follow-symlinks 's/(.*auth.*pam_faillock.so.*)\bfail_interval\b=?[[:alnum:]]*(.*)/\1\2/g' "$PAM_FILE_PATH"
+ fi
+ if [ -f /usr/bin/authselect ]; then
+
+ authselect apply-changes -b
+ fi
+ else
+ echo "$pam_file was not found" >&2
+ fi
+ done
else
- AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
for pam_file in "${AUTH_FILES[@]}"
do
if ! grep -qE '^\s*auth.*pam_faillock.so (preauth|authfail).*fail_interval' "$pam_file"; then
ansible remediation for rule 'xccd
... The diff is trimmed here ... |
/ok-to-test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Xeicker . I just included some small comments.
..._attempts/accounts_passwords_pam_faillock_deny/tests/conflicting_settings_authselect.fail.sh
Outdated
Show resolved
Hide resolved
Make them manage the edge cases: * When the user had set options in pam files, but faillock.conf was available * When the option is not a number * Remove pam option when the option doesn't have a value associated Signed-off-by: Edgar Aguilar <edgar.aguilar@oracle.com>
These new tests validate the update on faillock macros Signed-off-by: Edgar Aguilar <edgar.aguilar@oracle.com>
b659aea
to
8a4b38d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Xeicker . I will just wait the tests to finish.
Code Climate has analyzed commit afa488d and detected 0 issues on this pull request. The test coverage on the diff in this pull request is 100.0% (50% is the threshold). This pull request will bring the total coverage in the repository to 42.7% (0.0% change). View more on Code Climate. |
@Xeicker: The following tests failed, say
Full PR test history. Your PR dashboard. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
Besides the CI tests I also tested critical PAM rules in local VMs and everything worked fine. Thanks @Xeicker |
Description:
Rationale:
pam_faillock
man page, modifying pam_faillock options from pam files is still possible but not recommended.dir
option which isn't a numberbash_remove_pam_module_option_configuration
wasn't working