ปิด XML-RPC WordPress ป้องกัน Brute Force Attack

ถ้าคุณดู 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 รูปแบบ:

สำคัญ: ก่อนปิด 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 ดังต่อไปนี้:

วิธีที่ 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 เพิ่ม

วิธีตรวจสอบว่าปิดสำเร็จหรือยัง

หลังใช้วิธีใดวิธีหนึ่งแล้ว ให้ทดสอบดังนี้:

  1. เปิด Browser แล้วไปที่ https://yoursite.com/xmlrpc.php
  2. ถ้าเห็น 403 Forbidden หรือ 404 Not Found — ปิดสำเร็จแล้ว
  3. ถ้าเห็นข้อความ 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 จากการถูกโจมตี มาตรการที่ควรทำเพิ่มเติม:

การปิด 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 →