۱. الزامات 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"
در قسمت بعد به سراغ:
پیکربندی پارامترهای رمز عبور
می رویم.