Skip to content
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 pam_faillock.so rules #7929

Merged
merged 9 commits into from Dec 13, 2021

Conversation

marcusburghardt
Copy link
Member

Description:

Redesigned the OVAL and remediation logic to make the rule compatible with newer versions of pam and authselect tool, which define the pam_faillock.so parameters in /etc/security/faillock.conf. The new logic also covers some new possible situations making the rule more robust.

Rationale:

Manual changes in pam files may be challenging and are prone to human errors which may ultimately block the access to a system. There are system tools which better do this job. This PR make sure that proper tools are used always when possible, preserving the pam files format and ensuring the recommended settings.

This PR also fix the RHBZ#1956972

@github-actions
Copy link

github-actions bot commented Nov 29, 2021

This datastream diff is auto generated by the check Compare DS/Generate Diff

Click here to see the full diff
OVAL definition oval:ssg-accounts_passwords_pam_faillock_deny:def:1 differs:
--- old datastream
+++ new datastream
- criterion oval:ssg-test_accounts_passwords_pam_faillock_preauth_silent_system-auth:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_account_phase_system-auth:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_preauth_silent_password-auth:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_account_phase_password-auth:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_numeric_default_check_system-auth:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_authfail_deny_system-auth:tst:1
- criteria OR
- criterion oval:ssg-test_accounts_passwords_pam_faillock_numeric_default_check_password-auth:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_authfail_deny_password-auth:tst:1
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_system_pam_unix_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_password_pam_unix_auth:tst:1
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_system_pam_faillock_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_system_pam_faillock_account:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_password_pam_faillock_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_password_pam_faillock_account:tst:1
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_parameter_pamd_system:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_parameter_pamd_password:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_parameter_no_faillock_conf:tst:1
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_parameter_no_pamd_system:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_parameter_no_pamd_password:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_parameter_faillock_conf:tst:1
OCIL for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny' differs:
--- old datastream
+++ new datastream
@@ -1,5 +1,6 @@
 To ensure the failed password attempt policy is configured correctly, run the following command:
-$ grep pam_faillock /etc/pam.d/system-auth
+
+$ grep deny /etc/security/faillock.conf
 The output should show deny=.
 Is it the case that limiting the number of failed logon attempts for users is not configured?
 
bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny' differs:
--- old datastream
+++ new datastream
@@ -4,7 +4,35 @@
 var_accounts_passwords_pam_faillock_deny=''
 
 
-AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
+SYSTEM_AUTH="/etc/pam.d/system-auth"
+PASSWORD_AUTH="/etc/pam.d/password-auth"
+FAILLOCK_CONF="/etc/security/faillock.conf"
+
+if [ $(grep -c "^\s*auth.*pam_unix.so" $SYSTEM_AUTH) > 1 ] || \
+ [ $(grep -c "^\s*auth.*pam_unix.so" $PASSWORD_AUTH) > 1 ]; then
+ echo "Skipping remediation because there are more pam_unix.so entries than expected."
+ false
+fi
+
+if [ -f $FAILLOCK_CONF ]; then
+ if $(grep -q '^\s*deny\s*=' $FAILLOCK_CONF); then
+ sed -i --follow-symlinks "s/^\s*\(deny\s*\)=.*$/\1 = $var_accounts_passwords_pam_faillock_deny/g" $FAILLOCK_CONF
+ else
+ echo "deny = $var_accounts_passwords_pam_faillock_deny" >> $FAILLOCK_CONF
+ fi
+ # If the faillock.conf file is present, but for any reason, like an OS upgrade, the
+ # pam_faillock.so parameters are still defined in pam files, this makes them compatible with
+ # the newer versions of authselect tool and ensure the parameters are only in faillock.conf.
+ sed -i --follow-symlinks 's/\(pam_faillock.so preauth\).*$/\1 silent/g' $SYSTEM_AUTH $PASSWORD_AUTH
+ sed -i --follow-symlinks 's/\(pam_faillock.so authfail\).*$/\1/g' $SYSTEM_AUTH $PASSWORD_AUTH
+ authselect enable-feature with-faillock
+else
+ if [ -f /usr/sbin/authconfig ]; then
+ authconfig --enablefaillock --update
+ else
+ authselect enable-feature with-faillock
+ fi
+ AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
 
 for pam_file in "${AUTH_FILES[@]}"
 do
@@ -42,6 +70,7 @@
 sed -E -i --follow-symlinks '/^\s*account\s*required\s*pam_unix.so/i account required pam_faillock.so' "$pam_file"
 fi
 done
+fi
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny' differs:
--- old datastream
+++ new datastream
@@ -21,21 +21,10 @@
 tags:
 - always
 
-- name: Add auth pam_faillock preauth deny before pam_unix.so
- pamd:
- name: '{{ item }}'
- type: auth
- control: sufficient
- module_path: pam_unix.so
- new_type: auth
- new_control: required
- new_module_path: pam_faillock.so
- module_arguments: preauth silent deny={{ var_accounts_passwords_pam_faillock_deny
- }}
- state: before
- loop:
- - system-auth
- - password-auth
+- name: Check if system relies on authconfig
+ ansible.builtin.stat:
+ path: /usr/sbin/authconfig
+ register: result_authconfig_check
 when: '"pam" in ansible_facts.packages'
 tags:
 - CCE-80667-9
@@ -52,18 +41,10 @@
 - no_reboot_needed
 - restrict_strategy
 
-- name: Add deny argument to auth pam_faillock preauth
- pamd:
- name: '{{ item }}'
- type: auth
- control: required
- module_path: pam_faillock.so
- module_arguments: preauth silent deny={{ var_accounts_passwords_pam_faillock_deny
- }}
- state: args_present
- loop:
- - system-auth
- - password-auth
+- name: Check the presence of /etc/security/faillock.conf file
+ ansible.builtin.stat:
+ path: /etc/security/faillock.conf
+ register: result_faillock_conf_check
 when: '"pam" in ansible_facts.packages'
 tags:
 - CCE-80667-9
@@ -80,20 +61,38 @@
 - no_reboot_needed
 - restrict_strategy
 
-- name: Add auth pam_faillock authfail deny after pam_unix.so
- pamd:
- name: '{{ item }}'
- type: auth
- control: sufficient
- module_path: pam_unix.so
- new_type: auth
- new_control: '[default=die]'
- new_module_path: pam_faillock.so
- module_arguments: authfail deny={{ var_accounts_passwords_pam_faillock_deny }}
- state: after
- loop:
- - system-auth
- - password-auth
+- name: Ensure the pam_faillock.so deny parameter in /etc/security/faillock.conf
+ ansible.builtin.lineinfile:
+ path: /etc/security/faillock.conf
+ regexp: ^\s*deny\s*=
+ line: deny = {{ var_accounts_passwords_pam_faillock_deny }}
+ state: present
+ 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: Check if pam_faillock.so is already enabled
+ ansible.builtin.lineinfile:
+ path: /etc/pam.d/system-auth
+ regexp: .*auth.*pam_faillock.so.*
+ state: absent
+ check_mode: true
+ changed_when: false
+ register: result_pam_faillock_enabled
 when: '"pam" in ansible_facts.packages'
 tags:
 - CCE-80667-9
@@ -110,59 +109,161 @@
 - no_reboot_needed
 - restrict_strategy
 
-- name: Add deny argument to auth pam_faillock authfail
- pamd:
- name: '{{ item }}'
- type: auth
- new_type: auth
- control: '[default=die]'
- module_path: pam_faillock.so
- module_arguments: authfail deny={{ var_accounts_passwords_pam_faillock_deny }}
- state: args_present
- loop:
- - system-auth
- - password-auth
- when: '"pam" in ansible_facts.packages'
- 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: Add account pam_faillock before pam_unix.so
- pamd:
- name: '{{ item }}'
- type: account
- control: required
- module_path: pam_unix.so
- new_type: account
- new_control: required
- new_module_path: pam_faillock.so
- state: before
- loop:
- - system-auth
- - password-auth
- when: '"pam" in ansible_facts.packages'
- 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: Ensure the pam_faillock.so preauth parameters are not present in the pam files
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (.*pam_faillock.so preauth).*$
+ line: \1 silent
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ - result_pam_faillock_enabled.found
+ 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: Ensure the pam_faillock.so authfail parameters are not present in the pam
+ files
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (.*pam_faillock.so authfail).*$
+ line: \1
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ - result_pam_faillock_enabled.found
+ 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: Ensure pam_faillock.so is properly enabled using authconfig tool
+ ansible.builtin.command:
+ cmd: authconfig --enablefaillock --update
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_authconfig_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: Ensure pam_faillock.so is properly enabled using authselect
+ ansible.builtin.command:
+ cmd: authselect enable-feature with-faillock
+ register: result_pam_authselect_cmd
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ - not result_pam_faillock_enabled.found
+ 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: Ensure the pam_faillock.so preauth deny parameter in auth section
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(deny)=[0-5]+(.*)
+ line: \1required\3\4={{ var_accounts_passwords_pam_faillock_deny }}\5
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not 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: Ensure the pam_faillock.so authfail deny parameter in auth section
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(deny)=[0-5]+(.*)
+ line: \1required\3\4={{ var_accounts_passwords_pam_faillock_deny }}\5
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not 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

OVAL definition oval:ssg-accounts_passwords_pam_faillock_deny_root:def:1 differs:
--- old datastream
+++ new datastream
- criteria None
- criterion oval:ssg-test_pam_faillock_preauth_silent_system-auth:tst:1
- criterion oval:ssg-test_pam_faillock_authfail_deny_root_system-auth:tst:1
- criterion oval:ssg-test_pam_faillock_preauth_silent_password-auth:tst:1
- criterion oval:ssg-test_pam_faillock_authfail_deny_root_password-auth:tst:1
+ criteria AND
+ criteria AND
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_root_system_pam_unix_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_root_password_pam_unix_auth:tst:1
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_root_system_pam_faillock_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_root_system_pam_faillock_account:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_root_password_pam_faillock_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_root_password_pam_faillock_account:tst:1
+ criteria OR
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_root_parameter_pamd_system:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_root_parameter_pamd_password:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_root_parameter_no_faillock_conf:tst:1
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_root_parameter_no_pamd_system:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_root_parameter_no_pamd_password:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_deny_root_parameter_faillock_conf:tst:1
OCIL for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny_root' differs:
--- old datastream
+++ new datastream
@@ -1,6 +1,7 @@
 To ensure that even the root account is locked after a defined number of failed password
 attempts, run the following command:
-$ grep even_deny_root /etc/pam.d/system-auth
+
+$ grep even_deny_root /etc/security/faillock.conf
 The output should show even_deny_root.
 Is it the case that limiting the number of failed logon attempts for the root user is not configured?
 
bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny_root' differs:
--- old datastream
+++ new datastream
@@ -1,49 +1,38 @@
 # Remediation is applicable only in certain platforms
 if rpm --quiet -q pam; then
 
-AUTH_FILES[0]="/etc/pam.d/system-auth"
-AUTH_FILES[1]="/etc/pam.d/password-auth"
+SYSTEM_AUTH="/etc/pam.d/system-auth"
+PASSWORD_AUTH="/etc/pam.d/password-auth"
+FAILLOCK_CONF="/etc/security/faillock.conf"
 
-# This script fixes absence of pam_faillock.so in PAM stack or the
-# absense of even_deny_root in pam_faillock.so arguments
-# When inserting auth pam_faillock.so entries,
-# the entry with preauth argument will be added before pam_unix.so module
-# and entry with authfail argument will be added before pam_deny.so module.
+if [ $(grep -c "^\s*auth.*pam_unix.so" $SYSTEM_AUTH) > 1 ] || \
+ [ $(grep -c "^\s*auth.*pam_unix.so" $PASSWORD_AUTH) > 1 ]; then
+ echo "Skipping remediation because there are more pam_unix.so entries than expected."
+ false
+fi
 
-# The placement of pam_faillock.so entries will not be changed
-# if they are already present
-
-for pamFile in "${AUTH_FILES[@]}"
-do
- # if PAM file is missing, system is not using PAM or broken
- if [ ! -f $pamFile ]; then
- continue
- fi
-
- # is 'auth required' here?
- if grep -q "^auth.*required.*pam_faillock.so.*" $pamFile; then
- # has 'auth required' even_deny_root option?
- if ! grep -q "^auth.*required.*pam_faillock.so.*preauth.*even_deny_root" $pamFile; then
- # even_deny_root is not present
- sed -i --follow-symlinks "s/\(^auth.*required.*pam_faillock.so.*preauth.*\).*/\1 even_deny_root/" $pamFile
+if [ -f $FAILLOCK_CONF ]; then
+ if [ ! $(grep -q '^\s*even_deny_root' $FAILLOCK_CONF) ]; then
+ echo "even_deny_root" >> $FAILLOCK_CONF
+ fi
+ # If the faillock.conf file is present, but for any reason, like an OS upgrade, the
+ # pam_faillock.so parameters are still defined in pam files, this makes them compatible with
+ # the newer versions of authselect tool and ensure the parameters are only in faillock.conf.
+ sed -i --follow-symlinks 's/\(pam_faillock.so preauth\).*$/\1 silent/g' $SYSTEM_AUTH $PASSWORD_AUTH
+ sed -i --follow-symlinks 's/\(pam_faillock.so authfail\).*$/\1/g' $SYSTEM_AUTH $PASSWORD_AUTH
+ authselect enable-feature with-faillock
+else
+ if [ -f /usr/sbin/authconfig ]; then
+ authconfig --enablefaillock --update
+ else
+ authselect enable-feature with-faillock
+ fi
+ for file in $SYSTEM_AUTH $PASSWORD_AUTH; do
+ if ! grep -q "^auth.*pam_faillock.so \(preauth silent\|authfail\).*even_deny_root" $file; then
+ sed -i --follow-symlinks 's/\(pam_faillock.so \(preauth silent\|authfail\).*\)$/\1 even_deny_root/g' $file
 fi
- else
- # no 'auth required', add it
- sed -i --follow-symlinks "/^auth.*pam_unix.so.*/i auth required pam_faillock.so preauth silent even_deny_root" $pamFile
- fi
-
- # is 'auth [default=die]' here?
- if grep -q "^auth.*\[default=die\].*pam_faillock.so.*" $pamFile; then
- # has 'auth [default=die]' even_deny_root option?
- if ! grep -q "^auth.*\[default=die\].*pam_faillock.so.*authfail.*even_deny_root" $pamFile; then
- # even_deny_root is not present
- sed -i --follow-symlinks "s/\(^auth.*\[default=die\].*pam_faillock.so.*authfail.*\).*/\1 even_deny_root/" $pamFile
- fi
- else
- # no 'auth [default=die]', add it
- sed -i --follow-symlinks "/^auth.*pam_unix.so.*/a auth [default=die] pam_faillock.so authfail silent even_deny_root" $pamFile
- fi
-done
+ done
+fi
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny_root' differs:
--- old datastream
+++ new datastream
@@ -14,20 +14,10 @@
 - no_reboot_needed
 - restrict_strategy
 
-- name: Add auth pam_faillock preauth even_deny_root before pam_unix.so
- pamd:
- name: '{{ item }}'
- type: auth
- control: sufficient
- module_path: pam_unix.so
- new_type: auth
- new_control: required
- new_module_path: pam_faillock.so
- module_arguments: preauth silent even_deny_root
- state: before
- loop:
- - system-auth
- - password-auth
+- name: Check if system relies on authconfig
+ ansible.builtin.stat:
+ path: /usr/sbin/authconfig
+ register: result_authconfig_check
 when: '"pam" in ansible_facts.packages'
 tags:
 - CCE-80668-7
@@ -42,17 +32,10 @@
 - no_reboot_needed
 - restrict_strategy
 
-- name: Add even_deny_root argument to auth pam_faillock preauth
- pamd:
- name: '{{ item }}'
- type: auth
- control: required
- module_path: pam_faillock.so
- module_arguments: preauth silent even_deny_root
- state: args_present
- loop:
- - system-auth
- - password-auth
+- name: Check the presence of /etc/security/faillock.conf file
+ ansible.builtin.stat:
+ path: /etc/security/faillock.conf
+ register: result_faillock_conf_check
 when: '"pam" in ansible_facts.packages'
 tags:
 - CCE-80668-7
@@ -67,20 +50,36 @@
 - no_reboot_needed
 - restrict_strategy
 
-- name: Add auth pam_faillock authfail even_deny_root after pam_unix.so
- pamd:
- name: '{{ item }}'
- type: auth
- control: sufficient
- module_path: pam_unix.so
- new_type: auth
- new_control: '[default=die]'
- new_module_path: pam_faillock.so
- module_arguments: authfail even_deny_root
- state: after
- loop:
- - system-auth
- - password-auth
+- name: Ensure the pam_faillock.so even_deny_root parameter in /etc/security/faillock.conf
+ ansible.builtin.lineinfile:
+ path: /etc/security/faillock.conf
+ regexp: ^\s*even_deny_root
+ line: even_deny_root
+ state: present
+ 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: Check if pam_faillock.so is already enabled
+ ansible.builtin.lineinfile:
+ path: /etc/pam.d/system-auth
+ regexp: .*auth.*pam_faillock.so.*
+ state: absent
+ check_mode: true
+ changed_when: false
+ register: result_pam_faillock_enabled
 when: '"pam" in ansible_facts.packages'
 tags:
 - CCE-80668-7
@@ -95,54 +94,176 @@
 - no_reboot_needed
 - restrict_strategy
 
-- name: Add even_deny_root argument to auth pam_faillock authfail
- pamd:
- name: '{{ item }}'
- type: auth
- control: '[default=die]'
- module_path: pam_faillock.so
- module_arguments: authfail even_deny_root
- state: args_present
- loop:
- - system-auth
- - password-auth
- when: '"pam" in ansible_facts.packages'
- 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: Add account pam_faillock before pam_unix.so
- pamd:
- name: '{{ item }}'
- type: account
- control: required
- module_path: pam_unix.so
- new_type: account
- new_control: required
- new_module_path: pam_faillock.so
- state: before
- loop:
- - system-auth
- - password-auth
- when: '"pam" in ansible_facts.packages'
- 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: Ensure the pam_faillock.so preauth parameters are not present in the pam files
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (.*pam_faillock.so preauth).*$
+ line: \1 silent
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ - result_pam_faillock_enabled.found
+ 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: Ensure the pam_faillock.so authfail parameters are not present in the pam
+ files
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (.*pam_faillock.so authfail).*$
+ line: \1
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ - result_pam_faillock_enabled.found
+ 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: Ensure pam_faillock.so is properly enabled using authconfig tool
+ ansible.builtin.command:
+ cmd: authconfig --enablefaillock --update
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_authconfig_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: Ensure pam_faillock.so is properly enabled using authselect tool
+ ansible.builtin.command:
+ cmd: authselect enable-feature with-faillock
+ register: result_pam_authselect_cmd
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ - not result_pam_faillock_enabled.found
+ 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: Check if pam_faillock.so even_deny_root parameter is already enabled in pam
+ files
+ ansible.builtin.lineinfile:
+ path: /etc/pam.d/system-auth
+ regexp: .*auth.*pam_faillock.so (preauth|authfail).*even_deny_root
+ state: absent
+ check_mode: true
+ changed_when: false
+ register: result_pam_faillock_even_deny_root
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not 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: Ensure the pam_faillock.so preauth even_deny_root parameter in auth section
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
+ line: \1required\3 even_deny_root
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not result_faillock_conf_check.stat.exists
+ - result_pam_faillock_even_deny_root.found == 0
+ 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: Ensure the pam_faillock.so authfail even_deny_root parameter in auth section
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
+ line: \1required\3 even_deny_root
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not result_faillock_conf_check.stat.exists
+ - result_pam_faillock_even_deny_root.found == 0
+ 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

OVAL definition oval:ssg-accounts_passwords_pam_faillock_enforce_local:def:1 differs:
--- old datastream
+++ new datastream
- extend_definition oval:ssg-accounts_password_pam_faillock:def:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_enforce_local:tst:1
+ criteria AND
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_enforce_local_system_pam_unix_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_enforce_local_password_pam_unix_auth:tst:1
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_enforce_local_system_pam_faillock_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_enforce_local_system_pam_faillock_account:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_enforce_local_password_pam_faillock_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_enforce_local_password_pam_faillock_account:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_enforce_local_parameter_faillock_conf:tst:1
OCIL for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_enforce_local' differs:
--- old datastream
+++ new datastream
@@ -1,5 +1,5 @@
-To check if root user is required to use complex passwords, run the following command:
+To check if only local user are impacted by pam_faillock, run the following command:
 $ grep local_users_only /etc/security/faillock.conf
-The output should return local_users_only uncommented.
+The output should return local_users_only not commented.
 Is it the case that local_users_only is not uncommented or configured correctly?
 
bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_enforce_local' differs:
--- old datastream
+++ new datastream
@@ -1,20 +1,20 @@
 # Remediation is applicable only in certain platforms
 if rpm --quiet -q pam; then
 
-if [ -e "/etc/security/faillock.conf" ] ; then
- 
- LC_ALL=C sed -i "/^\s*local_users_only/Id" "/etc/security/faillock.conf"
-else
- touch "/etc/security/faillock.conf"
+SYSTEM_AUTH="/etc/pam.d/system-auth"
+PASSWORD_AUTH="/etc/pam.d/password-auth"
+FAILLOCK_CONF="/etc/security/faillock.conf"
+
+if [ $(grep -c "^\s*auth.*pam_unix.so" $SYSTEM_AUTH) > 1 ] || \
+ [ $(grep -c "^\s*auth.*pam_unix.so" $PASSWORD_AUTH) > 1 ]; then
+ echo "Skipping remediation because there are more pam_unix.so entries than expected."
+ false
 fi
-# make sure file has newline at the end
-sed -i -e '$a\' "/etc/security/faillock.conf"
 
-cp "/etc/security/faillock.conf" "/etc/security/faillock.conf.bak"
-# Insert at the end of the file
-printf '%s\n' "local_users_only" >> "/etc/security/faillock.conf"
-# Clean up after ourselves.
-rm "/etc/security/faillock.conf.bak"
+if [ ! $(grep -q '^\s*local_users_only' $FAILLOCK_CONF) ]; then
+ echo "local_users_only" >> $FAILLOCK_CONF
+fi
+authselect enable-feature with-faillock
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_enforce_local' differs:
--- old datastream
+++ new datastream
@@ -11,10 +11,10 @@
 - no_reboot_needed
 - restrict_strategy
 
-- name: Enforce pam_faillock for Local Accounts Only
- lineinfile:
+- name: Ensure the pam_faillock.so local_users_only parameter in /etc/security/faillock.conf
+ ansible.builtin.lineinfile:
 path: /etc/security/faillock.conf
- create: true
+ regexp: ^\s*local_users_only
 line: local_users_only
 state: present
 when: '"pam" in ansible_facts.packages'
@@ -27,3 +27,39 @@
 - medium_severity
 - no_reboot_needed
 - restrict_strategy
+
+- name: Check if pam_faillock.so is already enabled
+ ansible.builtin.lineinfile:
+ path: /etc/pam.d/system-auth
+ regexp: .*auth.*pam_faillock.so.*
+ state: absent
+ check_mode: true
+ changed_when: false
+ register: result_pam_faillock_enabled
+ when: '"pam" in ansible_facts.packages'
+ 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: Ensure pam_faillock.so is properly enabled using authselect tool
+ ansible.builtin.command:
+ cmd: authselect enable-feature with-faillock
+ register: result_pam_authselect_cmd
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not result_pam_faillock_enabled.found
+ 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

OVAL definition oval:ssg-accounts_passwords_pam_faillock_interval:def:1 differs:
--- old datastream
+++ new datastream
- criteria None
- criterion oval:ssg-test_accounts_passwords_pam_faillock_fail_interval_system-auth:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_authfail_fail_interval_system-auth:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_fail_interval_password-auth:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_preauth_fail_interval_password-auth:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_account_requires_password-auth:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_account_requires_system-auth:tst:1
+ criteria AND
+ criteria AND
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_interval_system_pam_unix_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_interval_password_pam_unix_auth:tst:1
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_interval_system_pam_faillock_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_interval_system_pam_faillock_account:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_interval_password_pam_faillock_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_interval_password_pam_faillock_account:tst:1
+ criteria OR
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_interval_parameter_pamd_system:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_interval_parameter_pamd_password:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_interval_parameter_no_faillock_conf:tst:1
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_interval_parameter_no_pamd_system:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_interval_parameter_no_pamd_password:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_interval_parameter_faillock_conf:tst:1
OCIL for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_interval' differs:
--- old datastream
+++ new datastream
@@ -1,8 +1,6 @@
-To ensure the failed password attempt policy is configured correctly,
-run the following command:
-$ grep pam_faillock /etc/pam.d/system-auth /etc/pam.d/password-auth
-For each file, the output should show fail_interval=<interval-in-seconds> where interval-in-seconds is or greater.
-If the fail_interval parameter is not set, the default setting
-of 900 seconds is acceptable.
+To ensure the failed password attempt policy is configured correctly, run the following command:
+
+$ grep fail_interval /etc/security/faillock.conf
+The output should show fail_interval = <interval-in-seconds> where interval-in-seconds is or greater.
 Is it the case that fail_interval is less than the required value?
 
bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_interval' differs:
--- old datastream
+++ new datastream
@@ -4,7 +4,35 @@
 var_accounts_passwords_pam_faillock_fail_interval=''
 
 
-AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
+SYSTEM_AUTH="/etc/pam.d/system-auth"
+PASSWORD_AUTH="/etc/pam.d/password-auth"
+FAILLOCK_CONF="/etc/security/faillock.conf"
+
+if [ $(grep -c "^\s*auth.*pam_unix.so" $SYSTEM_AUTH) > 1 ] || \
+ [ $(grep -c "^\s*auth.*pam_unix.so" $PASSWORD_AUTH) > 1 ]; then
+ echo "Skipping remediation because there are more pam_unix.so entries than expected."
+ false
+fi
+
+if [ -f $FAILLOCK_CONF ]; then
+ if $(grep -q '^\s*fail_interval\s*=' $FAILLOCK_CONF); then
+ sed -i --follow-symlinks "s/^\s*\(fail_interval\s*\)=.*$/\1 = $var_accounts_passwords_pam_faillock_fail_interval/g" $FAILLOCK_CONF
+ else
+ echo "fail_interval = $var_accounts_passwords_pam_faillock_fail_interval" >> $FAILLOCK_CONF
+ fi
+ # If the faillock.conf file is present, but for any reason, like an OS upgrade, the
+ # pam_faillock.so parameters are still defined in pam files, this makes them compatible with
+ # the newer versions of authselect tool and ensure the parameters are only in faillock.conf.
+ sed -i --follow-symlinks 's/\(pam_faillock.so preauth\).*$/\1 silent/g' $SYSTEM_AUTH $PASSWORD_AUTH
+ sed -i --follow-symlinks 's/\(pam_faillock.so authfail\).*$/\1/g' $SYSTEM_AUTH $PASSWORD_AUTH
+ authselect enable-feature with-faillock
+else
+ if [ -f /usr/sbin/authconfig ]; then
+ authconfig --enablefaillock --update
+ else
+ authselect enable-feature with-faillock
+ fi
+ AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
 
 for pam_file in "${AUTH_FILES[@]}"
 do
@@ -42,6 +70,7 @@
 sed -E -i --follow-symlinks '/^\s*account\s*required\s*pam_unix.so/i account required pam_faillock.so' "$pam_file"
 fi
 done
+fi
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_interval' differs:
--- old datastream
+++ new datastream
@@ -18,134 +18,303 @@
 tags:
 - always
 
-- name: Add auth pam_faillock preauth fail_interval before pam_unix.so
- pamd:
- name: '{{ item }}'
- type: auth
- control: sufficient
- module_path: pam_unix.so
- new_type: auth
- new_control: required
- new_module_path: pam_faillock.so
- module_arguments: preauth silent fail_interval={{ var_accounts_passwords_pam_faillock_fail_interval
+- name: Check if system relies on authconfig
+ ansible.builtin.stat:
+ path: /usr/sbin/authconfig
+ register: result_authconfig_check
+ when: '"pam" in ansible_facts.packages'
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Check the presence of /etc/security/faillock.conf file
+ ansible.builtin.stat:
+ path: /etc/security/faillock.conf
+ register: result_faillock_conf_check
+ when: '"pam" in ansible_facts.packages'
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure the pam_faillock.so fail_interval parameter in /etc/security/faillock.conf
+ ansible.builtin.lineinfile:
+ path: /etc/security/faillock.conf
+ regexp: ^\s*fail_interval\s*=
+ line: fail_interval = {{ var_accounts_passwords_pam_faillock_fail_interval }}
+ state: present
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Check if pam_faillock.so is already enabled
+ ansible.builtin.lineinfile:
+ path: /etc/pam.d/system-auth
+ regexp: .*auth.*pam_faillock.so.*
+ state: absent
+ check_mode: true
+ changed_when: false
+ register: result_pam_faillock_enabled
+ when: '"pam" in ansible_facts.packages'
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure the pam_faillock.so preauth parameters are not present in the pam files
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (.*pam_faillock.so preauth).*$
+ line: \1 silent
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ - result_pam_faillock_enabled.found
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure the pam_faillock.so authfail parameters are not present in the pam
+ files
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (.*pam_faillock.so authfail).*$
+ line: \1
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ - result_pam_faillock_enabled.found
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure pam_faillock.so is properly enabled using authconfig tool
+ ansible.builtin.command:
+ cmd: authconfig --enablefaillock --update
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_authconfig_check.stat.exists
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure pam_faillock.so is properly enabled using authselect
+ ansible.builtin.command:
+ cmd: authselect enable-feature with-faillock
+ register: result_pam_authselect_cmd
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ - not result_pam_faillock_enabled.found
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Check if pam_faillock.so fail_interval parameter is already enabled in pam
+ files
+ ansible.builtin.lineinfile:
+ path: /etc/pam.d/system-auth
+ regexp: .*auth.*pam_faillock.so (preauth|authfail).*fail_interval
+ state: absent
+ check_mode: true
+ changed_when: false
+ register: result_pam_faillock_fail_interval
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not result_faillock_conf_check.stat.exists
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure the desired value for pam_faillock.so preauth fail_interval parameter
+ in auth section
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(fail_interval)=[0-5]+(.*)
+ line: \1required\3\4={{ var_accounts_passwords_pam_faillock_fail_interval }}\5
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not result_faillock_conf_check.stat.exists
+ - result_pam_faillock_fail_interval.found > 0
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure the desired value for pam_faillock.so authfail fail_interval parameter
+ in auth section
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(fail_interval)=[0-5]+(.*)
+ line: \1required\3\4={{ var_accounts_passwords_pam_faillock_fail_interval }}\5
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not result_faillock_conf_check.stat.exists
+ - result_pam_faillock_fail_interval.found > 0
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure the inclusion of pam_faillock.so preauth fail_interval parameter in
+ auth section
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
+ line: \1required\3 fail_interval={{ var_accounts_passwords_pam_faillock_fail_interval
 }}
- state: before
- loop:
- - system-auth
- - password-auth
- when: '"pam" in ansible_facts.packages'
- tags:
- - CCE-80669-5
- - DISA-STIG-RHEL-08-020012
- - NIST-800-53-AC-7(a)
- - NIST-800-53-CM-6(a)
- - accounts_passwords_pam_faillock_interval
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed
- - restrict_strategy
-
-- name: Add fail_interval argument to auth pam_faillock preauth
- pamd:
- name: '{{ item }}'
- type: auth
- control: required
- module_path: pam_faillock.so
- module_arguments: preauth silent fail_interval={{ var_accounts_passwords_pam_faillock_fail_interval
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not result_faillock_conf_check.stat.exists
+ - result_pam_faillock_fail_interval.found == 0
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure the inclusion of pam_faillock.so authfail fail_interval parameter in
+ auth section
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
+ line: \1required\3 fail_interval={{ var_accounts_passwords_pam_faillock_fail_interval
 }}
- state: args_present
- loop:
- - system-auth
- - password-auth
- when: '"pam" in ansible_facts.packages'
- tags:
- - CCE-80669-5
- - DISA-STIG-RHEL-08-020012
- - NIST-800-53-AC-7(a)
- - NIST-800-53-CM-6(a)
- - accounts_passwords_pam_faillock_interval
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed
- - restrict_strategy
-
-- name: Add auth pam_faillock aufthfail fail_interval after pam_unix.so
- pamd:
- name: '{{ item }}'
- type: auth
- control: sufficient
- module_path: pam_unix.so
- new_type: auth
- new_control: '[default=die]'
- new_module_path: pam_faillock.so
- module_arguments: authfail fail_interval={{ var_accounts_passwords_pam_faillock_fail_interval
- }}
- state: after
- loop:
- - system-auth
- - password-auth
- when: '"pam" in ansible_facts.packages'
- tags:
- - CCE-80669-5
- - DISA-STIG-RHEL-08-020012
- - NIST-800-53-AC-7(a)
- - NIST-800-53-CM-6(a)
- - accounts_passwords_pam_faillock_interval
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed
- - restrict_strategy
-
-- name: Add fail_interval argument to auth pam_faillock authfail
- pamd:
- name: '{{ item }}'
- type: auth
- control: '[default=die]'
- module_path: pam_faillock.so
- module_arguments: authfail fail_interval={{ var_accounts_passwords_pam_faillock_fail_interval
- }}
- state: args_present
- loop:
- - system-auth
- - password-auth
- when: '"pam" in ansible_facts.packages'
- tags:
- - CCE-80669-5
- - DISA-STIG-RHEL-08-020012
- - NIST-800-53-AC-7(a)
- - NIST-800-53-CM-6(a)
- - accounts_passwords_pam_faillock_interval
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed
- - restrict_strategy
-
-- name: Add account pam_faillock before pam_unix.so
- pamd:
- name: '{{ item }}'
- type: account
- control: required
- module_path: pam_unix.so
- new_type: account
- new_control: required
- new_module_path: pam_faillock.so
- state: before
- loop:
- - system-auth
- - password-auth
- when: '"pam" in ansible_facts.packages'
- tags:
- - CCE-80669-5
- - DISA-STIG-RHEL-08-020012
- - NIST-800-53-AC-7(a)
- - NIST-800-53-CM-6(a)
- - accounts_passwords_pam_faillock_interval
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed
- - restrict_strategy
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not result_faillock_conf_check.stat.exists
+ - result_pam_faillock_fail_interval.found == 0
+ tags:
+ - CCE-80669-5
+ - DISA-STIG-RHEL-08-020012
+ - NIST-800-53-AC-7(a)
+ - NIST-800-53-CM-6(a)
+ - accounts_passwords_pam_faillock_interval
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy

OVAL definition oval:ssg-accounts_passwords_pam_faillock_unlock_time:def:1 differs:
--- old datastream
+++ new datastream
- criteria None
- criterion oval:ssg-test_var_faillock_unlock_time_is_never:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_is_never:tst:1
- criteria None
- criterion oval:ssg-test_var_faillock_unlock_time_is_never:tst:1
- criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_greater_or_equal_ext_var:tst:1
+ criteria AND
+ criteria AND
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_system_pam_unix_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_password_pam_unix_auth:tst:1
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_system_pam_faillock_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_system_pam_faillock_account:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_password_pam_faillock_auth:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_password_pam_faillock_account:tst:1
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_parameter_pamd_system:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_parameter_pamd_password:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_parameter_no_faillock_conf:tst:1
+ criteria AND
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_parameter_no_pamd_system:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_parameter_no_pamd_password:tst:1
+ criterion oval:ssg-test_accounts_passwords_pam_faillock_unlock_time_parameter_faillock_conf:tst:1
OCIL for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_unlock_time' differs:
--- old datastream
+++ new datastream
@@ -1,5 +1,8 @@
 To ensure the failed password attempt policy is configured correctly, run the following command:
-$ grep pam_faillock /etc/pam.d/system-auth
-The output should show unlock_time=<some-large-number> or 0 for never.
+
+$ grep fail_interval /etc/security/faillock.conf
+The output should show unlock_time = <interval-in-seconds> where interval-in-seconds is or greater.
+
+It can also be 0 for never.
 Is it the case that unlock_time is less than the expected value?
 
bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_unlock_time' differs:
--- old datastream
+++ new datastream
@@ -4,7 +4,35 @@
 var_accounts_passwords_pam_faillock_unlock_time=''
 
 
-AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
+SYSTEM_AUTH="/etc/pam.d/system-auth"
+PASSWORD_AUTH="/etc/pam.d/password-auth"
+FAILLOCK_CONF="/etc/security/faillock.conf"
+
+if [ $(grep -c "^\s*auth.*pam_unix.so" $SYSTEM_AUTH) > 1 ] || \
+ [ $(grep -c "^\s*auth.*pam_unix.so" $PASSWORD_AUTH) > 1 ]; then
+ echo "Skipping remediation because there are more pam_unix.so entries than expected."
+ false
+fi
+
+if [ -f $FAILLOCK_CONF ]; then
+ if $(grep -q '^\s*unlock_time\s*=' $FAILLOCK_CONF); then
+ sed -i --follow-symlinks "s/^\s*\(unlock_time\s*\)=.*$/\1 = $var_accounts_passwords_pam_faillock_unlock_time/g" $FAILLOCK_CONF
+ else
+ echo "unlock_time = $var_accounts_passwords_pam_faillock_unlock_time" >> $FAILLOCK_CONF
+ fi
+ # If the faillock.conf file is present, but for any reason, like an OS upgrade, the
+ # pam_faillock.so parameters are still defined in pam files, this makes them compatible with
+ # the newer versions of authselect tool and ensure the parameters are only in faillock.conf.
+ sed -i --follow-symlinks 's/\(pam_faillock.so preauth\).*$/\1 silent/g' $SYSTEM_AUTH $PASSWORD_AUTH
+ sed -i --follow-symlinks 's/\(pam_faillock.so authfail\).*$/\1/g' $SYSTEM_AUTH $PASSWORD_AUTH
+ authselect enable-feature with-faillock
+else
+ if [ -f /usr/sbin/authconfig ]; then
+ authconfig --enablefaillock --update
+ else
+ authselect enable-feature with-faillock
+ fi
+ AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
 
 for pam_file in "${AUTH_FILES[@]}"
 do
@@ -42,6 +70,7 @@
 sed -E -i --follow-symlinks '/^\s*account\s*required\s*pam_unix.so/i account required pam_faillock.so' "$pam_file"
 fi
 done
+fi
 
 else
 >&2 echo 'Remediation is not applicable, nothing was done'

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_unlock_time' differs:
--- old datastream
+++ new datastream
@@ -4,7 +4,7 @@
 tags:
 - CCE-80670-3
 - CJIS-5.5.3
- - DISA-STIG-RHEL-08-020014
+ - DISA-STIG-RHEL-08-020016
 - NIST-800-171-3.1.8
 - NIST-800-53-AC-7(b)
 - NIST-800-53-CM-6(a)
@@ -21,149 +21,249 @@
 tags:
 - always
 
-- name: Add auth pam_faillock preauth unlock_time before pam_unix.so
- pamd:
- name: '{{ item }}'
- type: auth
- control: sufficient
- module_path: pam_unix.so
- new_type: auth
- new_control: required
- new_module_path: pam_faillock.so
- module_arguments: preauth silent unlock_time={{ var_accounts_passwords_pam_faillock_unlock_time
- }}
- state: before
- loop:
- - system-auth
- - password-auth
+- name: Check if system relies on authconfig
+ ansible.builtin.stat:
+ path: /usr/sbin/authconfig
+ register: result_authconfig_check
 when: '"pam" in ansible_facts.packages'
 tags:
 - CCE-80670-3
 - CJIS-5.5.3
- - DISA-STIG-RHEL-08-020014
- - NIST-800-171-3.1.8
- - NIST-800-53-AC-7(b)
- - NIST-800-53-CM-6(a)
- - PCI-DSS-Req-8.1.7
- - accounts_passwords_pam_faillock_unlock_time
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed
- - restrict_strategy
-
-- name: Add unlock_time argument to pam_faillock preauth
- pamd:
- name: '{{ item }}'
- type: auth
- control: required
- module_path: pam_faillock.so
- module_arguments: preauth silent unlock_time={{ var_accounts_passwords_pam_faillock_unlock_time
- }}
- state: args_present
- loop:
- - system-auth
- - password-auth
+ - DISA-STIG-RHEL-08-020016
+ - NIST-800-171-3.1.8
+ - NIST-800-53-AC-7(b)
+ - NIST-800-53-CM-6(a)
+ - PCI-DSS-Req-8.1.7
+ - accounts_passwords_pam_faillock_unlock_time
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Check the presence of /etc/security/faillock.conf file
+ ansible.builtin.stat:
+ path: /etc/security/faillock.conf
+ register: result_faillock_conf_check
 when: '"pam" in ansible_facts.packages'
 tags:
 - CCE-80670-3
 - CJIS-5.5.3
- - DISA-STIG-RHEL-08-020014
- - NIST-800-171-3.1.8
- - NIST-800-53-AC-7(b)
- - NIST-800-53-CM-6(a)
- - PCI-DSS-Req-8.1.7
- - accounts_passwords_pam_faillock_unlock_time
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed
- - restrict_strategy
-
-- name: Add auth pam_faillock authfail unlock_interval after pam_unix.so
- pamd:
- name: '{{ item }}'
- type: auth
- control: sufficient
- module_path: pam_unix.so
- new_type: auth
- new_control: '[default=die]'
- new_module_path: pam_faillock.so
- module_arguments: authfail unlock_time={{ var_accounts_passwords_pam_faillock_unlock_time
- }}
- state: after
- loop:
- - system-auth
- - password-auth
+ - DISA-STIG-RHEL-08-020016
+ - NIST-800-171-3.1.8
+ - NIST-800-53-AC-7(b)
+ - NIST-800-53-CM-6(a)
+ - PCI-DSS-Req-8.1.7
+ - accounts_passwords_pam_faillock_unlock_time
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure the pam_faillock.so unlock_time parameter in /etc/security/faillock.conf
+ ansible.builtin.lineinfile:
+ path: /etc/security/faillock.conf
+ regexp: ^\s*unlock_time\s*=
+ line: unlock_time = {{ var_accounts_passwords_pam_faillock_unlock_time }}
+ state: present
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ tags:
+ - CCE-80670-3
+ - CJIS-5.5.3
+ - DISA-STIG-RHEL-08-020016
+ - NIST-800-171-3.1.8
+ - NIST-800-53-AC-7(b)
+ - NIST-800-53-CM-6(a)
+ - PCI-DSS-Req-8.1.7
+ - accounts_passwords_pam_faillock_unlock_time
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Check if pam_faillock.so is already enabled
+ ansible.builtin.lineinfile:
+ path: /etc/pam.d/system-auth
+ regexp: .*auth.*pam_faillock.so.*
+ state: absent
+ check_mode: true
+ changed_when: false
+ register: result_pam_faillock_enabled
 when: '"pam" in ansible_facts.packages'
 tags:
 - CCE-80670-3
 - CJIS-5.5.3
- - DISA-STIG-RHEL-08-020014
- - NIST-800-171-3.1.8
- - NIST-800-53-AC-7(b)
- - NIST-800-53-CM-6(a)
- - PCI-DSS-Req-8.1.7
- - accounts_passwords_pam_faillock_unlock_time
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed
- - restrict_strategy
-
-- name: Add unlock_time argument to auth pam_faillock authfail
- pamd:
- name: '{{ item }}'
- type: auth
- control: '[default=die]'
- module_path: pam_faillock.so
- module_arguments: authfail unlock_time={{ var_accounts_passwords_pam_faillock_unlock_time
- }}
- state: args_present
- loop:
- - system-auth
- - password-auth
- when: '"pam" in ansible_facts.packages'
- tags:
- - CCE-80670-3
- - CJIS-5.5.3
- - DISA-STIG-RHEL-08-020014
- - NIST-800-171-3.1.8
- - NIST-800-53-AC-7(b)
- - NIST-800-53-CM-6(a)
- - PCI-DSS-Req-8.1.7
- - accounts_passwords_pam_faillock_unlock_time
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed
- - restrict_strategy
-
-- name: Add account pam_faillock before pam_unix.so
- pamd:
- name: '{{ item }}'
- type: account
- control: required
- module_path: pam_unix.so
- new_type: account
- new_control: required
- new_module_path: pam_faillock.so
- state: before
- loop:
- - system-auth
- - password-auth
- when: '"pam" in ansible_facts.packages'
- tags:
- - CCE-80670-3
- - CJIS-5.5.3
- - DISA-STIG-RHEL-08-020014
- - NIST-800-171-3.1.8
- - NIST-800-53-AC-7(b)
- - NIST-800-53-CM-6(a)
- - PCI-DSS-Req-8.1.7
- - accounts_passwords_pam_faillock_unlock_time
- - low_complexity
- - low_disruption
- - medium_severity
- - no_reboot_needed
- - restrict_strategy
+ - DISA-STIG-RHEL-08-020016
+ - NIST-800-171-3.1.8
+ - NIST-800-53-AC-7(b)
+ - NIST-800-53-CM-6(a)
+ - PCI-DSS-Req-8.1.7
+ - accounts_passwords_pam_faillock_unlock_time
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure the pam_faillock.so preauth parameters are not present in the pam files
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (.*pam_faillock.so preauth).*$
+ line: \1 silent
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ - result_pam_faillock_enabled.found
+ tags:
+ - CCE-80670-3
+ - CJIS-5.5.3
+ - DISA-STIG-RHEL-08-020016
+ - NIST-800-171-3.1.8
+ - NIST-800-53-AC-7(b)
+ - NIST-800-53-CM-6(a)
+ - PCI-DSS-Req-8.1.7
+ - accounts_passwords_pam_faillock_unlock_time
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure the pam_faillock.so authfail parameters are not present in the pam
+ files
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (.*pam_faillock.so authfail).*$
+ line: \1
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ - result_pam_faillock_enabled.found
+ tags:
+ - CCE-80670-3
+ - CJIS-5.5.3
+ - DISA-STIG-RHEL-08-020016
+ - NIST-800-171-3.1.8
+ - NIST-800-53-AC-7(b)
+ - NIST-800-53-CM-6(a)
+ - PCI-DSS-Req-8.1.7
+ - accounts_passwords_pam_faillock_unlock_time
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure pam_faillock.so is properly enabled using authconfig tool
+ ansible.builtin.command:
+ cmd: authconfig --enablefaillock --update
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_authconfig_check.stat.exists
+ tags:
+ - CCE-80670-3
+ - CJIS-5.5.3
+ - DISA-STIG-RHEL-08-020016
+ - NIST-800-171-3.1.8
+ - NIST-800-53-AC-7(b)
+ - NIST-800-53-CM-6(a)
+ - PCI-DSS-Req-8.1.7
+ - accounts_passwords_pam_faillock_unlock_time
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure pam_faillock.so is properly enabled using authselect
+ ansible.builtin.command:
+ cmd: authselect enable-feature with-faillock
+ register: result_pam_authselect_cmd
+ when:
+ - '"pam" in ansible_facts.packages'
+ - result_faillock_conf_check.stat.exists
+ - not result_pam_faillock_enabled.found
+ tags:
+ - CCE-80670-3
+ - CJIS-5.5.3
+ - DISA-STIG-RHEL-08-020016
+ - NIST-800-171-3.1.8
+ - NIST-800-53-AC-7(b)
+ - NIST-800-53-CM-6(a)
+ - PCI-DSS-Req-8.1.7
+ - accounts_passwords_pam_faillock_unlock_time
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure the pam_faillock.so preauth unlock_time parameter in auth section
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(unlock_time)=[0-5]+(.*)
+ line: \1required\3\4={{ var_accounts_passwords_pam_faillock_unlock_time }}\5
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not result_faillock_conf_check.stat.exists
+ tags:
+ - CCE-80670-3
+ - CJIS-5.5.3
+ - DISA-STIG-RHEL-08-020016
+ - NIST-800-171-3.1.8
+ - NIST-800-53-AC-7(b)
+ - NIST-800-53-CM-6(a)
+ - PCI-DSS-Req-8.1.7
+ - accounts_passwords_pam_faillock_unlock_time
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy
+
+- name: Ensure the pam_faillock.so authfail unlock_time parameter in auth section
+ ansible.builtin.lineinfile:
+ path: '{{ item }}'
+ backrefs: true
+ regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(unlock_time)=[0-5]+(.*)
+ line: \1required\3\4={{ var_accounts_passwords_pam_faillock_unlock_time }}\5
+ state: present
+ loop:
+ - /etc/pam.d/system-auth
+ - /etc/pam.d/password-auth
+ when:
+ - '"pam" in ansible_facts.packages'
+ - not result_faillock_conf_check.stat.exists
+ tags:
+ - CCE-80670-3
+ - CJIS-5.5.3
+ - DISA-STIG-RHEL-08-020016
+ - NIST-800-171-3.1.8
+ - NIST-800-53-AC-7(b)
+ - NIST-800-53-CM-6(a)
+ - PCI-DSS-Req-8.1.7
+ - accounts_passwords_pam_faillock_unlock_time
+ - low_complexity
+ - low_disruption
+ - medium_severity
+ - no_reboot_needed
+ - restrict_strategy

bash remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_home_directories' differs:
--- old datastream
+++ new datastream
@@ -1,7 +1,2 @@
 
-for home_dir in $(awk -F':' '{ if ($4 >= 1000 && $4 != 65534) print $6 }' /etc/passwd); do
- # Only update the permissions when necessary. This will avoid changing the inode timestamp when
- # the permission is already defined as expected, therefore not impacting in possible integrity
- # check systems that also check inodes timestamps.
- find $home_dir -perm /7027 -exec chmod u-s,g-w-s,o=- {} \;
-done
+awk -F':' '{ if ($4 >= 1000 && $4 != 65534) system("chmod -f 700 "$6) }' /etc/passwd

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_file_permissions_home_directories' differs:
--- old datastream
+++ new datastream
@@ -48,7 +48,7 @@
 directories
 ansible.builtin.file:
 path: '{{ item.0.value[4] }}'
- mode: u-s,g-w-s,o=-
+ mode: '0700'
 loop: '{{ local_users|zip(path_exists.results)|list }}'
 when: item.1.stat is defined and item.1.stat.exists
 tags:

@marcusburghardt marcusburghardt added the do-not-merge/work-in-progress Used by openshift-ci bot. label Dec 1, 2021
@marcusburghardt marcusburghardt removed the do-not-merge/work-in-progress Used by openshift-ci bot. label Dec 1, 2021
@yuumasato yuumasato self-assigned this Dec 2, 2021
@yuumasato yuumasato added this to the 0.1.60 milestone Dec 7, 2021
@marcusburghardt
Copy link
Member Author

/retest

Copy link
Member

@yuumasato yuumasato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marcusburghardt Nice work on the rules, :)

Just fix the conflict and it should be good to go.

Redesign the OVAL and remediations logic to make the rule compatible
with newer versions of pam and authselect tool, which define the
pam_faillock.so parameters in /etc/security/faillock.conf. The new logic
also covered some new possible situations making the rule more robust.
Redesign the OVAL and remediation logic aligning this rule
with the other rules related to pam_faillock.so.
Redesigned the OVAL and remediation logic aligning this rule
with the other rules related to pam_faillock.so.
Redesigned the OVAL and remediation logic aligning this rule
with the other rules related to pam_faillock.so.
Aligned the OVAL and remediation logic of this rule with the
other rules related to pam_faillock.so.
@marcusburghardt
Copy link
Member Author

@marcusburghardt Nice work on the rules, :)

Just fix the conflict and it should be good to go.

Thanks @yuumasato.
Conflicts solved.

@openshift-ci
Copy link

openshift-ci bot commented Dec 13, 2021

@marcusburghardt: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-aws-rhcos4-moderate c79db43 link true /test e2e-aws-rhcos4-moderate

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.

@marcusburghardt
Copy link
Member Author

/retest

@yuumasato yuumasato merged commit c902d40 into ComplianceAsCode:master Dec 13, 2021
@marcusburghardt marcusburghardt deleted the BZ1956972 branch December 14, 2021 08:14
@marcusburghardt marcusburghardt added RHEL8 Red Hat Enterprise Linux 8 product related. CIS CIS Benchmark related. labels Jun 15, 2022
@marcusburghardt marcusburghardt added STIG STIG Benchmark related. RHEL7 Red Hat Enterprise Linux 7 product related. labels Jun 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CIS CIS Benchmark related. RHEL7 Red Hat Enterprise Linux 7 product related. RHEL8 Red Hat Enterprise Linux 8 product related. STIG STIG Benchmark related.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants