امن‌سازی Oracle Linux 9 (مقاله نوزدهم): پیکربندی آرگومان‌های ماژول‌های احراز هویت (PAM Arguments)

۱. الزامات CIS Benchmark (بخش 5.3.3)

  • 5.3.3 Configure PAM Arguments
    • 5.3.3.1 Configure pam_faillock module
  • 5.3.3.1.1 Ensure password failed attempts lockout is configured (Automated)
  • 5.3.3.1.2 Ensure password unlock time is configured (Automated)
  • 5.3.3.1.3 Ensure password failed attempts lockout includes root account (Automated)
    • 5.3.3.2 Configure pam_pwquality module
  • 5.3.3.2.1 Ensure password number of changed characters is configured (Automated)
  • 5.3.3.2.2 Ensure password length is configured (Automated)
  • 5.3.3.2.3 Ensure password complexity is configured (Manual)
  • 5.3.3.2.4 Ensure password same consecutive characters is configured (Automated)
  • 5.3.3.2.5 Ensure password maximum sequential characters is configured (Automated)
  • 5.3.3.2.6 Ensure password dictionary check is enabled (Automated)
  • 5.3.3.2.7 Ensure password quality is enforced for the root user (Automated)
    • 5.3.3.3 Configure pam_pwhistory module
  • 5.3.3.3.1 Ensure password history remember is configured (Automated)
  • 5.3.3.3.2 Ensure password history is enforced for the root user (Automated)
  • 5.3.3.3.3 Ensure pam_pwhistory includes use_authtok (Automated)
    • 5.3.3.4 Configure pam_unix module
  • 5.3.3.4.1 Ensure pam_unix does not include nullok (Automated)
  • 5.3.3.4.2 Ensure pam_unix does not include remember (Automated)
  • 5.3.3.4.3 Ensure pam_unix includes a strong password hashing algorithm (Automated)
  • 5.3.3.4.4 Ensure pam_unix includes use_authtok (Automated)

۲. مفهوم و دلیل امنیتی (Concept & Rationale)

  • قفل‌گذاری با pam_faillock: پس از تعداد مشخصی تلاش ناموفق برای ورود (مثلاً 5 بار)، حساب کاربری برای مدت زمان معینی (مثلاً 900 ثانیه) قفل می‌شود. این سیاست برای جلوگیری از حملات حدس رمز عبور (Brute-force) است و باید برای کاربر root نیز اعمال گردد (even_deny_root).
  • کیفیت رمز با pam_pwquality: اعمال الزاماتی نظیر حداقل طول رمز عبور (مثلاً 14 کاراکتر)، بررسی کلمات با دیکشنری (dictcheck)، جلوگیری از تکرار بیش از حد کاراکترهای متوالی (maxrepeat) و اطمینان از اعمال این سخت‌گیری‌ها بر روی کاربر root.
  • تاریخچه رمز عبور با pam_pwhistory: حفظ و نگهداری رمزهای عبور قبلی (مثلاً 5 رمز آخر) جهت جلوگیری از استفاده مجدد آن‌ها توسط کاربران.
  • مدیریت پایه با pam_unix: مسدودسازی کامل امکان ورود با رمز عبور خالی (nullok) و الزام سیستم به استفاده از الگوریتم‌های قوی هشینگ (مانند yescrypt یا sha512).

۳. بررسی سازگاری با پایگاه داده Oracle (RAC, ASM, Grid)

  • وضعیت تداخل: متوسط تا بالا
  • توضیحات و الزامات اوراکل:
    • بحران قفل شدن کاربران (faillock): اعمال محدودیت ورود اشتباه برای کاربران حیاتی مانند oracle، grid یا حساب‌های اتوماسیون (مانند OEM Agents) بسیار خطرناک است. وجود کانکشن‌های قدیمی، اسکریپت‌های دارای رمز منقضی‌شده، یا تلاش‌های ناموفق مانیتورینگ می‌تواند باعث قفل شدن این کاربران و ایجاد اختلال یا قطعی کامل کلاستر دیتابیس شود. این حساب‌ها باید حتماً در فایل /etc/security/faillock.conf از فرآیند قفل شدن مستثنی شوند.
    • نصب‌های خودکار (pwquality): در هنگام اجرای اسکریپت‌های اتوماسیون (مانند Ansible) که وظیفه ایجاد کاربران دیتابیس یا سیستم‌عامل را بر عهده دارند، رمزهای عبورِ تولیدی باید دقیقاً با این قواعد پیچیدگی مطابقت داشته باشند؛ در غیر این صورت فرآیند Provisioning و نصب با خطای احراز هویت متوقف خواهد شد.

 

۳. نحوه بررسی (Audit Script)

لینک این اسکریپت در github:

modules/audit_19_PAM_Arguments.sh

در صورتی که با bash script  آشنا نیستید، می توانید به آموزشی که برای دیتابیس ادمین ها در سایت گذاشته ام مراجعه کنید.

Bash for Oracle DBAs

#!/bin/bash
# Script: audit19.sh
# Purpose: Audit Script for Faillock & Password Quality (CIS Section 19)

echo "=========================================================================="
echo " CIS Requirement: Password Policies & Lockout Mechanisms"
echo " - Ensure faillock locks out users after 5 failed attempts for 15 mins."
echo " - Ensure pwquality enforces complexity (length, classes, dictcheck)."
echo " - Ensure password history remembers last 5 passwords."
echo " - Ensure yescrypt is used for password hashing."
echo " Oracle Context:"
echo " - WARNING: Strict faillock policies can lock out 'oracle' and 'grid'"
echo "   users during automated deployments (Ansible/Terraform). A PAM bypass"
echo "   should be implemented (covered in Sec 18) to avoid database outages."
echo "=========================================================================="

FAIL_COUNT=0

echo -e "\n[*] Checking faillock configuration (/etc/security/faillock.conf)..."
for param in "deny = 5" "unlock_time = 900" "even_deny_root"; do
    if grep -q -E "^\s*${param}" /etc/security/faillock.conf; then
        echo -e "  \e[32m[PASS]\e[0m $param is configured."
    else
        echo -e "  \e[31m[FAIL]\e[0m $param is missing or incorrect."
        FAIL_COUNT=$((FAIL_COUNT + 1))
    fi
done

echo -e "\n[*] Checking pwquality configuration (/etc/security/pwquality.conf)..."
for param in "difok = 8" "minlen = 14" "minclass = 4" "maxrepeat = 3" "maxsequence = 3" "dictcheck = 1" "enforce_for_root"; do
    if grep -q -E "^\s*${param}" /etc/security/pwquality.conf; then
        echo -e "  \e[32m[PASS]\e[0m $param is configured."
    else
        echo -e "  \e[31m[FAIL]\e[0m $param is missing or incorrect."
        FAIL_COUNT=$((FAIL_COUNT + 1))
    fi
done

echo -e "\n[*] Checking PAM configurations for pwhistory and yescrypt..."
for pam_file in /etc/authselect/system-auth /etc/authselect/password-auth; do
    echo -e "  \e[34m[INFO]\e[0m Checking $pam_file..."

    if grep -E '^\s*password\s+requisite\s+pam_pwhistory.so' $pam_file | grep -q 'remember=5' && \
       grep -E '^\s*password\s+requisite\s+pam_pwhistory.so' $pam_file | grep -q 'enforce_for_root'; then
        echo -e "  \e[32m[PASS]\e[0m pwhistory is set correctly."
    else
        echo -e "  \e[31m[FAIL]\e[0m Missing correct pwhistory settings."
        FAIL_COUNT=$((FAIL_COUNT + 1))
    fi

    if grep -E '^\s*password\s+(sufficient|required)\s+pam_unix.so' $pam_file | grep -q 'yescrypt'; then
        echo -e "  \e[32m[PASS]\e[0m pam_unix is using yescrypt."
    else
        echo -e "  \e[31m[FAIL]\e[0m yescrypt is not configured."
        FAIL_COUNT=$((FAIL_COUNT + 1))
    fi
done

if [ "$FAIL_COUNT" -eq 0 ]; then
    echo -e "\n\e[32m[+] AUDIT RESULT: PASS\e[0m"
else
    echo -e "\n\e[31m[-] AUDIT RESULT: FAIL ($FAIL_COUNT issues found)\e[0m"
fi

۴. نحوه اعمال با Bash (Remediation Script)

لینک این اسکریپت در github:

modules/remediate_19_PAM_Arguments.sh

#!/bin/bash

# =====================================================================
# OS Security Standard Remediation Script - Section 19
# Oracle Context: Strict password policies and lockout mechanisms.
# Oracle Exception: High faillock deny counts could lock out 'oracle'
# or 'grid'.
# =====================================================================

# Ensure script is run as root
if [ "$EUID" -ne 0 ]; then
  echo -e "\033[31m[ERROR] This script must be run as root.\033[0m"
  exit 1
fi

echo -e "\033[36m--- Configuring faillock.conf ---\033[0m"
FAILLOCK_CONF="/etc/security/faillock.conf"
sed -i -E 's/^\s*#?\s*deny\s*=.*/deny = 5/' $FAILLOCK_CONF
sed -i -E 's/^\s*#?\s*unlock_time\s*=.*/unlock_time = 900/' $FAILLOCK_CONF
sed -i -E 's/^\s*#?\s*even_deny_root.*/even_deny_root/' $FAILLOCK_CONF
grep -q "^deny = 5" $FAILLOCK_CONF || echo "deny = 5" >> $FAILLOCK_CONF
grep -q "^unlock_time = 900" $FAILLOCK_CONF || echo "unlock_time = 900" >> $FAILLOCK_CONF
grep -q "^even_deny_root" $FAILLOCK_CONF || echo "even_deny_root" >> $FAILLOCK_CONF

echo -e "\033[36m--- Configuring pwquality.conf ---\033[0m"
PWQUAL_CONF="/etc/security/pwquality.conf"
sed -i -E 's/^\s*#?\s*difok\s*=.*/difok = 8/' $PWQUAL_CONF
sed -i -E 's/^\s*#?\s*minlen\s*=.*/minlen = 14/' $PWQUAL_CONF
sed -i -E 's/^\s*#?\s*minclass\s*=.*/minclass = 4/' $PWQUAL_CONF
sed -i -E 's/^\s*#?\s*maxrepeat\s*=.*/maxrepeat = 3/' $PWQUAL_CONF
sed -i -E 's/^\s*#?\s*maxsequence\s*=.*/maxsequence = 3/' $PWQUAL_CONF
sed -i -E 's/^\s*#?\s*dictcheck\s*=.*/dictcheck = 1/' $PWQUAL_CONF
sed -i -E 's/^\s*#?\s*enforce_for_root.*/enforce_for_root/' $PWQUAL_CONF
grep -q "^maxsequence = 3" $PWQUAL_CONF || echo "maxsequence = 3" >> $PWQUAL_CONF

echo -e "\033[36m--- Configuring Custom Authselect Profile (oracle-sssd) ---\033[0m"
CUSTOM_PROFILE_DIR="/etc/authselect/custom/oracle-sssd"

if [ ! -d "$CUSTOM_PROFILE_DIR" ]; then
    echo -e "\033[33m[WARN] Custom profile 'oracle-sssd' not found. Creating it from sssd...\033[0m"
    authselect create-profile oracle-sssd -b sssd --symlinks
fi

for pam_file in "$CUSTOM_PROFILE_DIR/system-auth" "$CUSTOM_PROFILE_DIR/password-auth"; do
    if [ -f "$pam_file" ]; then
        # 1. Update pam_unix.so to use yescrypt instead of sha512
        sed -i 's/\bsha512\b/yescrypt/g' "$pam_file"

        # 2. Add remember=5 and enforce_for_root to pam_pwhistory.so
        # First ensure the line has the required parameters, if not, append them
        if grep -q "pam_pwhistory.so" "$pam_file"; then
            sed -i -E 's/(pam_pwhistory\.so.*)/\1/' "$pam_file"
            # Safely add remember=5 if missing
            if ! grep -q "pam_pwhistory.so.*remember=" "$pam_file"; then
                sed -i 's/pam_pwhistory.so/pam_pwhistory.so remember=5/g' "$pam_file"
            fi
            # Safely add enforce_for_root if missing
            if ! grep -q "pam_pwhistory.so.*enforce_for_root" "$pam_file"; then
                sed -i 's/pam_pwhistory.so/pam_pwhistory.so enforce_for_root/g' "$pam_file"
            fi
        fi
    fi
done

echo -e "\033[36m--- Applying Authselect Changes ---\033[0m"
# Re-apply the custom profile with required features
authselect select custom/oracle-sssd with-faillock without-nullok with-pwhistory --force
authselect apply-changes

echo -e "\033[32m[OK] Section 19 Remediation completed.\033[0m"

در قسمت بعد به سراغ:

پیکربندی پارامترهای رمز عبور

می رویم.