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

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 安全要先擋住登入嘗試,而不是先藏網址。
2️⃣ 更改登入網址的效果與限制
用安全外掛更改登入網址後,預設的 [wp-login.php] 會回傳 404 錯誤,一直敲預設網址的自動攻擊就到不了登入畫面。新的網址要另外告訴擁有管理員帳號的人。
這個方法不費工,但忘記新網址就進不了管理後台,必須用 FTP 或檔案管理員把那個外掛的資料夾改名來停用。多人管理的網站,最好把網址記在同一個地方。
3️⃣ 限制登入嘗試與兩步驟驗證
就算改了登入網址,新網址一旦外流,猜密碼的嘗試還是會繼續。WordPress 核心沒有登入失敗次數限制,密碼輸錯幾次都會再打開同一個登入畫面。
登入嘗試限制外掛會把超過規定次數的 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 就回應,一般訪客瀏覽頁面不會碰到這個限制。
ℹ️ 聯盟行銷說明
本站內容包含聯盟行銷連結。訪客透過這些連結購買商品或服務時,本站會從賣家獲得佣金。在這個過程中,購買者支付的金額(遇到活動折扣時金額會降低↓)並不會因此提高。刊登的價格、折扣與庫存資訊以撰寫當時為準,可能與實際情況不同,購買前請向賣家做最後確認。商品的挑選與評價依本站自訂的標準撰寫,是否支付佣金不會影響介紹順序或評價內容。