Category: Linux (OS, shell script, etc)

  • Debian Oval Security auto check

    Debian Oval Security 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, runs check, 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***********"
    SUBJECT="OVAL Report ${SERVER_HOSTNAME} $(date +%F)"
    
    OVAL_TIMESTAMP="N/A"
    OVAL_VERSION="N/A"
    
    # -------------------------
    # 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}"
            echo "-------------------------------------"
            echo "OVAL Version: ${OVAL_VERSION}"
            echo "OVAL Timestamp: ${OVAL_TIMESTAMP}"
            echo "-------------------------------------"
        } > "${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 
    
            if [ -f "${RESULT_XML}" ]; then
                OVAL_VERSION=$(grep 'oval:schema_version' "${DEST_XML}" 2>/dev/null | cut -d\> -f2 | cut -d\< -f1 | head -1 || echo "N/A")
                OVAL_TIMESTAMP=$(grep 'oval:timestamp' "${DEST_XML}" 2>/dev/null | cut -d\> -f2 | cut -d\< -f1 | head -1 || echo "N/A")
    
                echo "🔎 Extracted OVAL Version: ${OVAL_VERSION}, Timestamp: ${OVAL_TIMESTAMP} from result.xml"
            fi
            # ----------------------------------------------------------------------
    
            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
    • ก็จะมีอีเมลส่งมาทุกวันนนน
    • จบ
    • ขอให้สนุก
  • SSH with MFA

    เปิด Multi Factor Authentication (MFA) ให้กับ OpenSSH บน Ubuntu 22.04

    1. ติดตั้ง Google authenticator PAM module

    sudo apt install libpam-google-authenticator

    2. เปิดใช้งาน Google Authenticatior PAM ให้ OpenSSH

    echo "auth required pam_google_authenticator.so" | sudo tee -a /etc/pam.d/sshd
    
    sudo systemctl restart sshd.service

    3. เปิด KbdInteractiveAuthentication

    OpenSSH version 8.7 ขึ้นไปจะใช้ KbdInteractiveAuthentication แทน ChallengeResponseAuthentication

    ตั้งค่า KbdInteractiveAuthentication yes

    sudo grep -q "^KbdInteractiveAuthentication" /etc/ssh/sshd_config && sudo sed -i 's/^#?no/KbdInteractiveAuthentication yes/' /etc/ssh/sshd_config | sudo tee -a /etc/ssh/sshd_config >/dev/null <<<"KbdInteractiveAuthentication yes"
    
    sudo systemctl restart sshd.service

    4. เชื่อมต่อกับ Authenticator

    ใช้คำสั่ง

    google-authenticator

    เปิด Authenticator บน Smart Phone (Google/Microsoft ก็ได้) จากนั้น Scan QR Code จากนั้นตอบตามนี้

    Make tokens “time-base””: yes
    Update the .google_authenticator file: yes
    Disallow multiple uses: yes
    Increase the original generation time limit: no
    Enable rate-limiting: yes

    เมื่อ ssh เข้ามา ก็จะได้หน้าจอประมาณนี้

    หวังว่าจะเป็นประโยชน์ครับ

  • [บันทึกกันลืม] วิธีหาไฟล์ที่มีคำที่ต้องการ โดยแสดงเฉพาะ ชื่อไฟล์เท่านั้น

    โจทย์ ต้องการหาไฟล์ที่มีคำว่า text_pattern จากทุกไฟล์ในไดเรคทอรี่ /path/to/ ที่มีนามสกุล .ipynb แต่ต้องไม่มีคำว่า checkpoint ใน path หรือชื่อไฟล์

    find /path/to -name "*.ipynb" ! -name "*checkpoint*" -type f -print0 | while read -r -d '' i; do
        if grep -q "text_pattern" "$i"; then
             echo "$i"  # Output only the filename if the pattern is found
        fi;
    done
  • Install from scratch – licensing (1)

    ติดตั้งปรับแต่ง Ubuntu 22.04 เพื่อเตรียมสำหรับติดตั้ง WordPress บน apache2 และติดตั้ง WordPress

    Host setting
    1. เครื่อง Server มี 2 ชื่อ A record เป็น server-name1.psu.ac.th Cname เป็น server-name.psu.ac.th
    2. ติดตั้ง Ubuntu 22.04 ข้ามเรื่องการติดตั้ง Ubuntu ไปนะครับ
    3. จะได้ username: group ที่สามารถเรียกใช้ sudo ได้ตั้งแต่เริ่มต้นตามที่ติดตั้ง
    4. sudo apt update && sudo apt dist-upgrade -y && sudo apt autopurge -y เพื่อปรับปรุง software ต่าง ๆ ให้เป็นรุ่นปัจจุบัน
    5. sudo reboot ในกรณีที่มี kernel ใหม่ต้องรีบูตเพื่อเปลี่ยน kernel
    6. sudo apt install mysql-server apache2 php libapache2-mod-php php-mysql php-gd php-imagick php-xml php-curl php-mbstring php-intl php-zip unzip php-apcu
    7. sudo a2enmod ssl rewrite headers
    8. เปลี่ยนเป็น user root ด้วยคำสั่ง sudo -i
    9. cd /etc/ssl/private
    10. cp /home/username/certificate/* . (ต้องได้รับไฟล์ certificate มาเรียบร้อยแล้วนะครับ ขอข้ามไปเรื่องการจัดเตรียมไฟล์ certificate) ในตัวอย่างนี้จะมีไฟล์เดียวคือ star.psu.ac.th-combined.crt
    11. openssl dhparam -out /etc/ssl/private/dhparams_4096.pem
    12. /etc/apache2/sites-available
    13. vi default-ssl.conf
    <IfModule mod_ssl.c>
    SSLUseStapling On
    SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
    <VirtualHost _default_:443>
    ServerAdmin someone@somedomain.com
    ServerName server-name1.psu.ac.th

    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    SSLEngine on

    SSLCertificateFile /etc/ssl/private/star.psu.ac.th-combined.crt

    SSLOpenSSLConfCmd DHParameters "/etc/ssl/private/dhparam.pem"
    SSLOpenSSLConfCmd ECDHParameters brainpoolP512r1
    SSLOpenSSLConfCmd Curves brainpoolP512r1:sect571r1:secp521r1:secp384r1

    #A+
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    SSLHonorCipherOrder on
    SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
    SSLCompression off
    #Header add Strict-Transport-Security "max-age=15768000;includeSubDomains"
    Header always set Strict-Transport-Security "max-age=63072000"

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
    SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory /usr/lib/cgi-bin>
    SSLOptions +StdEnvVars
    </Directory>

    </VirtualHost>
    </IfModule>
    1. vi licensing.conf
    <virtualHost *:80>
        Documentroot /var/www/html/lsc
        ServerName server-name.psu.ac.th
        ErrorLog ${APACHE_LOG_DIR}/licensing_error_log
        CustomLog ${APACHE_LOG_DIR}/licensing_access_log common
        Options -Indexes
        RewriteEngine On
        RewriteRule (.*) https://server-name.psu.ac.th
        RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) [NC]
        RewriteRule ^.* - [F]
    </virtualhost>
    1. vi licensing-ssl.conf
    <IfModule mod_ssl.c>
    SSLUseStapling On
    SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
            <VirtualHost *:443>
                    ServerAdmin someone@somedomain.com
                    ServerName server-name.psu.ac.th
                    DocumentRoot /var/www/html/lsc

                    LogLevel info
                    ErrorLog ${APACHE_LOG_DIR}/lsc-ssl-error.log
                    CustomLog ${APACHE_LOG_DIR}/lsc-ssl-access.log combined

                   SSLEngine on

                    SSLOpenSSLConfCmd DHParameters "/etc/ssl/private/dhparams_4096.pem"
                    SSLOpenSSLConfCmd ECDHParameters brainpoolP512r1
    SSLOpenSSLConfCmd Curves brainpoolP512r1:sect571r1:secp521r1:secp384r1

                    SSLCertificateFile /etc/ssl/private/star.psu.ac.th-combined.crt

    #A+
    SSLProtocol all -SSLv2 -SSLv3
    SSLHonorCipherOrder on
    SSLCipherSuite TLSv1.3 TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384
    SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
    SSLCompression off
    Header always set Strict-Transport-Security "max-age=63072000"

                    RewriteEngine on
                    RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) [NC]
                    RewriteRule ^.* - [F]

                    Options -Indexes

                    <FilesMatch "\.(cgi|shtml|phtml|php)$">
                                    SSLOptions +StdEnvVars
                    </FilesMatch>

                    <Directory /var/www/html/lsc>
                            Options FollowSymLinks
                            AllowOverride All
                    </Directory>

                    <Directory /usr/lib/cgi-bin>
                                    SSLOptions +StdEnvVars
                    </Directory>
            </VirtualHost>
    </IfModule>
    1. a2ensite licensing.conf licensing-ssl.conf default-ssl.conf
    2. a2enmod headers
    3. systemctl restart apache2
    4. mysql
    CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
    create database licensing;
    GRANT ALL PRIVILEGES ON licensing.* TO 'username'@'localhost' WITH GRANT OPTION;
    quit
    1. cd /var/www/html
    2. wget https://wordpress.org/latest.zip
    3. unzip latest.zip
    4. rm latest.zip
    5. mv wordpress lsc
    6. chmod -R username:www-data .
    7. cd lsc
    8. chmod g+w .
    9. logout
    10. จบส่วนการตั้งค่า Host เพื่อเตรียมติดตั้ง WordPress
    11. เปิด browser ไปที่เว็บ http://licensing.psu.ac.th ซึ่งจะถูก redirect ไปที่ https://licensing.psu.ac.th โดยอัตโนมัติ
    12. กรอกข้อมูลสำหรับเชื่อมต่อให้เรียบร้อย และติดตั้ง wordpress ให้เรียบร้อย
    13. กลับมาที่ console หรือ terminal
    14. cd /var/www/html/lsc
    15. chmod og-w .
    16. sudo chown username:www-data .htaccess wp-config.php
    17. chmod og-w .htacess wp-config.php
    18. vi wp-config.php เพิ่มข้อความว่า
    /** Direct install plugin **/
    define('FS_METHOD', 'direct');
    1. cd /var/www/html/lsc/wp-content
    2. mkdir uploads upgrade languages
    3. sudo chown -R username:www-data uploads upgrade languages themes plugins
    4. chmod -R g+w uploads upgrade languages themes plugins เพื่อให้สามารถติดตั้ง plugin theme และ upload ไฟล์ขึ้นเว็บได้ เมื่อติดตั้ง themes และ plugins ได้จนพอใจแล้วสั่งคำสั่งต่อไปนี้ chmod -R g-w upgrades languages themes plugins
    5. จบส่วนติดตั้ง WordPress
  • Ubuntu OVAL

    เครื่องมือตรวจสอบช่องโหว่สำหรับอูบุนตู

    เพิ่มเติม สำหรับ Ubuntu 24.04 10Jun2024

    เมื่อได้รับทราบข้อมูลช่องโหว่ของลีนุกซ์อูบุนตูที่ดูแลอยู่จากเว็บไซต์ให้บริการตรวจสอบช่องโหว่ในระบบได้ฟรีๆ ไม่มีค่าใช้จ่าย เช่น https://www.shodan.io/ ซึ่งบริการฟรี สถานะ Last Seen แสดงวันที่ Shodan แวะเวียนมาตรวจสอบให้ล่าสุด
    จึงเกิดคำถามว่า ถ้าเราได้อัพเดตส่วนประกอบพื้นฐานต่างๆ ที่ Ubuntu มีมาให้ด้วยคำสั่ง
    sudo apt update
    sudo apt dist-upgrade
    แล้วจะรู้ได้อย่างไรว่า ช่องโหว่ต่างๆ ได้ถูกปิดให้ปลอดภัยขึ้นแล้วตามคำแนะนำของ Ubuntu ที่มีประกาศข่าวเรื่องความปลอดภัยเกี่ยวกับอูบุนตูไว้ที่ https://ubuntu.com/security/notices

    อูบุนตูมี Ubuntu OVAL (Open Vulnerability and Assessment Language) ไว้ให้ใช้ตรวจสอบช่องโหว่ ซึ่งใช้โปรแกรมชื่อ OpenSCAP เพื่อทำรายงานช่องโหว่ให้ดูได้เอง ตามขั้นตอนต่อไปนี้

    1. Login เข้าไปที่เครื่องอูบุนตูที่ใช้อินเทอร์เน็ตได้
    2. Download ด้วยการใช้คำสั่ง
    wget https://security-metadata.canonical.com/oval/com.ubuntu.$(lsb_release -cs).usn.oval.xml.bz2

    หรือเลือก Download ให้ตรง Ubuntu Version จากตัวเลือกที่
    https://security-metadata.canonical.com/oval/
    โดยให้เลือกแบบ CVE เพื่อจะได้เปรียบเทียบรายการช่องโหว่กับรายงาน Nessus ที่แสดงด้วย CVE เช่นกัน
    1. คลายไฟล์ที่ถูกบีบอัดลดขนาดที่ Download มาได้ ด้วยการใช้คำสั่ง
    bunzip2 com.ubuntu.$(lsb_release -cs).usn.oval.xml.bz2
    1. ใช้โปรแกรม OpenSCAP เพื่ออ่านเงื่อนไขการตรวจสอบช่องโหว่ต่างๆ บนเครื่อง และสร้างไฟล์รายงานผลชื่อ report.html ด้วยการใช้คำสั่ง
    oscap oval eval --report report.html com.ubuntu.$(lsb_release -cs).usn.oval.xml
    1. เพิ่มเติม จากคุณ เกรียงไกร 15Feb2023 => บางเครื่องต้องติดตั้ง libopenscap8 ก่อนด้วยคำสั่ง sudo apt install libopenscap8 ไม่งั้นใช้ oscap ไม่ได้
    2. เพิ่มเติม สำหรับ Ubuntu 24.04 10Jun2024 => ต้องติดตั้ง openscap-scanner ด้วยคำสั่ง sudo apt install openscap-scanner ไม่งั้นใช้ oscap ไม่ได้
    3. ใช้โปรแกรม เว็บบราวเซอร์ เพื่อเปิดอ่านไฟล์รายงานผลชื่อ report.html

    ตัวอย่างการใช้งานจริงกับเครื่องบริการทดสอบความเร็วอินเทอร์เน็ต Ookla Server ซึ่งใช้เป็นตัวอย่างแสดง

    1. Ubuntu Server 20.04 5.4.0-121#137 15Jun2022 ก่อนจะใช้คำสั่ง sudo apt dist-upgrade เพื่อปรับปรุงความปลอดภัย
      ในรายงานแสดงจำนวน 14 #X ที่ยังมีช่องโหว่ พร้อมด้วยรายการช่องโหว่หมายเลข USN และ CVE ต่างๆ โดยละเอียดตามรูป
    2. Ubuntu Server 20.04 5.4.0-137#154 5Jan2023 เมื่อได้ใช้คำสั่ง sudo apt dist-upgrade ปรับปรุงความปลอดภัยและรีบูทเครื่องแล้ว
      ในรายงานแสดงจำนวน 2 #X ที่ยังมีช่องโหว่ พร้อมด้วยรายการช่องโหว่หมายเลข USN และ CVE ต่างๆ โดยละเอียดตามรูป
    3. เนื่องจากส่วนการปรับปรุงความปลอดภัยอีก 2 รายการที่ยังเหลืออยู่นั้นทาง Ubuntu จะมีบริการให้เฉพาะกับสมาชิก Ubuntu Pro https://ubuntu.com/pro เท่านั้น (จะเขียนคำแนะนำเพิ่มให้ครับ)
      ซึ่งหลังจากทำตามขั้นตอนใส่ คีย์ ของ Ubuntu Pro ลงบน เครื่องอูบุนตูของเราเรียบร้อย และอัพเดตความปลอดภัยเพิ่มจากสิทธิ์ Ubuntu Pro ในรายงาน OVAL จะได้รับการอัพเดตปิดกั้นช่องโหว่อย่างครบถ้วน ตามรูป
    4. ถึงแม้ว่าวันนี้ อูบุนตู ของท่านจะได้รับการอัพเดตล่าสุดแล้ว แต่ด้วยภัยคุกคามทางไซเบอร์มีการเปลี่ยนแปลงอยู่เสมอ ก็อย่าลืมติดตามอ่านข่าวสารเกี่ยวกับความปลอดภัยไซเบอร์ และหมั่นปรับปรุง อัพเดต อยู่เป็นประจำครับ
  • ติดตั้ง haproxy บน Ubuntu Desktop

    เป็นขั้นตอนที่ทำขึ้น เพื่อทำการ redirect port 80 เข้าไปยัง web server ใน VM (OpenNebula miniONE on KVM) ที่เราติดตั้งไว้ในเครื่อง Ubuntu Desktop ในตัวอย่างนี้ Ubuntu Desktop มี IP 192.168.1.70 และ VM มี IP 172.16.100.3

    ขั้นตอน

    1. เปิด Terminal และติดตั้ง haproxy ด้วยคำสั่ง sudo apt install haproxy
    2. เข้าทำงานสิทธิ root ด้วยคำสั่ง sudo  su  –
      และไปในไดเรกทอรี cd  /etc/haproxy
      เก็บสำรองไฟล์ config ไว้ก่อน ด้วย cp  haproxy.cfg  haproxy.cfg.orig
      เข้าไปแก้ไขไฟล์ vi  haproxy.cfg
    3. เพิ่มบรรทัดเหล่านี้ ต่อท้ายบรรทัด errorfile 504 /etc/haproxy/errors/504.http

    frontend www-http

       bind *:80

       mode http

       acl is_cms path -i -m beg /cms/

       use_backend be_cms if is_cms

    backend be_cms

       option forwardfor

       server cms 172.16.100.3:80

    1. ทำการ restart haproxy และ ดู status
    2. ทดสอบการเข้าใช้งานจากเครื่องใน network เดียวกันกับเครื่อง Ubuntu Desktop ของเรา ไปที่ http://REAL-IP/cms/ 

    จบครับ

  • สร้าง VM OpenNebula miniONE on KVM ตอนที่ 2 add one-context

    เป็นขั้นตอนติดตั้ง one-context ต่อจากตอนที่แล้ว

    ขั้นตอน

    1. คำสั่ง sudo su – และ คำสั่ง 

    wget https://github.com/OpenNebula/addon-context-linux/releases/download/v5.12.0.2/one-context_5.12.0.2-1.deb

    1. ลบ cloud-init ด้วยคำสั่ง apt-get purge -y cloud-init
      ติดตั้งด้วยคำสั่ง dpkg -i one-context_*deb || apt-get install -fy
    2. เมื่อเสร็จ ให้ออกจาก web console และ คลิก Power off hard
    3. เอา CD-ROM ออก
    4. เมื่อถึงตรงนี้ VM นี้ก็พร้อมใช้เป็นต้นแบบในครั้งต่อไปได้ เราจึง Save as Template สมมติให้ชื่อว่า ubuntu-server-20.04
    5. ปรับแต่ VM Template เพื่อเติมสิ่งที่เกี่ยวกับ Context โดยคลิกปุ่ม Update
    6. คลิกที่ Context และ คลิกที่ตัวเลือกทุกอัน
    7. ใส่ Custom vars คือ SET_HOSTNAME, USERNAME และ PASSWORD
    8. ตอนนี้ VM Template นี้ ก็พร้อมใช้งาน เพื่อสร้าง VM ใหม่อันต่อไป โดยจะคลิกที่คำว่า Instantiate ก็ได้
    9. เลือกได้ว่าจะให้สร้างทีละกี่ instances ส่วนชื่อให้ละไว้ไม่ต้องใส่ก็ได้
    10. จะได้ชื่อจาก ชื่อ VM Template และต่อท้ายด้วย VMID
    11. คลิกที่ web console เพื่อเข้าไปใช้งาน VM
    12. จะได้หน้านี้
    13. ทดสอบ login ด้วย username ชื่อ papa ตามที่เราตั้งใน Context
    14. หน้า Dashboard หลังจากที่เราสร้างเสร็จ 1 ตัว
    15. หากเข้าหน้าเว็บ Sunstone ไม่ได้เพราะลืม password ของ username oneadmin ดูที่นี่
    16. ถึงตรงนี้ เราควรจะ ssh จาก ubuntu desktop เข้าไปยัง VM ได้ แต่หากเราไม่สามารถ ssh เข้าไปยัง VM เพราะว่า ssh host key ไม่มีเนื่องจากข้อผิดพลาดในขั้นตอนติดตั้ง Ubuntu server ให้สร้างด้วยคำสั่ง ssh-keygen -A ในเครื่อง VM แล้ววนกลับไปสร้าง VM Template ใหม่ 

    ในตอนต่อไปก็จะเป็นการติดตั้ง CMS Web Site เพื่อใช้ในการทดสอบการให้บริการ TCP port 80 ผ่าน HAPROXY ของเครื่อง ubuntu desktop

  • สร้าง VM OpenNebula miniONE on KVM

    หลังจากติดตั้ง server เสร็จแล้ว ตอนนี้ เรามาลองสร้าง VM กันสัก 1 ตัว หลักการคือ สร้าง image ที่เป็น disk เปล่า ๆ จากนั้นสร้าง VM Template ให้มาใช้ image นี้ และกำหนดค่า VM Template ให้เสร็จ แล้วสร้าง VM จาก VM Template นั้น

    ขั้นตอน

    1. สร้าง Image เปล่า สมมติตั้งชื่อว่า DISK8GB กำหนด Type คือ Generic storage datablock และเป็นแบบ Empty disk image กำหนดขนาด 8 GB
    2. สร้าง Image ที่เป็น CD-ROM สมมติตั้งชื่อว่า iso-ubuntu-focal กำหนด Type คือ Readonly CD-ROM โดย Upload จากฮาร์ดดิสก์ และเลือก ubuntu-20.04.1-live-server-amd64.iso
    3. ตอนนี้เตรียมของ 2 อย่าง พร้อมแล้ว
    4. สร้าง VM Template ชื่อ Install new ubuntu ใช้ Hypervisor ชนิด KVM กำหนด Memory 768 MB (เพิ่มได้) 
    5. กำหนดค่า Storage ให้ DISK0 ใช้ image ชื่อ DISK8GB
    6. กำหนดค่า Network ใช้อันที่มีอยู่แล้วคือ vnet (สร้างเองได้ภายหลัง)
    7. คลิก Create เพื่อสร้าง VM Template
    8. จะได้ดังรูป
    9. สร้าง VM จาก VM Template ที่สร้างในข้อที่แล้ว คลิกที่ Instances > VMs และคลิกปุ่ม +
    10. เลือก VM Template ชื่อ install new ubuntu
    11. จะได้ VM ชื่อ install new ubuntu-0
    12. แต่ตอนนี้ เรายังไม่ได้ใส่ CD-ROM เพื่อติดตั้ง ให้คลิก Power Off hard
    13. คลิกที่ VM 
    14. คลิกที่ Storage และ คลิก Attach disk
    15. คลิกเลือก image ที่เป็น CD-ROM
    16. ตอนนี้ เรามี disk และ CD-ROM แล้ว
    17. คลิก Config เพื่อเข้าไป Update configuration
    18. ตั้งค่า OS&CPU Boot order ให้ boot CD-ROM
    19. เปิด VM
    20. เข้าไปทำงานทางหน้า Web console 
    21. รอ
    22. ติดตั้ง Ubuntu Server ลงใน VM
      (ติดตั้ง Ubuntu Server 20.04 ใน VM ของ miniONE KVM)

    ตอนต่อไปเป็นขั้นตอนติดตั้ง one-context เพิ่มลงใน VM อ่านต่อเรื่องนี้ สร้าง VM OpenNebula miniONE on KVM ตอนที่ 2 add one-context

  • ติดตั้ง Ubuntu Server 20.04 ใน VM ของ miniONE KVM

    เป็นขั้นตอนสร้าง VM ที่เป็น Ubuntu Server 20.04 ใน VM ของ miniONE KVM

    ขั้นตอน

    1. เลือกใช้ภาษาอังกฤษในการติดตั้ง
    2. เลือก keyboard layout 
    3. ตั้งค่า IP Address แบบ static เลือก Interface name และ คลิก Edit IPv4
    4. เลือก Method แบบ Manual
    5. ใส่ค่า IP Address
    6. ไปต่อ คลิก Done
    7. ไปต่อ คลิก Done
    8. ตั้ง Mirror address มาที่ http://th.archive.ubuntu.com/ubuntu
    9. Storage configuration เลือก Use an entire disk 
    10. ไปต่อ คลิก Done
    11. Confirm destructive action เลือก Continue
    12. กำหนดค่า name, username และ password
    13. เลือก Install OpenSSH server และคลิก Done
    14. Featured Server Snaps ไม่เลือก ไปต่อ คลิก Done
    15. รอ
    16. เมื่อเสร็จ คลิก Reboot
    17. ในขั้นตอน downloading and installing security updates หากนานมาก จะไม่รอ ก็คลิก Cancel update and reboot
    18. เมื่อกลับเข้าใช้งาน ต้อง update เองสักรอบ เพื่อลงโปรแกรมอื่น ๆ ได้
    19. และอาจเป็นผลให้ติดตั้ง ssh host key ไม่สำเร็จ ตรวจสอบด้วยคำสั่ง ls -l /etc/ssh
    20. แก้ไขโดยสร้าง ssh host key ด้วยคำสั่ง ssh-keygen -A

    จบขั้นตอนสร้าง Ubuntu Server