IPradr PHP Guard 1.0 — Linux / Python 3.9 ขึ้นไป
วันที่จัดทำ: 23 ตุลาคม 2569

ขอบเขต
เครื่องมือตรวจสอบภายในเครื่องและตรวจความเปลี่ยนแปลงไฟล์แบบ HIDS เบื้องต้น
ใช้เฉพาะ Python standard library ไม่ต้อง pip install และไม่สแกนเครือข่าย
รองรับข้อมูลแพ็กเกจ Debian/Ubuntu และระบบ RPM
ไม่ใช่เครื่องมือยืนยันว่าโจมตีได้ ไม่ใช่ antivirus และไม่รับรองว่าเครื่องสะอาด
Hardening 4 ค่า INI เป็นการลดข้อมูลเปิดเผยและเปิด error logging ไม่ใช่แพตช์ PHP2Shell
ต้องติดตั้งแพตช์ PHP จากผู้ผลิตแยกต่างหาก

ติดตั้ง
นำโฟลเดอร์นี้ไปยัง Linux แล้วรัน:
  sudo install -d -m 0755 /opt/phpguard
  sudo install -m 0755 phpguard.py /opt/phpguard/phpguard.py
  sudo install -d -m 0700 /var/lib/phpguard
  python3 /opt/phpguard/phpguard.py --help

1. ตรวจระบบ
  sudo python3 /opt/phpguard/phpguard.py audit --output /var/lib/phpguard/audit-before.json
ตรวจ runtimes, รายชื่อ INI, แพ็กเกจ และบริการจาก systemd
ตรวจพบเฉพาะ PATH และตำแหน่งมาตรฐาน ไม่เข้าตรวจ container อัตโนมัติ
แผงโฮสติ้ง ตำแหน่ง PHP เฉพาะ และแต่ละ container ต้องตรวจแยก
CLI ไม่ยืนยัน runtime ของเว็บ ต้องตรวจการตั้งค่า virtual host และ FPM pool จริง
รายงานอาจมีรายละเอียดภายใน ให้เก็บเป็นข้อมูลผู้ดูแล ไม่เผยแพร่สาธารณะ

2. ประเมินและวางแผน
กฎเวอร์ชันอิง CVE-2026-109618 / CVE-2026-109619 ณ วันที่จัดทำ
เกณฑ์ upstream: 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12
หมายเลขถึงเกณฑ์ไม่ใช่การรับรองปลอดภัยจากทุก CVE
หมายเลขต่ำกว่าเกณฑ์อาจมี vendor backport ต้องตรวจประกาศผู้ผลิตก่อนสรุป
สาขานอกกฎจะแสดงว่าต้องทบทวนเอง ไม่เดาว่าแก้แล้วหรือมีช่องโหว่
สคริปต์ไม่ดึงกฎใหม่จากอินเทอร์เน็ตโดยอัตโนมัติ

ตัวอย่าง สร้างแผนสำหรับไฟล์ที่ผู้ดูแลยืนยันว่าเว็บใช้งาน:
  sudo python3 /opt/phpguard/phpguard.py plan --ini /etc/php/8.3/fpm/php.ini --output /var/lib/phpguard/plan.json
แทนพาธตัวอย่างด้วยไฟล์จริง อ่าน plan.json ก่อนทำขั้นตอน apply
ค่าที่แก้: expose_php=Off, display_errors=Off, display_startup_errors=Off, log_errors=On
ตรวจว่า log มีปลายทางที่เขียนได้และมีการหมุนเวียนไฟล์
ไม่แก้ upload limit, disable_functions, permission หรือ web server rules แบบเหมารวม
ไม่รองรับ INI ที่มี [HOST=...] หรือ [PATH=...] ในโหมดแก้อัตโนมัติ
ไฟล์ต้องเป็น UTF-8, regular file และไม่มี symlink ในเส้นทาง
ค่าจาก conf.d, pool, .user.ini หรือแอปอาจ override INI นี้ได้
v1.0.1: plan/apply ตรวจไฟล์ใน conf.d (และ PHP_INI_SCAN_DIR) ที่ตั้งค่าเดียวกันทับไว้ แสดงใน "overrides" และ apply จะรายงาน configuration_written_but_overridden ให้แก้ไฟล์เหล่านั้นด้วย

3. สำรองและสร้าง baseline
สำรองแอปและฐานข้อมูลด้วยระบบสำรองที่ใช้งานอยู่ และทดสอบกู้คืนก่อนอัปเดต PHP
สร้าง baseline จากระบบที่ตรวจแล้วว่าเชื่อถือได้ เก็บสำเนานอกเครื่องด้วย
ตัวอย่างควรปรับให้ชี้ไปยัง code/config ที่ปกติไม่เปลี่ยน:
  sudo python3 /opt/phpguard/phpguard.py baseline --paths /var/www/html /etc/php /etc/nginx --output /var/lib/phpguard/baseline.json
ใส่เฉพาะพาธที่มีอยู่จริง หากมีข้อผิดพลาดการอ่านจะไม่สร้าง baseline
เก็บ SHA-256, owner, group, permission และ symlink target โดยไม่ตาม symlink
ห้ามเก็บ baseline/output ภายในโฟลเดอร์ที่เฝ้าระวัง
โฟลเดอร์ cache/session/upload ที่เปลี่ยนตามปกติจะเกิดแจ้งเตือน ควรเลือกรากแยกให้เหมาะสม
ไม่ทับ baseline เดิม ให้ใช้ชื่อใหม่หลังตรวจยอมรับการเปลี่ยนแปลง

4. ใช้แผน hardening
ทำในช่วงบำรุงรักษา หลีกเลี่ยงการแก้ configuration พร้อมกับเครื่องมืออื่น
  sudo python3 /opt/phpguard/phpguard.py apply --plan /var/lib/phpguard/plan.json --backup-dir /var/lib/phpguard/backups --confirm
สำรองไฟล์และ receipt ก่อนเขียน ตรวจ hash ป้องกันใช้แผนเก่า
เก็บ inode เดิมเพื่อรักษา ACL/security labels ใช้ advisory lock
การเขียนไม่ได้ atomic สำหรับโปรแกรมอื่นที่ไม่เคารพ lock จึงต้องใช้ช่วงบำรุงรักษา
ผลลัพธ์บอกพาธ receipt.json สำหรับย้อนกลับ
ไม่ restart บริการและไม่แก้แพ็กเกจ ให้ตรวจ config ตามคู่มือระบบก่อน restart บริการ PHP ที่ถูกต้อง
หาก INI สำรองมี secret ให้เก็บ backup-dir เป็นโฟลเดอร์ root-only

ย้อนกลับ configuration:
  sudo python3 /opt/phpguard/phpguard.py rollback --receipt /var/lib/phpguard/backups/ชื่อรายการ/receipt.json --confirm
จะปฏิเสธหากไฟล์ปัจจุบันถูกแก้หลัง apply หรือสำเนาสำรองไม่ตรง hash
หลังย้อนกลับต้องตรวจ configuration และ restart บริการที่เกี่ยวข้องตามแผน
rollback นี้ไม่ใช่การ downgrade แพ็กเกจ PHP

5. อัปเดตแพตช์และตรวจผล
ติดตั้ง PHP รุ่นแก้ไขจาก repository หรือผู้จำหน่ายที่ระบบรองรับในช่วงบำรุงรักษา
ทดสอบบน staging ก่อน โดยเฉพาะ extensions, login, upload, session และงานตามเวลา
เริ่ม worker ใหม่ให้ครบทุก pool/replica ตามวิธีของระบบ
  sudo python3 /opt/phpguard/phpguard.py verify --output /var/lib/phpguard/audit-after.json
verify (v1.0.1) อ่านค่าที่ PHP ใช้งานจริงจาก `-i` ของทุก php/php-fpm ที่พบ เทียบกับ 4 ค่าที่ต้องการ
exit code: 0 = ทุก runtime ตรง (all_runtimes_hardened), 1 = ยังมี runtime ที่ไม่ตรง ดู mismatches ในไฟล์ผล
ยังไม่ครอบคลุม php_admin_value ใน FPM pool, .user.ini และค่าต่อ directory ซึ่งอาจต่างกันเมื่อเรียกผ่านเว็บ
ตรวจเวอร์ชันและ 4 ค่าจาก runtime เว็บผ่านช่องทางภายใน ไม่เปิด phpinfo สู่สาธารณะ
ตรวจ HTTP/HTTPS, ฟังก์ชันธุรกิจ และ error log ด้วยผู้ดูแล

6. ตรวจความเปลี่ยนแปลงและเฝ้าระวัง
  sudo python3 /opt/phpguard/phpguard.py check --baseline /var/lib/phpguard/baseline.json --output /var/lib/phpguard/check.json
exit code: 0 ไม่พบความเปลี่ยนแปลง, 1 พบเปลี่ยนแปลง, 2 ผิดพลาด/ข้อมูลไม่ครบ
ไม่พบความเปลี่ยนแปลงหมายถึงตรง baseline เท่านั้น ไม่ได้ยืนยันว่าไม่ถูกบุกรุก
  sudo python3 /opt/phpguard/phpguard.py watch --baseline /var/lib/phpguard/baseline.json --output /var/lib/phpguard/latest-check.json --interval 300
สแกนทุก 300 วินาทีหลังจบรอบก่อน เก็บผลล่าสุด และพิมพ์เหตุการณ์เมื่อชุดผลเปลี่ยน
ไม่ติดตาม process, network หรือ log แบบ real-time และอาจพลาดไฟล์ที่สร้างแล้วลบระหว่างรอบ
ไม่มีการลบ/quarantine ไฟล์โดยอัตโนมัติ ถ้าพบสิ่งผิดปกติให้เก็บหลักฐานก่อน
สำหรับ process monitoring ต่อเนื่อง ต้องต่อ Linux Audit/eBPF หรือ HIDS ที่มีอยู่เพิ่ม
การเปลี่ยนแปลงไฟล์เพียงอย่างเดียวไม่ใช่หลักฐานยืนยัน web shell

รันต่อเนื่องด้วย systemd (หลังสร้าง baseline แล้ว)
  sudo install -m 0644 phpguard-watch.service /etc/systemd/system/phpguard-watch.service
  sudo systemctl daemon-reload
  sudo systemctl enable --now phpguard-watch.service
  sudo systemctl status phpguard-watch.service
  sudo journalctl -u phpguard-watch.service -n 50
หยุด: sudo systemctl disable --now phpguard-watch.service
unit นี้ตั้ง ProtectHome=read-only (v1.0.1) จึงอ่าน /home ได้แต่เขียนไม่ได้ รองรับเว็บใต้ /home เช่น cPanel/DirectAdmin หรือ ~/public_html
ตั้ง journal retention ตามนโยบาย; latest-check.json ถูกแทนที่ทุกครั้ง ประวัติอยู่ใน journal
root ที่ถูกยึดอาจแก้ทั้ง baseline และเครื่องมือ ควรส่ง log/สำเนาฐานออกนอกเครื่อง

แหล่งอ้างอิงกฎ:
https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w
https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp
https://www.php.net/supported-versions.php

สถานะการทดสอบ
มี unit tests สำหรับ version boundaries, baseline changes และ hardening plan
ต้องทดสอบ integration บน Linux staging ก่อนใช้ production
