PlusMagi's Blog By Pitt Phunsanit Linux,SecDevOps ClamAV: Shell script ตรวจสอบและสั่งอัปเดตฐานข้อมูลพร้อมสแกน

ClamAV: Shell script ตรวจสอบและสั่งอัปเดตฐานข้อมูลพร้อมสแกน

ข้อเสียของ ClamAV คือมันไม่ได้ scan เครื่องเองเหมือน antivirus เจ้าอื่น ๆ แต่เราแก้ได้โดย การ ใช้ shell script ในการทำรอบการ scan เอง




clamav_monthly_check.sh

  1. สร้างไฟล์
    sudo nano /usr/local/bin/clamav_monthly_check.sh
  2. ใส่เนื้อหา แล้วบันทึก
    1. ctrl + x
    2. Y

/usr/local/bin/clamav_monthly_check.sh

#!/usr/bin/env bash
set -euo pipefail

# -------------------------------------------------------------
# Configuration
# -------------------------------------------------------------
SCAN_TARGET="/"                         # ไดเรกทอรีเป้าหมายที่ต้องการสแกน
LOG_FILE="/var/log/clamav_scheduled.log"  # ไฟล์ log
STATE_FILE="/var/lib/clamav/last_scan_month" # ไฟล์บันทึกสถานะรอบเดือนที่สแกนล่าสุด
QUARANTINE_DIR="/var/quarantine/clamav" # ไดเรกทอรีเก็บไฟล์ติดไวรัส (optional)

# ตรวจสอบสิทธิ์ root/sudo ก่อนทำงาน
if [[ $EUID -ne 0 ]]; then
   echo "[-] Script must be run as root or via sudo" >&2
   exit 1
fi

mkdir -p "$(dirname "$STATE_FILE")"
mkdir -p "$QUARANTINE_DIR"

CURRENT_DOM=$(date +%-d)               # วันที่ปัจจุบัน (1-31)
CURRENT_MONTH_KEY=$(date +%Y-%m)       # รหัสรอบเดือนปัจจุบัน เช่น 2026-09

LAST_SCANNED_MONTH=""
if [[ -f "$STATE_FILE" ]]; then
    LAST_SCANNED_MONTH=$(cat "$STATE_FILE" 2>/dev/null || echo "")
fi

# -------------------------------------------------------------
# Evaluation Logic
# -------------------------------------------------------------
SHOULD_SCAN=false
REASON=""

if [[ "$CURRENT_DOM" -eq 13 ]]; then
    SHOULD_SCAN=true
    REASON="Scheduled run on the 13th"
elif [[ "$LAST_SCANNED_MONTH" != "$CURRENT_MONTH_KEY" && "$CURRENT_DOM" -gt 13 ]]; then
    # เลยวันที่ 13 มาแล้ว แต่รอบของเดือนนี้ยังไม่เคยรันสำเร็จ (เช่น เครื่องปิด)
    SHOULD_SCAN=true
    REASON="Catch-up scan triggered (Missed scan for $CURRENT_MONTH_KEY)"
elif [[ -z "$LAST_SCANNED_MONTH" ]]; then
    # กรณีเพิ่งติดตั้งสคริปต์และยังไม่มีประวัติสแกนมาก่อน
    SHOULD_SCAN=true
    REASON="Initial setup run"
fi

if [[ "$SHOULD_SCAN" == false ]]; then
    exit 0
fi

# -------------------------------------------------------------
# Execution
# -------------------------------------------------------------
log_msg() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log_msg "[*] Starting ClamAV routine. Reason: $REASON"

# 1. Update Virus Database
log_msg "[*] Updating signature database via freshclam..."
if systemctl is-active --quiet clamav-freshclam; then
    # หาก freshclam รันเป็น daemon อยู่แล้ว ให้ reload/trigger
    systemctl restart clamav-freshclam || true
else
    freshclam --quiet || log_msg "[!] Warning: freshclam reported non-zero status"
fi

# 2. Execute ClamAV Scan
log_msg "[*] Starting scan on target: $SCAN_TARGET"
# หมายเหตุ: clamscan ส่ง exit code 0 = สะอาด, 1 = พบไวรัส, >1 = เกิดข้อผิดพลาด
SCAN_EXIT=0
clamscan -r -i \
    --exclude-dir="^/sys" \
    --exclude-dir="^/proc" \
    --exclude-dir="^/dev" \
    --exclude-dir="^/var/quarantine" \
    --move="$QUARANTINE_DIR" \
    --log="$LOG_FILE" \
    "$SCAN_TARGET" || SCAN_EXIT=$?

if [[ "$SCAN_EXIT" -le 1 ]]; then
    # บันทึกสถานะรอบสำเร็จ (0 หรือ 1 ถือว่าการสแกนทำงานจนจบ)
    echo "$CURRENT_MONTH_KEY" > "$STATE_FILE"
    log_msg "[+] ClamAV scan completed successfully. (Exit code: $SCAN_EXIT)"
else
    log_msg "[-] ClamAV scan aborted or encountered an error. (Exit code: $SCAN_EXIT)"
    exit "$SCAN_EXIT"
fi



การตั้งค่า Cron Job

เพื่อให้ระบบสามารถตรวจจับและรันชดเชยได้ทันทีเมื่อเปิดเครื่องหรือข้ามวัน ให้ตั้ง crontab ให้เรียกเช็คทุกวันในช่วงเวลาที่ต้องการ (เช่น ตี 2)

# เปิด root crontab
sudo EDITOR=nano crontab -e
หรือ
sudo crontab -e

# เพิ่มบรรทัดนี้ลงไปล่างสุด (สคริปต์จะกรองวันเอง ถ้าไม่ใช่วันที่ 13 และไม่มีรอบค้าง จะ exit ทันทีโดยไม่กิน resource)
0 2 * * * /bin/bash /usr/local/bin/clamav_monthly_check.sh

อ่านเพิ่มเติม

Exit mobile version