ความปลอดภัย WP: ความปลอดภัย wp-admin | เปลี่ยนที่อยู่ล็อกอิน·จำกัดการล็อกอิน·XML-RPC

ประกาศแอฟฟิลิเอต Ver 3.1
ประกาศแอฟฟิลิเอต Ver 3.2 (เฉพาะมือถือ)

ความปลอดภัย wp-admin คือการตั้งค่าที่กันการเดารหัสผ่านที่เข้ามาทางหน้าผู้ดูแลระบบและหน้าล็อกอินของ WordPress จากบันทึกการเข้าถึงของเซิร์ฟเวอร์ Nginx + Apache ที่รันเว็บไซต์ WordPress หลายเว็บ คำขออัตโนมัติที่เข้ามาทาง xmlrpc.php ยังคงมาต่อแม้เปลี่ยนที่อยู่ล็อกอินแล้ว จึงต้องใช้การจำกัดอัตราที่ระดับเซิร์ฟเวอร์ร่วมด้วย

1️⃣ ทำไม wp-admin และ wp-login.php จึงถูกโจมตี

ที่อยู่หน้าผู้ดูแล WordPress เป็นที่รู้กันทั่วไปซึ่งถือเป็นจุดอ่อน แต่ก็ชดเชยได้ด้วยการเสริมความปลอดภัย เว็บไซต์ WordPress ทุกเว็บใช้ /wp-admin/ และ [wp-login.php] เหมือนกัน และถ้าเปิด /wp-admin/ ขณะไม่ได้ล็อกอิน จะถูกพาไปหน้าล็อกอิน [wp-login.php]

การโจมตีเข้ามาในรูปแบบการเดารหัสผ่าน คือใส่ชื่อผู้ใช้และรหัสผ่านซ้ำ ๆ ในหน้าล็อกอินนี้ ความปลอดภัย wp-admin จึงต้องเริ่มจากการกันการพยายามล็อกอิน ก่อนการซ่อนที่อยู่

ทางเข้าล็อกอินของ WordPress 2 ทาง
เข้าผ่านเบราว์เซอร์
/wp-admin/
ถ้าไม่ได้ล็อกอินจะถูกพาไปหน้าล็อกอิน (302)
wp-login.php
หน้าล็อกอิน · ใส่ชื่อผู้ใช้และรหัสผ่าน
แอป · คำขออัตโนมัติ
xmlrpc.php
ส่งชื่อผู้ใช้และรหัสผ่านด้วยคำขอ POST โดยไม่ผ่านหน้าล็อกอิน
ไม่ผ่านหน้าล็อกอิน
system.multicall ลองรหัสผ่านหลายตัวในคำขอเดียว · เปลี่ยนที่อยู่ล็อกอินแล้วที่อยู่นี้ก็ยังเหมือนเดิม
ตรวจชื่อผู้ใช้·รหัสผ่านแบบเดียวกัน
ทั้งสองทางตรวจบัญชีด้วยฟังก์ชันยืนยันตัวตนเดียวกันของ WordPress
การเดารหัสผ่านจะเข้ามาทางที่เปิดอยู่จากสองทางนี้ การเปลี่ยนที่อยู่ล็อกอินมีผลแค่ทางด้านบน xmlrpc.php จึงต้องปิดแยกหรือจำกัดจำนวนคำขอ

2️⃣ ผลและข้อจำกัดของการเปลี่ยนที่อยู่ล็อกอิน

ถ้าเปลี่ยนที่อยู่ล็อกอินด้วยปลั๊กอินความปลอดภัย [wp-login.php] เดิมจะตอบกลับข้อผิดพลาด 404 การโจมตีอัตโนมัติที่เคาะที่อยู่เดิมจึงมาไม่ถึงหน้าล็อกอิน ที่อยู่ใหม่ต้องแจ้งแยกให้ผู้ที่มีบัญชีผู้ดูแลระบบ

🧭 ทางเข้าล็อกอินของ WordPress
แผนภาพอธิบาย
⬜ ไม่มีปลั๊กอิน
🛡️ Hide My WP
🚪 ทางเข้าล็อกอิน
/wp-login.php · /wp-admin/ที่อยู่เดียวกันในทุก WordPress
หน้าล็อกอิน404
/newloginที่อยู่ที่เปลี่ยนแล้ว · รู้แค่ผู้ดูแล
หน้าล็อกอิน
POST /xmlrpc.phpตรวจรหัสผ่านโดยไม่มีหน้าล็อกอิน
ตอบการตรวจรหัสผ่านปิดใช้ 405
วัดจริงบนเว็บไซต์ทดสอบ · คำขอขณะไม่ได้ล็อกอิน
→
🤖 การโจมตีอัตโนมัติ
ทางเข้าที่ลองรหัสผ่านได้ด้วยที่อยู่ที่รู้กันทั่วไป
2 แห่ง
1 แห่ง
ไม่มี
ถ้าไม่มีปลั๊กอิน จะลองรหัสผ่านได้ 2 ที่ คือ [wp-login.php] ที่เหมือนกันทุกเว็บไซต์ WordPress และ [xmlrpc.php] ที่ตรวจรหัสผ่านโดยไม่มีหน้าล็อกอิน
ถ้าเปลี่ยนที่อยู่ล็อกอิน [wp-login.php] และ /wp-admin/ จะตอบ 404 แต่ [xmlrpc.php] ยังตอบว่าชื่อผู้ใช้และรหัสผ่านถูกหรือไม่ตามเดิม
ถ้าปิด XML-RPC ด้วย คำขอล็อกอินไปที่ [xmlrpc.php] จะจบด้วยคำตอบว่าบริการ XML-RPC ถูกปิดอยู่ จึงลองรหัสผ่านด้วยที่อยู่ที่รู้กันทั่วไปไม่ได้

วิธีนี้ไม่ยุ่งยาก แต่ถ้าลืมที่อยู่ใหม่ จะเข้าหน้าผู้ดูแลไม่ได้ ต้องเปลี่ยนชื่อโฟลเดอร์ของปลั๊กอินนั้นผ่าน FTP หรือตัวจัดการไฟล์เพื่อปิดใช้งาน ถ้าเป็นเว็บไซต์ที่มีหลายคนดูแล ควรจดที่อยู่ไว้ในที่เดียว

3️⃣ จำกัดการพยายามล็อกอินและการยืนยันตัวตน 2 ขั้นตอน

แม้เปลี่ยนที่อยู่ล็อกอินแล้ว ถ้าที่อยู่ใหม่รั่วออกไป การลองเดารหัสผ่านก็ยังดำเนินต่อ แกนหลักของ WordPress ไม่จำกัดจำนวนครั้งที่ล็อกอินผิด ใส่รหัสผ่านผิดกี่ครั้งก็เปิดหน้าล็อกอินเดิมขึ้นมาอีก

🧭 จำกัดการพยายามล็อกอินและการยืนยันตัวตน 2 ขั้นตอน
แผนภาพอธิบาย
⬜ ไม่มีปลั๊กอิน
🛡️ ปลั๊กอินความปลอดภัย
🔑 ล็อกอินจาก IP เดียวกัน
ครั้งที่ 1รหัสผ่านผิด
หน้าล็อกอินอีกครั้งเหลือ 3 ครั้ง
ครั้งที่ 2รหัสผ่านผิด
หน้าล็อกอินอีกครั้งเหลือ 2 ครั้ง
ครั้งที่ 3รหัสผ่านผิด
หน้าล็อกอินอีกครั้งเหลือ 1 ครั้ง
ครั้งที่ 4รหัสผ่านผิด
หน้าล็อกอินอีกครั้งบล็อก 20 นาที
ครั้งที่ 5กำลังถูกบล็อกรหัสผ่านผิดคำขอล็อกอิน · XML-RPC
หน้าล็อกอินอีกครั้งxmlrpc.php ก็ 403
ใส่รหัสผ่านรหัสผ่านถูก
หน้าใส่รหัส
Authentication Code6 หลักจากแอปยืนยันตัวตน · เปลี่ยนทุก 30 วินาที
หน้าผู้ดูแลระบบ
ผู้โจมตีที่รู้แค่รหัสผ่านไม่รู้รหัส
หยุดที่หน้ารหัส
วัดจริงบนเว็บไซต์ทดสอบ · คำขอต่อเนื่องจาก IP เดียวกัน
→
🤖 การโจมตีอัตโนมัติ
ลองรหัสผ่านต่อไปได้ไหม
ไม่จำกัด
บล็อกที่ครั้งที่ 4
หยุดที่รหัส
ถ้าไม่มีปลั๊กอิน ต่อให้ใส่รหัสผ่านผิด 6 ครั้งจาก IP เดียวกัน หน้าล็อกอินเดิมก็เปิดขึ้นทุกครั้ง
ถ้าเปิดการจำกัดการพยายามล็อกอิน ทุกครั้งที่ผิดจะแสดงจำนวนครั้งที่เหลือ และถ้าผิดครั้งที่ 4 IP นั้นจะล็อกอินไม่ได้ 20 นาที ระหว่างถูกบล็อก คำขอ xmlrpc.php ก็จบด้วย 403
ถ้าเปิดการยืนยันตัวตน 2 ขั้นตอน แม้รหัสผ่านถูก ก็ต้องใส่ [Authentication Code] 6 หลักที่แอปยืนยันตัวตนสร้างใหม่ทุก 30 วินาที หน้าผู้ดูแลระบบจึงจะเปิด

ปลั๊กอินจำกัดการพยายามล็อกอินจะบล็อก IP ที่เกินจำนวนครั้งที่กำหนดไว้ช่วงหนึ่ง ส่วนการยืนยันตัวตน 2 ขั้นตอนจะขอรหัสจากแอปยืนยันตัวตนในโทรศัพท์อีกครั้งแม้รหัสผ่านถูก เวลาเปิดการยืนยันตัวตน 2 ขั้นตอน ให้เก็บรหัสสำรองไว้ใช้ตอนโทรศัพท์หายด้วย

4️⃣ ปิด xmlrpc.php

[xmlrpc.php] เป็นทางเข้าที่สองที่รับชื่อผู้ใช้และรหัสผ่านโดยไม่ผ่านหน้าล็อกอิน และถ้าใช้วิธี [system.multicall] ก็ลองรหัสผ่านหลายตัวได้ในคำขอเดียว

บันทึกการเข้าถึงของเซิร์ฟเวอร์ Nginx + Apache ที่รันเว็บไซต์ WordPress หลายเว็บ มีคำขอ POST ไปที่ [xmlrpc.php] 2,250 ครั้งตั้งแต่ 00:00 ถึง 09:50 น. ของวันที่ 13 ตุลาคม คำขอมาจาก 22 IP และ User-Agent ปลอมตัวเป็น Jetpack และ WordPress.com

ถ้าไม่ได้ใช้แอปมือถือ WordPress หรือ Jetpack ให้บล็อกคำขอ [xmlrpc.php] ในการตั้งค่า Nginx หรือใช้การตั้งค่าปิด XML-RPC ของปลั๊กอินความปลอดภัย

# ภายในบล็อก server — ปฏิเสธคำขอ xmlrpc.php
location = /xmlrpc.php {
    deny all;
}

เมื่อใส่การตั้งค่านี้ คำขอ GET และ POST ที่เข้ามาทาง [xmlrpc.php] จะจบด้วย 403 ทั้งหมดโดยไม่ไปถึง PHP การปิด XML-RPC ของปลั๊กอินความปลอดภัยปฏิเสธเฉพาะคำขอที่ต้องล็อกอิน ส่วนไฟล์ยังตอบกลับอยู่ ถ้าอยากลดการรัน PHP ไปด้วย บล็อกที่ Nginx จะเหมาะกว่า

5️⃣ บล็อกที่เซิร์ฟเวอร์: จำกัด IP ที่เข้าหน้าผู้ดูแล·จำกัดอัตรา

ถ้าดูแลจาก IP คงที่เท่านั้น วิธีที่แน่นอนที่สุดคืออนุญาต [wp-login.php] และ /wp-admin/ เฉพาะ IP นั้นใน Nginx แต่ไม่เหมาะกับสภาพแวดล้อมที่ IP บ้านหรือที่ทำงานเปลี่ยนบ่อย

ดูเหมือนบล็อก /wp-admin/ ทั้งหมดก็พอ แต่ฟีเจอร์ฝั่งผู้เข้าชม เช่น การค้นหาหรือตะกร้าสินค้า มักส่งคำขอไปที่ [admin-ajax.php] จึงต้องเปิดไฟล์นั้นไว้

# ภายในบล็อก server — อยู่เหนือ location ที่ประมวลผล PHP
location = /wp-login.php {
    allow 203.0.113.10;   # IP คงที่ที่ใช้ดูแล
    deny all;
    # คัดลอกการตั้งค่าของ location ที่ประมวลผล PHP มาไว้ใต้บรรทัดนี้
}

ถ้าเปิด [wp-login.php] จาก IP อื่นที่ไม่ได้กำหนด จะได้ 403 ส่วน IP ที่กำหนดจะเปิดหน้าล็อกอินได้ ภายใน location ต้องคัดลอกการตั้งค่าประมวลผล PHP ของเว็บไซต์ (fastcgi_pass ฯลฯ) มาใส่ตามเดิม หน้าล็อกอินจึงจะทำงานปกติ

ถ้ากำหนด IP ตายตัวไม่ได้ ก็มีวิธีจำกัดอัตราคำขอ PHP ของผู้เข้าชมที่ไม่ได้ล็อกอิน ขั้นตอนการจำกัดไว้ที่ 30 ครั้งต่อนาทีเพื่อไม่ให้คำขออัตโนมัติแย่งทรัพยากรเซิร์ฟเวอร์อยู่ใน คำเตือน php-fpm max_children (บทความแยก)

# บล็อก http — นับตาม IP เฉพาะคำขอที่ไม่มีคุกกี้ล็อกอิน
map $http_cookie $php_anon_key {
    default                 $binary_remote_addr;
    "~*wordpress_logged_in" "";
}
limit_req_zone $php_anon_key zone=php_anon:10m rate=30r/m;

# ภายใน location ที่ประมวลผล PHP
limit_req zone=php_anon burst=60 nodelay;
limit_req_status 429;

ถ้า IP หนึ่งที่ไม่ได้ล็อกอินส่งคำขอ PHP ต่อเนื่อง จะประมวลผลได้ถึงครั้งที่ 61 หลังจากนั้นจะตอบ 429 และไม่นับคำขอที่มีคุกกี้ล็อกอิน ถ้าแคชหน้าตอบกลับโดยไม่ผ่าน PHP การเปิดหน้าของผู้เข้าชมทั่วไปก็ไม่ติดข้อจำกัดนี้

🔗 เนื้อหาแนะนำ
เสริมความปลอดภัย ช่องโหว่ความปลอดภัยของ wp-config.php และการเสริมความปลอดภัย พร้อมกรณีจริงที่สำเนา swap (.swp) เปิดได้ตรง ๆ ผ่านที่อยู่เว็บ บทความนี้ครอบคลุม 6 รายการตรวจความปลอดภัยของ wp-config.php ไล่จากบนลงล่าง อ่านบทความ → WordPress Box

ℹ️ ประกาศเรื่องลิงก์แอฟฟิลิเอต
เนื้อหาของเว็บไซต์นี้มีลิงก์แอฟฟิลิเอต หากผู้เข้าชมซื้อสินค้าหรือบริการผ่านลิงก์เหล่านี้ เว็บไซต์นี้จะได้รับค่าคอมมิชชันจากผู้ขาย ในกระบวนการนี้ ราคาที่ผู้ซื้อจ่าย(ราคาจะลดลงเมื่อมีโปรโมชัน↓)จะไม่สูงขึ้นแต่อย่างใด ราคา ส่วนลด และข้อมูลสต็อกที่แสดงเป็นข้อมูล ณ เวลาที่เขียนและอาจต่างจากความเป็นจริง โปรดตรวจสอบกับผู้ขายอีกครั้งก่อนซื้อ การเลือกและการประเมินสินค้าเขียนตามเกณฑ์ของเราเอง และการได้รับค่าคอมมิชชันหรือไม่ไม่มีผลต่อลำดับการแนะนำหรือเนื้อหาการประเมิน

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *

Prove your humanity: 3   +   1   =