Set Interval For Counting Failed Password Attempts

Classification:

compliance

Framework:

Control:

Description

Utilizing pam_faillock.so, the fail_interval directive configures the system to lock out an account after a number of incorrect login attempts within a specified time period.

Rationale

By limiting the number of failed logon attempts the risk of unauthorized system access via user password guessing, otherwise known as brute-forcing, is reduced. Limits are imposed by locking the account.

Remediation

Shell script

The following script can be run on the host to remediate the issue.

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'libpam-runtime' 2>/dev/null | grep -q installed; then

var\_accounts\_passwords\_pam\_faillock\_fail\_interval='900'


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
authselect enable-feature with-faillock

authselect apply-changes -b
else
 
pam\_file="/etc/pam.d/common-auth"
if ! grep -qE '^\s\*auth\s+required\s+pam\_faillock\.so\s+preauth.\*$' "$pam\_file" ; then
 sed -i --follow-symlinks '/^auth.\*pam\_unix\.so.\*/i auth required pam\_faillock.so preauth' "$pam\_file"
fi
if ! grep -qE '^\s\*auth\s+\[default=die\]\s+pam\_faillock\.so\s+authfail.\*$' "$pam\_file" ; then
 sed -i --follow-symlinks '/^auth.\*pam\_unix\.so.\*/a auth [default=die] pam\_faillock.so authfail' "$pam\_file"
fi
if ! grep -qE '^\s\*auth\s+sufficient\s+pam\_faillock\.so\s+authsucc.\*$' "$pam\_file" ; then
 sed -i --follow-symlinks '/^auth.\*pam\_faillock\.so.\*authfail.\*/a auth sufficient pam\_faillock.so authsucc' "$pam\_file"
fi

pam\_file="/etc/pam.d/common-account"
if ! grep -qE '^\s\*account\s+required\s+pam\_faillock\.so.\*$' "$pam\_file" ; then
 echo 'account required pam\_faillock.so' >> "$pam\_file"
fi

fi

AUTH\_FILES=("/etc/pam.d/common-auth" "/etc/pam.d/password-auth")

FAILLOCK\_CONF="/etc/security/faillock.conf"
if [ -f $FAILLOCK\_CONF ]; then
 regex="^\s\*fail\_interval\s\*="
 line="fail\_interval = $var\_accounts\_passwords\_pam\_faillock\_fail\_interval"
 if ! grep -q $regex $FAILLOCK\_CONF; then
 echo $line >> $FAILLOCK\_CONF
 else
 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
 for pam\_file in "${AUTH\_FILES[@]}"
 do
 if ! grep -qE '^\s\*auth.\*pam\_faillock\.so (preauth|authfail).\*fail\_interval' "$pam\_file"; then
 sed -i --follow-symlinks '/^auth.\*required.\*pam\_faillock\.so.\*preauth.\*silent.\*/ s/$/ fail\_interval='"$var\_accounts\_passwords\_pam\_faillock\_fail\_interval"'/' "$pam\_file"
 sed -i --follow-symlinks '/^auth.\*required.\*pam\_faillock\.so.\*authfail.\*/ s/$/ fail\_interval='"$var\_accounts\_passwords\_pam\_faillock\_fail\_interval"'/' "$pam\_file"
 else
 sed -i --follow-symlinks 's/\(^auth.\*required.\*pam\_faillock\.so.\*preauth.\*silent.\*\)\('"fail\_interval"'=\)[0-9]\+\(.\*\)/\1\2'"$var\_accounts\_passwords\_pam\_faillock\_fail\_interval"'\3/' "$pam\_file"
 sed -i --follow-symlinks 's/\(^auth.\*required.\*pam\_faillock\.so.\*authfail.\*\)\('"fail\_interval"'=\)[0-9]\+\(.\*\)/\1\2'"$var\_accounts\_passwords\_pam\_faillock\_fail\_interval"'\3/' "$pam\_file"
 fi
 done
fi

else
 >&2 echo 'Remediation is not applicable, nothing was done'
fi

Warning

If the system relies on authselect tool to manage PAM settings, the remediation will also use authselect tool. However, if any manual modification was made in PAM files, the authselect integrity check will fail and the remediation will be aborted in order to preserve intentional changes. In this case, an informative message will be shown in the remediation report. If the system supports the /etc/security/faillock.conf file, the pam_faillock parameters should be defined in faillock.conf file.