ถ้าคุณดู Access Log ของ WordPress เว็บไซต์ จะพบว่ามีคนพยายาม Request ไปยัง /xmlrpc.php อยู่ตลอดเวลา — บางเว็บเจอหลายพันครั้งต่อวัน นี่คือการโจมตีแบบ Brute Force ที่ Hacker ใช้ช่องโหว่ XML-RPC ในการทดสอบรหัสผ่านจำนวนมากโดยไม่ผ่าน Login Page ปกติ
บทความนี้จะอธิบายว่า XML-RPC คืออะไร ทำไมถึงอันตราย และวิธีปิดที่ถูกต้องแต่ละแบบ
XML-RPC คืออะไร?
XML-RPC เป็น Protocol ที่ WordPress ใช้สำหรับ Remote Procedure Call — คือการส่งคำสั่งเข้า WordPress จากภายนอก ผ่านไฟล์ xmlrpc.php ที่อยู่ใน Root ของ WordPress เดิมทีถูกสร้างขึ้นเพื่อให้แอปภายนอก เช่น WordPress Mobile App หรือ Jetpack สามารถโพสต์บทความและจัดการเว็บได้
ปัจจุบัน WordPress มี REST API ที่ทันสมัยและปลอดภัยกว่ามาแล้ว ทำให้ XML-RPC กลายเป็น Legacy ที่ไม่จำเป็นสำหรับผู้ใช้ส่วนใหญ่
ทำไม XML-RPC ถึงอันตราย?
ช่องโหว่หลักของ XML-RPC มีอยู่ 3 รูปแบบ:
- Brute Force Attack แบบ Multicall — XML-RPC รองรับการเรียก Function หลายครั้งในการ Request เดียว (
system.multicall) ทำให้ Hacker ทดสอบรหัสผ่านได้หลายพันคู่ใน Request เดียว หลีกเลี่ยง Rate Limiting ได้ - DDoS Amplification — Hacker ใช้
pingback.pingใน XML-RPC เพื่อให้เว็บของคุณส่ง Request ไปยังเป้าหมาย DDoS แทน ทำให้ IP ของคุณถูกแบนและเว็บถูกใช้เป็น Bot - Content Injection — ถ้ารหัสผ่านถูก Crack ได้ Hacker สามารถโพสต์เนื้อหาหรือแก้ไขเว็บผ่าน XML-RPC โดยไม่ผ่านหน้า Admin ปกติ
สำคัญ: ก่อนปิด XML-RPC ตรวจสอบว่าคุณไม่ได้ใช้ Service เหล่านี้: Jetpack Plugin, WordPress Mobile App (iOS/Android), ManageWP, InfiniteWP หรือ Third-party Publishing Tool ใดๆ — ถ้าใช้อยู่ ให้ปิดแบบ Selective แทน
วิธีที่ 1 — ปิดด้วย .htaccess (แนะนำที่สุด)
วิธีนี้ Block การ Request ไปยัง xmlrpc.php ที่ระดับ Web Server โดยตรง ก่อนที่ PHP จะรัน ทำให้ประสิทธิภาพดีที่สุดและไม่กิน Resource ของ WordPress
เพิ่มโค้ดต่อไปนี้ใน .htaccess ของเว็บ (อยู่ใน Root ของ WordPress เดียวกับ wp-config.php):
# Block xmlrpc.php
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>
หรือใช้แบบนี้ก็ได้:
# Block xmlrpc.php (Alternative)
<IfModule mod_rewrite.c>
RewriteRule ^xmlrpc\.php$ - [F,L]
</IfModule>
หลังบันทึก .htaccess แล้ว ให้ทดสอบโดยเปิด yoursite.com/xmlrpc.php — ควรได้ 403 Forbidden
วิธีที่ 2 — ปิดผ่าน Plugin (ง่ายที่สุดสำหรับมือใหม่)
ถ้าไม่ต้องการแก้ไฟล์ .htaccess เอง สามารถใช้ Plugin ดังต่อไปนี้:
- Disable XML-RPC — Plugin เล็กๆ ที่ทำหน้าที่เดียวคือปิด XML-RPC ฟรีและไม่ต้องตั้งค่าอะไรเพิ่ม
- Wordfence Security — Security Suite ที่มีตัวเลือก Block XML-RPC อยู่ในการตั้งค่า เหมาะถ้าต้องการ Security Plugin ครบชุด
- All-in-One Security (AIOS) — มีตัวเลือก Complete Block XML-RPC ใน Features → WordPress Tweaks
วิธีที่ 3 — ปิดด้วย functions.php (เฉพาะส่วน)
วิธีนี้ปิดแบบ Selective โดยยังให้บาง Service ใช้งานได้ เหมาะสำหรับผู้ที่ใช้ Jetpack หรือ Service ที่ต้องการ XML-RPC บางส่วน
// ปิด XML-RPC Methods ส่วนใหญ่ แต่ยังเปิดสำหรับ Jetpack
add_filter('xmlrpc_enabled', '__return_false');
// ปิด Pingback ผ่าน XML-RPC (ป้องกัน DDoS Amplification)
add_filter('xmlrpc_methods', function($methods) {
unset($methods['pingback.ping']);
unset($methods['pingback.extensions.getPingbacks']);
return $methods;
});
เพิ่มโค้ดนี้ใน functions.php ของ Child Theme (แนะนำ) หรือใช้ Plugin Code Snippets เพื่อเพิ่มโค้ดโดยไม่แตะ Theme
แนะนำ: สำหรับเว็บส่วนใหญ่ที่ไม่ได้ใช้ Jetpack หรือ WordPress Mobile App ให้ใช้วิธีที่ 1 (.htaccess) — ปิดสมบูรณ์ ไม่กิน Resource ไม่ต้องติดตั้ง Plugin เพิ่ม
วิธีตรวจสอบว่าปิดสำเร็จหรือยัง
หลังใช้วิธีใดวิธีหนึ่งแล้ว ให้ทดสอบดังนี้:
- เปิด Browser แล้วไปที่
https://yoursite.com/xmlrpc.php - ถ้าเห็น 403 Forbidden หรือ 404 Not Found — ปิดสำเร็จแล้ว
- ถ้าเห็นข้อความ
XML-RPC server accepts POST requests only— ยังเปิดอยู่ ตรวจสอบขั้นตอนซ้ำ
นอกจากนี้ยังสามารถใช้ Tool ออนไลน์เช่น xmlrpc.eritreo.it เพื่อทดสอบว่า XML-RPC ตอบสนองหรือไม่
การตั้งค่า Rate Limiting บน Nginx และ Apache
แม้จะปิด XML-RPC แล้ว การตั้งค่า Rate Limiting ก็ยังมีความสำคัญเพื่อจำกัดจำนวน Request จาก IP เดียวในช่วงเวลาสั้นๆ ซึ่งช่วยป้องกัน Brute Force ที่อาจผ่านช่องทางอื่น
สำหรับ Apache (ใช้ mod_evasive)
# ติดตั้ง mod_evasive
sudo apt install libapache2-mod-evasive -y
# ตั้งค่าใน /etc/apache2/mods-enabled/evasive.conf
DOSHashTableSize 3097
DOSPageCount 5
DOSSiteCount 100
DOSPageInterval 2
DOSSiteInterval 1
DOSBlockingPeriod 60
สำหรับ Nginx
# เพิ่มใน nginx.conf ส่วน http block
limit_req_zone $binary_remote_addr zone=wp_login:10m rate=10r/m;
# ใน server block สำหรับ WordPress
location = /wp-login.php {
limit_req zone=wp_login burst=3 nodelay;
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
}
การตั้งค่านี้จำกัดไว้ที่ 10 Request ต่อนาทีต่อ IP และ Burst ได้ไม่เกิน 3 Request พร้อมกัน เพียงพอสำหรับการใช้งานจริงแต่บล็อก Bot ที่พยายามเข้าระบบจำนวนมากได้ดี
เปรียบเทียบวิธีปิด XML-RPC แต่ละแบบ
| วิธี | ระดับการป้องกัน | ใช้ Resource | ยืดหยุ่น | เหมาะกับใคร |
|---|---|---|---|---|
| .htaccess | สูงสุด | ไม่กิน PHP | ต่ำ (ปิดหมด) | ผู้ใช้ทั่วไปที่ไม่ใช้ Jetpack |
| Plugin | สูง | กิน PHP เล็กน้อย | ปานกลาง | มือใหม่ที่ไม่ถนัด server config |
| functions.php | ปานกลาง | กิน PHP ทุก Request | สูง (ปิดบางส่วนได้) | ผู้ที่ใช้ Jetpack หรือ WP App |
วิธีตรวจสอบ Access Log เพื่อหา xmlrpc.php Attacks
ก่อนปิด XML-RPC ลองตรวจดู Access Log เพื่อดูว่าถูกโจมตีอยู่หรือไม่ และรู้ว่ามี IP ใดที่น่าสงสัย
ใน DirectAdmin สามารถดู Raw Access Log ได้ผ่านหน้า Control Panel หรือผ่าน SSH ด้วยคำสั่ง:
# นับจำนวน Request ไปยัง xmlrpc.php ใน 24 ชั่วโมงล่าสุด
grep "xmlrpc.php" /var/log/apache2/access.log | wc -l
# ดู IP ที่ Request xmlrpc.php มากที่สุด
grep "xmlrpc.php" /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20
# ดู Log แบบ Real-time
tail -f /var/log/apache2/access.log | grep xmlrpc
ถ้าพบว่ามี Request ไปยัง xmlrpc.php มากกว่า 100 ครั้งต่อวัน หรือเห็น IP เดียวกัน Request ซ้ำๆ หลายร้อยครั้ง แสดงว่าถูกโจมตีอยู่และควรปิดทันที นอกจากนี้ยังสามารถ Block IP เหล่านั้นด้วย .htaccess หรือ Fail2ban เพิ่มเติมได้
มาตรการเพิ่มเติมเพื่อความปลอดภัย WordPress
การปิด XML-RPC เป็นเพียงหนึ่งในหลายวิธีที่ควรทำเพื่อป้องกัน WordPress จากการถูกโจมตี มาตรการที่ควรทำเพิ่มเติม:
- เปลี่ยน URL ของ Admin Login จาก
/wp-adminเป็น URL ที่ไม่คาดเดาได้ - เปิดใช้ Two-Factor Authentication (2FA) สำหรับบัญชี Admin
- จำกัดจำนวนครั้งการ Login ด้วย Plugin เช่น Login LockDown
- อัพเดต WordPress, Theme และ Plugin เป็นเวอร์ชันล่าสุดเสมอ
- ใช้ Security Plugin เช่น Wordfence หรือ Sucuri
การปิด XML-RPC บน WordPress Multisite
WordPress Multisite มีรูปแบบการจัดการ XML-RPC ที่แตกต่างจากไซต์ปกติเล็กน้อย เนื่องจาก xmlrpc.php อยู่ที่ Root ของ Network ทั้งหมด (ไม่ใช่แต่ละ Site) การปิดด้วย .htaccess ที่ Root จะมีผลกับทุก Sub-site พร้อมกัน ซึ่งในกรณีส่วนใหญ่เป็นสิ่งที่ต้องการ
อย่างไรก็ตามหากเป็น Multisite แบบ Subdirectory เช่น yoursite.com/blog1/ ให้ตรวจสอบว่า .htaccess Rule ที่เพิ่มอยู่นอก WordPress Rewrite Rules (ไม่ได้อยู่ระหว่าง # BEGIN WordPress และ # END WordPress) เพราะ WordPress อาจเขียนทับ Rules ของคุณตอนอัพเดตได้
# .htaccess สำหรับ WordPress Multisite — ใส่ก่อน # BEGIN WordPress
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>
# BEGIN WordPress
# ... WordPress Rewrite Rules ที่มีอยู่แล้ว ...
# END WordPress
สำหรับ Multisite แบบ Subdomain เช่น blog1.yoursite.com xmlrpc.php ยังอยู่ที่ Root เดิม ใช้วิธีเดียวกันและจะมีผลครอบคลุมทุก Subdomain อัตโนมัติ
การตั้งค่า Fail2ban เพื่อบล็อก IP ที่โจมตี xmlrpc.php
แม้จะปิด XML-RPC ด้วย .htaccess แล้ว Bot ยังคงส่ง Request มาทดสอบ สิ้นเปลือง Bandwidth และทำให้ Log เต็ม การตั้งค่า Fail2ban ให้ตรวจจับและ Block IP เหล่านั้นอัตโนมัติจะช่วยลดภาระได้อย่างมีประสิทธิภาพ
ติดตั้ง Fail2ban บน Ubuntu
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
สร้าง Filter สำหรับ xmlrpc.php
สร้างไฟล์ /etc/fail2ban/filter.d/wordpress-xmlrpc.conf
[Definition]
failregex = ^<HOST> .* "POST /xmlrpc.php.*" (200|403|404|500) .*$
ignoreregex =
สร้าง Jail สำหรับ WordPress xmlrpc
สร้างหรือแก้ไขไฟล์ /etc/fail2ban/jail.local
[wordpress-xmlrpc]
enabled = true
port = http,https
filter = wordpress-xmlrpc
logpath = /var/log/apache2/access.log
maxretry = 5
findtime = 60
bantime = 3600
การตั้งค่านี้จะ Block IP ที่ Request xmlrpc.php เกิน 5 ครั้งใน 60 วินาที โดยให้ Ban นาน 1 ชั่วโมง ปรับค่า bantime เป็น 86400 (1 วัน) หรือ -1 (ถาวร) สำหรับ Bot ที่รุนแรง
# Reload Fail2ban เพื่อใช้งาน config ใหม่
sudo fail2ban-client reload
# ตรวจสอบสถานะ Jail ที่เปิดใช้งาน
sudo fail2ban-client status wordpress-xmlrpc
# ดู IP ที่ถูก Ban อยู่
sudo fail2ban-client status wordpress-xmlrpc | grep "Banned IP"
เปรียบเทียบ XML-RPC กับ WordPress REST API
หลายคนสงสัยว่าถ้าปิด XML-RPC แล้วจะยังสามารถใช้ Remote API กับ WordPress ได้หรือไม่ คำตอบคือได้ เพราะ WordPress มี REST API ที่ทันสมัยกว่ามากอยู่แล้ว
| คุณสมบัติ | XML-RPC | WordPress REST API |
|---|---|---|
| เปิดตัว | WordPress 3.5 (2012) | WordPress 4.4 (2015) ครบใน 4.7 (2016) |
| Protocol | XML over HTTP POST | JSON over HTTP/HTTPS (GET, POST, PUT, DELETE) |
| Authentication | Username + Password ใน Request | Application Password, OAuth, JWT |
| ความปลอดภัย | ต่ำ (multicall, pingback abuse) | สูงกว่า (Nonce, Application Password) |
| ใช้งานปัจจุบัน | Legacy (ไม่ควรใช้) | มาตรฐานปัจจุบัน (ใช้ใน Gutenberg ด้วย) |
WordPress REST API เข้าถึงได้ที่ /wp-json/wp/v2/ และรองรับการ Create, Read, Update, Delete ข้อมูลทุกประเภทแบบ Granular ผ่าน Standard HTTP Methods ซึ่งปลอดภัยกว่า XML-RPC มากในทุกมิติ
Hosting WordPress พร้อม Security ระดับ Enterprise
AsiaGB Hosting มี Imunify360 ป้องกัน Malware และ DirectAdmin ที่จัดการ .htaccess ได้ง่าย เหมาะสำหรับ WordPress ที่ต้องการความปลอดภัยสูง ราคาเริ่มต้น 500 บาท/ปี
ดูแพ็กเกจ Hosting →