Tag: gemini.google.com

  • Debian Oval auto check

    Debian Oval auto check

    วันก่อนเขียนสคริปต์ตรวจสอบ Debian oval อัตโนมัติเขียนเสร็จ อ่ะ ไหนๆ สมัครโปรของ เจ๊มินิ (gemini.google.com) แล้ว ให้เจ๊ช่วยขัดเกลาสคริปต์ bash script บ้านๆ เสร็จปุบ ดูหรูไฮ… ทันตาเห็น จากสคริปต์ พบว่าเขียน bash ยังไงให้ถูก ? โวะเพิ่งรู้ว่ามีนั่นนี่โน่น…

    • สร้างสคริปต์ gem-oval-check.sh มีข้อความว่า
    gem-oval-check.sh
    #!/usr/bin/env bash
    # OVAL Updater & Parser - Final Fixed Version 
    # Description: Downloads Debian OVAL definitions, checks for CVEs, generates links, and sends an email report.
    
    # -------------------------
    # 1. Configuration & Variables
    # -------------------------
    readonly DEBIAN_CODENAME=$(lsb_release -c | awk '{print $2}')
    readonly DEBIAN_RELEASE=$(cat /etc/debian_version)
    readonly SERVER_HOSTNAME=$(hostname -f)
    readonly SERVER_IP=$(hostname -I | awk '{print $1}')
    readonly URL="https://www.debian.org/security/oval/oval-definitions-${DEBIAN_CODENAME}.xml.bz2"
    readonly DEST_BZ2="oval-definitions-${DEBIAN_CODENAME}.xml.bz2"
    readonly DEST_XML="oval-definitions-${DEBIAN_CODENAME}.xml"
    readonly TMP_BZ2="/tmp/${DEST_BZ2}"
    readonly RESULT_XML="oval_result.xml"
    readonly ID_FILE="/tmp/oval_ids_${DEBIAN_CODENAME}"
    readonly MSG_FILE="/tmp/oval_messages_${DEBIAN_CODENAME}"
    readonly CVE_REPORT="/tmp/oval_cve_titles_parsed_${DEBIAN_CODENAME}"
    
    readonly REPORT_TO="***************YOUR E-MAIL ADDRESS******************"
    SUBJECT="OVAL Report ${SERVER_HOSTNAME} $(date +%F)"
    
    # -------------------------
    # 2. Functions
    # -------------------------
    
    # Function for clean up temporary files
    cleanup() {
        rm -f "${ID_FILE}" "${MSG_FILE}" "${CVE_REPORT}"
    }
    trap cleanup EXIT
    
    # Function to generate URL based on the security ID (CVE or DSA)
    generate_url() {
        local id_string=$1
        if [[ "$id_string" =~ ^CVE-[0-9]{4}-[0-9]+$ ]]; then
            echo "https://cve.mitre.org/cgi-bin/cvename.cgi?name=${id_string}"
        elif [[ "$id_string" =~ ^DSA-[0-9]+-[0-9]+$ ]]; then
            echo "https://www.debian.org/security/${id_string}"
        else
            echo "(No Link Available)"
        fi
    }
    
    # Function to generate and send email
    send_report() {
        local exit_status=$1
        local message_type=$2 # 'SUCCESS', 'INFO', 'ERROR', 'CVE_FOUND'
        local status_prefix=""
        case "${message_type}" in
            "SUCCESS")
                status_prefix="[OVAL OK] Not Found"
                ;;
            "INFO")
                status_prefix="[OVAL INFO] Not Found (Old File Check)"
                ;;
            "ERROR")
                status_prefix="[OVAL ERROR]"
                ;;
            "CVE_FOUND")
                status_prefix="[OVAL ALERT] CVE Found!"
                ;;
        esac
        
        local final_subject="${status_prefix} - OVAL Report ${SERVER_HOSTNAME} $(date +%F)"
    
        {
            echo "Host Name: ${SERVER_HOSTNAME}"
            echo "IP Address: ${SERVER_IP}"
        } > "${MSG_FILE}"
    
        case "${message_type}" in
            "SUCCESS")
                echo "**********************" >> "${MSG_FILE}"
                echo "* Congratulations!  *" >> "${MSG_FILE}"
                echo "**********************" >> "${MSG_FILE}"
                echo "Distribution: ${DEBIAN_CODENAME} Release: ${DEBIAN_RELEASE}" >> "${MSG_FILE}"
                echo "No CVE found" >> "${MSG_FILE}"
                echo "No definitions with result=true found" >> "${MSG_FILE}"
                ;;
            "INFO")
                echo "**********************" >> "${MSG_FILE}"
                echo "* OVAL Check Ran   *" >> "${MSG_FILE}"
                echo "**********************" >> "${MSG_FILE}"
                echo "File not modified (HTTP 304). Check performed on local file." >> "${MSG_FILE}"
                echo "Distribution: ${DEBIAN_CODENAME} Release: ${DEBIAN_RELEASE}" >> "${MSG_FILE}"
                echo "No CVE found" >> "${MSG_FILE}"
                ;;
            "ERROR")
                echo "**********************" >> "${MSG_FILE}"
                echo "* ERROR!       *" >> "${MSG_FILE}"
                echo "**********************" >> "${MSG_FILE}"
                echo "$3" >> "${MSG_FILE}"
                ;;
            "CVE_FOUND")
                echo "**********************" >> "${MSG_FILE}"
                echo "* CVE Found!!!   *" >> "${MSG_FILE}"
                echo "**********************" >> "${MSG_FILE}"
                echo "Distribution: ${DEBIAN_CODENAME} Release: ${DEBIAN_RELEASE}" >> "${MSG_FILE}"
                echo "--------------------------------------------------------" >> "${MSG_FILE}"
                echo "Package | Security ID | URL" >> "${MSG_FILE}"
                echo "--------------------------------------------------------" >> "${MSG_FILE}"
                cat "${CVE_REPORT}" >> "${MSG_FILE}" 
                ;;
        esac
    
        if ! mail -s "${final_subject}" "${REPORT_TO}" < "${MSG_FILE}"; then
            echo "🚨 ERROR: Failed to send email report to ${REPORT_TO}" >&2
        fi
        echo "Report sent to ${REPORT_TO}. Exiting with status ${exit_status}."
        exit "${exit_status}"
    }
    
    # -------------------------
    # 3. Main Logic
    # -------------------------
    
    echo "🚀 Starting OVAL check for Debian ${DEBIAN_CODENAME} (${DEBIAN_RELEASE}) on ${SERVER_HOSTNAME} (${SERVER_IP})..."
    
    STATUS=$(curl -s -f -w "%{http_code}" -z "${TMP_BZ2}" -o "${TMP_BZ2}" "${URL}" || echo "999")
    
    case "${STATUS}" in
        200)
            echo "✅ New/updated file downloaded (HTTP 200). Processing..."
            
            rm -f "${DEST_XML}" "${RESULT_XML}"
            cp "${TMP_BZ2}" "${DEST_BZ2}"
            
            ;&
    
        304)
            if [ "$STATUS" -eq 304 ]; then
                echo "ℹ️ OVAL file not modified (HTTP 304). Running check on existing file..."
            fi
            
            if [ ! -f "${DEST_XML}" ] && [ ! -f "${DEST_BZ2}" ]; then
                if [ -f "${TMP_BZ2}" ]; then
                    echo "⚠️ Local file missing. Using cached file for check."
                    cp "${TMP_BZ2}" "${DEST_BZ2}"
                else
                    send_report 1 "ERROR" "Cannot process OVAL check. Local files missing (HTTP ${STATUS})."
                fi
            fi
    
            if [ ! -f "${DEST_XML}" ]; then
                if ! bunzip2 -f "${DEST_BZ2}"; then
                    send_report 1 "ERROR" "Failed to decompress OVAL file: bunzip2 failed."
                fi
            fi
    
            echo "🔬 Running OVAL evaluation with oscap..."
            oscap oval eval --results "${RESULT_XML}" "${DEST_XML}" || true 
    
            grep "<definition " "${RESULT_XML}" 2>/dev/null | \
              sed -nE 's/.*id="([^"]+)".*result="([^"]+)".*/\1,\2/p' | \
              awk -F, 'tolower($2) ~ /true/ {print $1}' | sort -u > "${ID_FILE}"
            
            if [ -s "${ID_FILE}" ]; then
                echo "🚨 Found $(wc -l < "${ID_FILE}") definitions with result=true."
                
                : > "${CVE_REPORT}" 
                
                while IFS= read -r ID || [ -n "${ID}" ]; do
                    [ -z "${ID}" ] && continue
                    
                    CVE_TITLE=$(grep -a -A6 -F -- "$ID" "${RESULT_XML}" 2>/dev/null | \
                                sed -n 's/.*<title>\(.*\)<\/title>.*/\1/p' | head -n1 || true)
    
                    if [ -n "$CVE_TITLE" ]; then
                        SECURITY_ID=$(echo "${CVE_TITLE}" | awk '{print $1}')
                        PACKAGE_NAME=$(echo "${CVE_TITLE}" | awk '{print $2}')
                        
                        LINK=$(generate_url "${SECURITY_ID}")
                        
                        PARSED_CVE="${PACKAGE_NAME} | ${SECURITY_ID} | ${LINK}"
                    else
                        PARSED_CVE="(no-title-found-for-${ID})"
                    fi
                    
                    echo "${PARSED_CVE}" >> "${CVE_REPORT}"
                done < "${ID_FILE}"
    
                send_report 0 "CVE_FOUND"
    
            else
                echo "✅ No vulnerable definitions found (result=true)."
                if [ "$STATUS" -eq 304 ]; then
                     send_report 0 "INFO"
                else
                     send_report 0 "SUCCESS"
                fi
            fi
            ;;
    
        999)
            send_report 1 "ERROR" "Network/Curl failed to reach ${URL}"
            ;;
    
        *)
            send_report 1 "ERROR" "Something went wrong: Unexpected HTTP status code ${STATUS} from ${URL}"
            ;;
    esac
    • เปลี่ยนสิทธิ์
    Bash
    chmod +x gem-oval-check.sh
    • อย่าลืมก่อนใช้งานต้องติดตั้ง openscap-scanner ด้วยคำสั่ง
    Bash
    apt install -y openscap-scanner
    • จากนั้นตั้ง crontab รันวันละครั้ง
    Bash
    crontab -e
    • กรอกข้อมูล
    Bash
    30 2 * * * /path_to_script/gem-oval-check.sh > /dev/null 2>&1
    • ก็จะมีอีเมลส่งมาทุกวันนนน
    • จบ
    • ขอให้สนุก