WP 安全:wp-admin 安全 | 更改登入網址·限制登入·XML-RPC

聯盟行銷揭露 Ver 3.1
聯盟行銷揭露 Ver 3.2(僅限行動版)

wp-admin 安全是擋下從 WordPress 管理後台與登入畫面進來的暴力破解攻擊的設定。查看執行多個 WordPress 網站的 Nginx + Apache 伺服器存取紀錄後發現,即使改了登入網址,從 xmlrpc.php 進來的自動請求仍然持續,所以連伺服器端的速率限制也一起套用。

1️⃣ wp-admin 與 wp-login.php 被攻擊的原因

WordPress 管理後台的網址人人都知道,這是弱點,但可以靠加強安全來彌補。所有 WordPress 網站都使用同樣的 /wp-admin/ 與 [wp-login.php],在登出狀態開啟 /wp-admin/ 會被導向 [wp-login.php] 登入畫面。

攻擊是以暴力破解的方式進來,在這個登入畫面反覆輸入使用者名稱與密碼。所以 wp-admin 安全要先擋住登入嘗試,而不是先藏網址。

WordPress 的兩個登入入口
用瀏覽器連線
/wp-admin/
登出狀態就導向登入畫面(302)
wp-login.php
登入畫面 · 輸入使用者名稱與密碼
App · 自動請求
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 處
沒有
沒有外掛時,可以在兩個地方試密碼:所有 WordPress 網站都一樣的 [wp-login.php],以及不經登入畫面就確認密碼的 [xmlrpc.php]。
更改登入網址後,[wp-login.php] 與 /wp-admin/ 會回傳 404,但 [xmlrpc.php] 仍然會回答使用者名稱與密碼對不對。
連 XML-RPC 也關掉的話,對 [xmlrpc.php] 的登入請求會以「XML-RPC 服務已停用」的回應結束,就無法在已知網址試密碼。

這個方法不費工,但忘記新網址就進不了管理後台,必須用 FTP 或檔案管理員把那個外掛的資料夾改名來停用。多人管理的網站,最好把網址記在同一個地方。

3️⃣ 限制登入嘗試與兩步驟驗證

就算改了登入網址,新網址一旦外流,猜密碼的嘗試還是會繼續。WordPress 核心沒有登入失敗次數限制,密碼輸錯幾次都會再打開同一個登入畫面。

🧭 限制登入嘗試與兩步驟驗證
說明圖解
⬜ 沒有外掛
🛡️ 安全外掛
🔑 同一 IP 的登入
第 1 次密碼錯誤
再次顯示登入畫面剩 3 次
第 2 次密碼錯誤
再次顯示登入畫面剩 2 次
第 3 次密碼錯誤
再次顯示登入畫面剩 1 次
第 4 次密碼錯誤
再次顯示登入畫面封鎖 20 分鐘
第 5 次封鎖中密碼錯誤登入 · XML-RPC 請求
再次顯示登入畫面xmlrpc.php 也是 403
輸入密碼密碼正確
輸入代碼畫面
Authentication Code驗證 App 的 6 位數 · 每 30 秒更換
管理後台
只查出密碼的攻擊者不知道代碼
停在代碼畫面
測試網站實測 · 同一 IP 連續請求
→
🤖 自動攻擊
能不能一直試密碼
無限制
第 4 次封鎖
停在代碼
沒有外掛時,同一 IP 輸錯密碼六次,每次都還是打開同一個登入畫面。
開啟登入嘗試限制後,每次輸錯都會顯示剩下的次數,第 4 次錯就讓那個 IP 20 分鐘內無法登入。封鎖期間,xmlrpc.php 的請求也會以 403 結束。
開啟兩步驟驗證後,就算密碼正確,也要輸入驗證 App 每 30 秒重新產生的 6 位數 [Authentication Code],才會打開管理後台。

登入嘗試限制外掛會把超過規定次數的 IP 封鎖一段時間;兩步驟驗證則是即使密碼正確,也要再輸入手機驗證 App 的代碼。開啟兩步驟驗證時,也要一併保存手機遺失時使用的備用代碼。

4️⃣ 關閉 xmlrpc.php

[xmlrpc.php] 是不經登入畫面就接收使用者名稱與密碼的第二個入口,用 [system.multicall] 方式還能在一次請求裡試多組密碼。

查看執行多個 WordPress 網站的 Nginx + Apache 伺服器存取紀錄,10 月 13 日 0 點到 9 點 50 分,進到 [xmlrpc.php] 的 POST 請求有 2,250 筆。請求來自 22 個 IP,User-Agent 則冒充 Jetpack 與 WordPress.com。

如果沒有使用 WordPress 行動 App 或 Jetpack,就在 Nginx 設定擋下 [xmlrpc.php] 請求,或使用安全外掛的關閉 XML-RPC 設定。

# server 區塊內 — 拒絕 xmlrpc.php 請求
location = /xmlrpc.php {
    deny all;
}

加入這個設定後,進到 [xmlrpc.php] 的 GET 與 POST 請求都不會到達 PHP,全部以 403 結束。安全外掛的關閉 XML-RPC 只拒絕需要登入的請求,檔案仍會回應,所以想連 PHP 執行都減少的話,在 Nginx 擋比較合適。

5️⃣ 在伺服器擋下:限制管理員存取 IP·速率限制

只從固定 IP 管理的話,最確實的方法是在 Nginx 只允許那個 IP 存取 [wp-login.php] 與 /wp-admin/。家裡或辦公室 IP 常變的環境就不適合。

整個 /wp-admin/ 擋掉好像就好,但訪客畫面的搜尋或購物車等功能常會向 [admin-ajax.php] 送出請求,所以這個檔案要開著。

# server 區塊內 — 放在處理 PHP 的 location 上方
location = /wp-login.php {
    allow 203.0.113.10;   # 管理用的固定 IP
    deny all;
    # 在下方原樣貼上處理 PHP 的 location 設定
}

從指定以外的 IP 開啟 [wp-login.php] 會出現 403,指定的 IP 則能打開登入畫面。location 裡要原樣放入網站的 PHP 處理設定(fastcgi_pass 等),登入畫面才會正常執行。

無法固定 IP 的話,也可以對未登入訪客的 PHP 請求設定速率限制;限制為每分鐘 30 次、讓自動請求無法佔用伺服器資源的過程,請參考 php-fpm max_children 警告 這篇文章。

# http 區塊 — 只按 IP 計算沒有登入 Cookie 的請求
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;

# 處理 PHP 的 location 內
limit_req zone=php_anon burst=60 nodelay;
limit_req_status 429;

未登入的單一 IP 連續送出 PHP 請求時,處理到第 61 次,之後回傳 429,有登入 Cookie 的請求不計算。如果頁面快取不經 PHP 就回應,一般訪客瀏覽頁面不會碰到這個限制。

ℹ️ 聯盟行銷說明
本站內容包含聯盟行銷連結。訪客透過這些連結購買商品或服務時,本站會從賣家獲得佣金。在這個過程中,購買者支付的金額(遇到活動折扣時金額會降低↓)並不會因此提高。刊登的價格、折扣與庫存資訊以撰寫當時為準,可能與實際情況不同,購買前請向賣家做最後確認。商品的挑選與評價依本站自訂的標準撰寫,是否支付佣金不會影響介紹順序或評價內容。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Prove your humanity: 6   +   4   =