In the previous part,
Securing Privilege Escalation was completed.
1. CIS Benchmark Requirements (Section 5.3)
The duplicate and disordered numbering has been corrected and aligned with the standard:
- 5.3 Pluggable Authentication Modules
- 5.3.1 Configure PAM software packages
- 5.3.1.1 Ensure latest version of
pamis installed (Automated) - 5.3.1.2 Ensure latest version of
authselectis installed (Automated) - 5.3.1.3 Ensure latest version of
libpwqualityis installed (Automated) - 5.3.2 Configure
authselect - 5.3.2.1 Ensure active
authselectprofile includes PAM modules (Automated) - 5.3.2.2 Ensure
pam_faillockmodule is enabled (Automated) - 5.3.2.3 Ensure
pam_pwqualitymodule is enabled (Automated) - 5.3.2.4 Ensure
pam_pwhistorymodule is enabled (Automated) - 5.3.2.5 Ensure
pam_unixmodule is enabled (Automated)
2. Concept & Rationale
Concept: This section focuses on configuring the PAM (Pluggable Authentication Modules) infrastructure and centrally managing authentication policies through the authselect tool.
Security rationale:
- Base packages (5.3.1): Oracle Linux 9 depends on the
pam,authselect, andlibpwqualitypackages for authentication management. Keeping these packages updated is essential for remediating security vulnerabilities. - Authselect management (5.3.2.1): In modern Linux releases such as EL9, manually editing files under
/etc/pam.d/is deprecated and unsafe. Integratedauthselectprofiles should be used instead. - Account lockout (5.3.2.2 - faillock): The
pam_faillockmodule helps defend against brute-force attacks by temporarily locking an account after multiple failed login attempts. - Password complexity (5.3.2.3 - pwquality): Enforces stricter password rules such as minimum length, mixed case, numbers, and special characters.
- Password history (5.3.2.4 - pwhistory): Prevents users from reusing previous passwords.
- Secure hashing (5.3.2.5 - pam_unix): Ensures passwords are hashed and stored using strong modern algorithms such as
yescryptorsha512.
3. Oracle Database Compatibility (RAC, ASM, Grid)
Conflict level: Low to medium (requires careful handling for automation and system accounts)
Oracle-specific considerations:
- Interaction with
faillock: In Oracle RAC environments, monitoring scripts such as Oracle Enterprise Manager (OEM), cluster processes, or automated logins may generate failed attempts because of transient network issues or configuration mistakes. Iffaillockis active, critical accounts such asoracleorgridmay become locked, potentially causing a full database service outage. - Recommended solution: Oracle system accounts such as
oracleandgridshould be excluded from lockout restrictions. This can be implemented through/etc/security/faillock.confor related management parameters. - Interaction with
pwquality: During silent Grid Infrastructure or database installations, or when using provisioning tools such as Ansible or Terraform, generated and injected passwords for database or operating system users must comply with the activepam_pwqualitypolicy. Otherwise, installation may fail because the password is rejected.
4. How to Audit (Audit Script)
The following script checks whether the required packages are installed and verifies the active authselect profile:
GitHub link for this script: modules/audit_18_PAM_Authselect.sh
If you are not familiar with Bash scripting, you can refer to the training published for database administrators on the site: Bash for Oracle DBAs.
#!/bin/bash
# Script: audit18.sh
# Purpose: Audit Script for PAM, Authselect & Oracle Faillock Bypass (CIS 5.3)
if [ "$EUID" -ne 0 ]; then
echo -e "\e[31m[!] Please run as root\e[0m"
exit 1
fi
FAIL_COUNT=0
echo "=========================================================================="
echo " Audit Script for PAM Packages & Authselect Profile (CIS 5.3)"
echo " Context: EL9 authselect requires 'with-faillock' and 'without-nullok'."
echo " Exception (Oracle): 'oracle' and 'grid' must be bypassed in PAM to avoid DB outage."
echo "=========================================================================="
echo -e "\n[*] Checking required PAM packages..."
check_package() {
local pkg=$1
if rpm -q "$pkg" >/dev/null 2>&1; then
echo -e " \e[32m[PASS]\e[0m Package '$pkg' is installed"
else
echo -e " \e[31m[FAIL]\e[0m Package '$pkg' is NOT installed"
((FAIL_COUNT++))
fi
}
check_package "pam"
check_package "authselect"
check_package "libpwquality"
echo -e "\n[*] Checking Authselect Profile configuration..."
CURRENT_PROFILE=$(authselect current 2>/dev/null | head -n 1 | awk '{print $3}')
if [ -z "$CURRENT_PROFILE" ] || [[ "$CURRENT_PROFILE" == "No" ]]; then
echo -e " \e[31m[FAIL]\e[0m No authselect profile is currently active"
((FAIL_COUNT++))
else
echo -e " \e[32m[PASS]\e[0m Active authselect profile: $CURRENT_PROFILE"
check_authselect_feature() {
local feature=$1
if authselect current 2>/dev/null | grep -qw "$feature"; then
echo -e " \e[32m[PASS]\e[0m Feature '$feature' is enabled"
else
echo -e " \e[31m[FAIL]\e[0m Feature '$feature' is missing"
((FAIL_COUNT++))
fi
}
check_authselect_feature "with-faillock"
check_authselect_feature "without-nullok"
fi
echo -e "\n[*] Checking Oracle/Grid Faillock Bypass..."
if grep -q "pam_succeed_if.so user in oracle:grid" /etc/pam.d/system-auth 2>/dev/null; then
echo -e " \e[32m[PASS]\e[0m Oracle/Grid accounts are successfully excluded from faillock rules"
else
echo -e " \e[31m[FAIL]\e[0m Oracle/Grid accounts are NOT excluded from faillock (High Risk for DB!)"
((FAIL_COUNT++))
fi
echo "=========================================================================="
if [ $FAIL_COUNT -eq 0 ]; then
echo -e "\e[32m[+] AUDIT PASSED: PAM, Authselect, and Oracle Exceptions are perfectly configured.\e[0m"
else
echo -e "\e[31m[-] AUDIT FAILED: $FAIL_COUNT issue(s) found. Run remediation18.sh.\e[0m"
fi
5. How to Remediate with Bash (Remediation Script)
This script installs the required packages and configures the authselect profile with the necessary security modules enabled:
GitHub link for this script: modules/remediate_18_PAM_Authselect.sh
#!/bin/bash
# Script: remediation18.sh
# Purpose: Remediation Script for PAM & Authselect with Oracle Exclusions (CIS 5.3)
if [ "$EUID" -ne 0 ]; then
echo -e "\e[31m[!] Please run as root\e[0m"
exit 1
fi
echo "=========================================================================="
echo " Remediation Script for PAM Packages & Authselect Profile (CIS 5.3)"
echo " Action: Creating custom authselect profile to implement 'with-faillock'"
echo " while explicitly excluding 'oracle' and 'grid' accounts."
echo "=========================================================================="
# Variables for custom profile
CUSTOM_PROFILE_NAME="oracle-sssd"
BASE_PROFILE="sssd"
CUSTOM_DIR="/etc/authselect/custom/$CUSTOM_PROFILE_NAME"
echo -e "\n[*] 1. Creating Custom Authselect Profile for Oracle..."
# Ensure any broken previous attempts are cleaned up
rm -rf "$CUSTOM_DIR"
echo "Creating custom profile '$CUSTOM_PROFILE_NAME' based on '$BASE_PROFILE'..."
# Without --symlinks to ensure physical files are copied and modifiable
authselect create-profile "$CUSTOM_PROFILE_NAME" -b "$BASE_PROFILE"
if [ ! -d "$CUSTOM_DIR" ]; then
echo -e "\e[31m[!] Error: Failed to create custom authselect profile!\e[0m"
exit 1
fi
echo -e "\n[*] 2. Injecting Faillock Bypass logic for 'oracle' and 'grid' users..."
BYPASS_RULE="auth [success=1 default=ignore] pam_succeed_if.so user in oracle:grid"
for pam_file in system-auth password-auth; do
FILE_PATH="$CUSTOM_DIR/$pam_file"
if [ -f "$FILE_PATH" ]; then
# Insert bypass rule right above the first occurrence of pam_faillock preauth
sed -i "/pam_faillock.so preauth/i $BYPASS_RULE" "$FILE_PATH"
# Insert bypass rule right above pam_faillock authfail
sed -i "/pam_faillock.so authfail/i $BYPASS_RULE" "$FILE_PATH"
# Insert bypass rule right above pam_faillock authsucc
sed -i "/pam_faillock.so authsucc/i $BYPASS_RULE" "$FILE_PATH"
echo " -> Injected successfully into $pam_file"
else
echo " -> Warning: File $pam_file not found in custom directory!"
fi
done
echo -e "\n[*] 3. Applying the new Custom Oracle Profile..."
# Select the profile. In EL9 the path prefix 'custom/' is required.
authselect select "custom/$CUSTOM_PROFILE_NAME" with-faillock without-nullok --force
echo -e "\n[*] 4. Forcing Authselect changes to PAM stack..."
authselect apply-changes
echo -e "\n[*] Current Authselect Configuration:"
authselect current
echo "=========================================================================="
echo -e "\e[32m[+] Remediation completed.\e[0m"
echo -e "Please run audit18.sh to verify."
In the next part, we will cover: