Bash for Oracle DBAs Part 12: Final Project — Hardening Script Case Study

Bash for Oracle DBAs — Part 12: Final Project — Hardening Script Case Study

در این قسمت پایانی از مجموعهٔ Bash for Oracle DBAs، به‌جای آموزش یک ساختار جدید، یک پروژهٔ واقعی و کوچک Hardening را کالبدشکافی می‌کنیم. این رویکرد از دو جهت مهم است: اول اینکه تمام مفاهیمی که در بخش‌های قبلی آموختیم در یک سناریوی عملی کنار هم قرار می‌گیرند، و دوم اینکه یک Oracle DBA می‌تواند ببیند Bash چگونه در دنیای واقعی برای Audit و Remediation استفاده می‌شود.

فایل‌های این مطالعهٔ موردی، روی System-wide Crypto Policy و تنظیمات SSH در Oracle Linux 9 تمرکز دارند. این موضوع برای محیط‌های دیتابیسی مهم است، چون Hardening باید در عین افزایش امنیت، دسترسی مدیریتی DBA و پایداری سرویس‌ها را هم حفظ کند.

در این مقاله دو اسکریپت واقعی را بررسی می‌کنیم:

  • audit_07_System_Crypto_Policy.sh برای بررسی وضعیت فعلی
  • remediate_07_System_Crypto_Policy.sh برای اعمال اصلاحات

این دو اسکریپت از نظر طراحی، مثال خوبی از تفاوت بین Read-only Audit و Privileged Remediation هستند.


۱) هدف سناریو: CIS 1.6 و System-wide Crypto Policy

هدف این سناریو، بررسی و اعمال یک policy سراسری برای Cryptography در سطح سیستم‌عامل است. در این پروژه، دو موضوع اصلی دنبال می‌شود:

  • اطمینان از اینکه سیستم از policy مناسب و امن استفاده می‌کند
  • حذف تنظیمات hardcoded در فایل‌های SSH که ممکن است policy سراسری را دور بزنند

در محیط‌های Oracle، این تغییرات معمولاً باید با دقت انجام شوند تا نه Database service و نه دسترسی SSH برای مدیریت سیستم دچار اختلال نشوند.

۲) نمای کلی اسکریپت Audit

اسکریپت Audit فقط وضعیت را می‌خواند، نتیجه را به‌صورت انسانی گزارش می‌کند و هیچ تغییری در سیستم ایجاد نمی‌کند. این اسکریپت از چند ساختار مهم Bash استفاده می‌کند:

  • Shebang: #!/bin/bash
  • متغیرها: FAIL_COUNT، CURRENT_POLICY، HARDCODED
  • Command substitution با $(...)
  • شرط if و pattern matching در [[ ... ]]
  • grep -E برای جست‌وجوی directiveها
  • Redirectهای ساده مثل 2>/dev/null

کد اصلی Audit به‌صورت زیر است:

#!/bin/bash
# Script: audit_cis_1_6.sh
# Purpose: Audit System-wide Crypto Policy (CIS 1.6)

echo "=========================================================================="
echo " CIS Requirement: 1.6 System-wide Crypto Policy"
echo " - Ensure system-wide crypto policy is set correctly (NO-SHA1, CIS-SSH)."
echo " - Ensure no hardcoded crypto settings exist in sshd_config."
echo " Oracle Context:"
echo " 1. Updating the system crypto policy is generally transparent to"
echo "    Oracle Database and RAC installations."
echo " 2. Removing hardcoded SSH ciphers ensures SSHD uses the system-wide"
echo "    secure policy without disrupting DBA remote access."
echo "=========================================================================="

FAIL_COUNT=0

echo -e "\n[*] 1. Checking System Crypto Policy..."
CURRENT_POLICY=$(update-crypto-policies --show 2>/dev/null)
if [[ "$CURRENT_POLICY" == *"DEFAULT:NO-SHA1:CIS-SSH"* || "$CURRENT_POLICY" == *"FIPS:NO-SHA1:CIS-SSH"* ]]; then
    echo -e "  \e[32m[PASS]\e[0m System Crypto Policy is $CURRENT_POLICY."
else
    echo -e "  \e[31m[FAIL]\e[0m Crypto Policy is $CURRENT_POLICY (Expected: DEFAULT:NO-SHA1:CIS-SSH)."
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

echo -e "\n[*] 2. Checking sshd_config for hardcoded crypto settings..."
HARDCODED=$(grep -h -E -i '^\s*(Ciphers|MACs|KexAlgorithms|GSSAPIKexAlgorithms|HostKeyAlgorithms|PubkeyAcceptedKeyTypes)' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf 2>/dev/null)

if [ -z "$HARDCODED" ]; then
    echo -e "  \e[32m[PASS]\e[0m No hardcoded crypto settings found in SSH config."
else
    echo -e "  \e[31m[FAIL]\e[0m Hardcoded crypto settings found:"
    echo "$HARDCODED"
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

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

۳) تحلیل Audit: چه چیزی را یاد می‌گیریم؟

این اسکریپت نمونهٔ خوبی از یک Audit Script ساده اما کاربردی است. مهم‌ترین نکات آموزشی آن عبارت‌اند از:

  • Command substitution: خروجی دستورها در متغیرها ذخیره می‌شود.
  • Conditional matching: بررسی مقدار policy با [[ ... == *pattern* ]].
  • Regular expression: استفاده از grep -E برای پیدا کردن directiveهای SSH.
  • Counting failures: استفاده از FAIL_COUNT برای جمع‌بندی نتیجه.
  • Redirect to /dev/null: پنهان‌کردن خطاهای غیرضروری از خروجی.

با این حال، از دید طراحی حرفه‌ای، این اسکریپت چند محدودیت هم دارد:

  • از set -euo pipefail استفاده نشده است.
  • exit status واقعی اسکریپت با نتیجهٔ PASS/FAIL هم‌راستا نیست.
  • لاگ جداگانه، timestamp و validation عمیق ندارد.

با وجود این محدودیت‌ها، برای یک اسکریپت Audit سبک، ساختار آن قابل‌فهم و شفاف است.


۴) نمای کلی اسکریپت Remediation

اسکریپت Remediation همان‌طور که از نامش پیداست، تغییر واقعی را اعمال می‌کند. این یعنی سطح خطر آن از Audit بالاتر است و باید با privilege مناسب و دقت بیشتر اجرا شود.

این اسکریپت چند بخش اصلی دارد:

  • بررسی root بودن کاربر
  • Comment کردن directiveهای hardcoded در SSH config
  • ایجاد policy module اختصاصی برای SSH
  • اعمال System-wide Crypto Policy
  • Restart کردن سرویس SSHD

کد اصلی اسکریپت Remediation به‌صورت زیر است:

#!/bin/bash
# Script: remediate_cis_1_6.sh
# Purpose: Configure System-wide Crypto Policy based on CIS (CIS 1.6)
# Context: Oracle Linux 9 (Database/RAC compatible)

if [ "$EUID" -ne 0 ]; then echo "Please run as root"; exit 1; fi

echo -e "\n[+] Applying System-wide Crypto Policy (CIS 1.6)..."

# 1. Remove hardcoded crypto settings from SSH configs (CIS 1.6.2)
echo "[*] Cleaning up hardcoded crypto settings from sshd_config..."
sed -ri 's/^\s*(Ciphers|MACs|KexAlgorithms|GSSAPIKexAlgorithms|HostKeyAlgorithms|PubkeyAcceptedKeyTypes)/# \1/' /etc/ssh/sshd_config
if ls /etc/ssh/sshd_config.d/*.conf 1> /dev/null 2>&1; then
    sed -ri 's/^\s*(Ciphers|MACs|KexAlgorithms|GSSAPIKexAlgorithms|HostKeyAlgorithms|PubkeyAcceptedKeyTypes)/# \1/' /etc/ssh/sshd_config.d/*.conf
fi

# 2. Create custom policy module for SSH restrictions (CIS 1.6.4 to 1.6.7)
echo "[*] Creating custom module /etc/crypto-policies/policies/modules/CIS-SSH.pmod..."
cat < /etc/crypto-policies/policies/modules/CIS-SSH.pmod
# Disable CBC and ChaCha20-Poly1305 for SSH
cipher@ssh = -*CBC -CHACHA20-POLY1305

# Disable MACs less than 128 bits
mac@ssh = -*MD5* -*UMAC-64*
EOF

# 3. Apply the Crypto Policy (CIS 1.6.1, 1.6.3)
echo "[*] Applying DEFAULT:NO-SHA1:CIS-SSH policy..."
update-crypto-policies --set DEFAULT:NO-SHA1:CIS-SSH

# 4. Restart SSHD to apply changes
echo "[*] Restarting SSHD service..."
systemctl restart sshd

echo -e "\n[+] Crypto policy updated and SSHD restarted successfully."

۵) تحلیل Remediation: چه چیزهایی در این اسکریپت مهم است؟

این اسکریپت از نظر Bash و از نظر مدیریت سیستم، چند بخش آموزشی مهم دارد:

  • Root check: با $EUID تشخیص می‌دهد آیا اسکریپت با دسترسی root اجرا شده یا نه.
  • In-place editing: با sed -i فایل‌های پیکربندی را مستقیم تغییر می‌دهد.
  • Glob expansion: الگوی /etc/ssh/sshd_config.d/*.conf برای فایل‌های متعدد استفاده شده است.
  • Here document: با <<EOF محتوای policy module نوشته می‌شود.
  • Service management: با systemctl restart sshd تغییرات اعمال می‌شوند.

این اسکریپت در عمل تغییرات زیر را انجام می‌دهد:

  1. هر directive سخت‌کدشده‌ای مثل Ciphers یا MACs را comment می‌کند.
  2. فایل policy module جدیدی با نام CIS-SSH.pmod ایجاد می‌کند.
  3. Policy سراسری را روی DEFAULT:NO-SHA1:CIS-SSH تنظیم می‌کند.
  4. سرویس SSHD را restart می‌کند تا تغییرات فعال شوند.

۶) تفاوت Audit و Remediation در این پروژه

این بخش مهم‌ترین نتیجهٔ فنی مطالعهٔ موردی است. Audit و Remediation هر دو به یک هدف امنیتی خدمت می‌کنند، اما نقش آن‌ها کاملاً متفاوت است.

موضوع Audit Remediation
هدف تشخیص وضعیت اعمال اصلاح
اثر روی سیستم Read-only تغییردهنده
ابزار اصلی grep و command substitution sed، cat <<EOF، update-crypto-policies
Privilege نیاز معمولاً کم root لازم است
ریسک پایین بالا

برای یک Oracle DBA، این تفکیک بسیار مهم است. ابتدا باید Audit مطمئن شود وضعیت محیط درست نیست، سپس Remediation آن را اصلاح کند. هر دو مرحله باید قابل‌فهم، قابل‌پیش‌بینی و تا حد امکان امن باشند.


۷) مفاهیم Bash که در این پروژه تمرین شدند

اگر بخواهیم از دید آموزشی بگوییم این دو فایل چه چیزهایی را پوشش می‌دهند، فهرست زیر دقیق‌ترین جمع‌بندی است:

  • #!/bin/bash
  • Comment و مستندسازی در ابتدای اسکریپت
  • متغیرها و شمارنده‌ها
  • $(...) برای command substitution
  • [[ ... ]] برای شرط‌های Bash
  • Pattern matching با wildcard
  • grep -E -i -h
  • sed -ri
  • Here document
  • Redirect به /dev/null
  • استفاده از $EUID برای root check
  • systemctl restart

در عین حال، چند ابزار مهم در این پروژه اصلاً استفاده نشده‌اند، از جمله:

  • awk
  • loopها مانند for و while
  • tee
  • pipeline واقعی با |
  • functionها
  • strict mode مانند set -euo pipefail

۸) نکات حرفه‌ای برای بهبود این اسکریپت‌ها

اگر بخواهیم این دو اسکریپت را برای محیط production بالغ‌تر کنیم، چند بهبود مهم پیشنهاد می‌شود:

  • استفاده از set -euo pipefail در Remediation برای جلوگیری از ادامهٔ اسکریپت پس از شکست.
  • گرفتن backup قبل از sed -i و امکان rollback.
  • اعتبارسنجی SSH با sshd -t قبل از restart.
  • بررسی status سرویس با systemctl is-active sshd یا systemctl status sshd.
  • نوشتن log جداگانه برای Audit و Remediation.
  • اضافه‌کردن exit status مناسب برای نتیجهٔ نهایی Audit.

این‌ها دقیقاً همان چیزهایی هستند که در بخش ۱۱ مجموعه دربارهٔ Error Handling و Robust Scripting یاد گرفتیم.


۹) جمع‌بندی نهایی مجموعه

با مطالعهٔ این پروژه، همهٔ قطعات اصلی Bash که برای یک Oracle DBA مهم هستند در کنار هم دیده می‌شوند: شرط‌ها، pattern matching، redirectها، command substitution، grep، sed، heredoc، root check و service control. مهم‌تر از همه، این مقاله نشان می‌دهد که Bash فقط برای اسکریپت‌های ساده نیست؛ بلکه می‌تواند پایهٔ یک workflow قابل‌اعتماد برای Hardening، Audit و Remediation هم باشد.

اگر بخواهم کل مجموعه را در یک جمله خلاصه کنم، نتیجه این است: یک Oracle DBA حرفه‌ای فقط مصرف‌کنندهٔ اسکریپت نیست؛ باید بتواند Bash را آن‌قدر خوب بفهمد که اسکریپت‌های امن، قابل‌پیش‌بینی و قابل‌نگهداری بنویسد.

با این مقاله، مجموعهٔ آموزشی Bash for Oracle DBAs به پایان می‌رسد.


مقاله قبلی:
Bash for Oracle DBAs — Part 11: Error Handling, Strict Mode, and Robust Scripting