本文约 4,663 字,预计阅读 12 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:日志里几千条 xmlrpc.php 请求
看服务器访问日志,经常能发现大量这样的请求:
185.220.101.x - - [10/Oct/2026:03:12:44] "POST /xmlrpc.php HTTP/1.1" 200
185.220.101.x - - [10/Oct/2026:03:12:45] "POST /xmlrpc.php HTTP/1.1" 200
... 连续几千条
这些几乎全是攻击:system.multicall 暴力破解(一个请求里塞几百次登录尝试,绕过登录失败限速)和 pingback 反射 DDoS(把你的站点当放大器去打别人)。
但 XML-RPC 同时也是 WordPress 官方手机 App、桌面客户端、部分第三方发布工具依赖的协议。一刀切删掉,可能把正常功能一起干掉。所以先要弄清楚它在你站上有没有被用到。
原理分析:XML-RPC 是什么,还剩什么用
XML-RPC 是老牌的远程调用协议(XML over HTTP POST),比 REST 早十几年。WordPress 早期就内置 xmlrpc.php,用于:
- 远程发布:博客客户端(Windows Live Writer、MarsEdit、WordPress 官方 App);
- Pingback / Trackback:站与站之间的引用通知;
- Jetpack 的部分功能(老功能仍有依赖);
- 部分插件的跨站通信。
请求体长这样:
<?xml version="1.0"?>
<methodCall>
<methodName>wp.getPosts</methodName>
<params>
<param><value><i4>1</i4></value></param>
<param><value><string>username</string></value></param>
<param><value><string>password</string></value></param>
</params>
</methodCall>
三类真实攻击:
攻击 1:system.multicall 爆破
XML-RPC 有个方法叫 system.multicall,允许在一个 HTTP 请求里调用多次方法。攻击者把它和 wp.getCategories(需要账号密码)组合,一个请求尝试几百组密码,完全绕过了登录页的失败次数限制。这是 WordPress 站点被撞库成功率最高的方式。
攻击 2:pingback 反射放大
pingback.ping 方法允许 A 站告诉 B 站”我引用了你”,B 站会去 A 站抓页面验证。攻击者伪造大量 pingback 请求,源 IP 填受害者,于是成百上千个 WordPress 站点同时去请求受害者——分布式放大 DDoS。
攻击 3:用户信息枚举
wp.getUsersBlogs 等方法在旧版本可以探测用户名。
怎么判断你的站有没有在用 XML-RPC
看访问日志里有没有合法的 xmlrpc 请求:
grep "xmlrpc.php" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head
如果全是可疑 IP(境外、短时间大量),说明没人用,可以关。如果看到自己公司的固定 IP 或 App 的请求,就要留。
保姆级实操
方案一:彻底关闭(最常用、推荐)
代码方式(子主题 functions.php):
// 完全禁用 XML-RPC
add_filter( 'xmlrpc_enabled', '__return_false' );
这个过滤器会让 xmlrpc.php 返回 405 并提示 “XML-RPC services are disabled on this site.”。
Nginx 层直接挡(性能最好,不进 PHP):
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
Apache(.htaccess):
<Files xmlrpc.php>
Require all denied
</Files>
宝塔面板:网站 → 设置 → 配置文件,在 server 块里加上面的 Nginx 规则。
方案二:只关危险方法,保留发布功能
如果确实用 App 或第三方工具发布,只禁用 system.multicall 和 pingback:
// 禁用 pingback
add_filter( 'xmlrpc_methods', function( $methods ) {
unset( $methods['pingback.ping'] );
unset( $methods['pingback.extensions.getPingbacks'] );
unset( $methods['system.multicall'] );
return $methods;
});
方案三:只关 pingback(保留远程发布)
后台路径:设置 → 讨论 → 取消”允许其他博客发送链接通知(pingback)”。或者:
add_filter( 'xmlrpc_methods', function( $methods ) {
unset( $methods['pingback.ping'] );
return $methods;
});
// 同时去掉 HTTP 头里的 X-Pingback
add_filter( 'wp_headers', function( $headers ) {
unset( $headers['X-Pingback'] );
return $headers;
});
方案四:限速(CDN / Nginx)
Cloudflare WAF 建规则:
(http.request.uri.path eq "/xmlrpc.php") → 托管挑战 / 阻断
或者用速率限制规则:同一 IP 每分钟超过 5 次 POST /xmlrpc.php → 阻断 1 小时。
Nginx 限速:
limit_req_zone $binary_remote_addr zone=xrpc:10m rate=6r/m;
location = /xmlrpc.php {
limit_req zone=xrpc burst=2 nodelay;
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
方案五:IP 白名单
只有自己公司 IP 能用:
location = /xmlrpc.php {
allow 203.0.113.10;
deny all;
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
验证是否关闭成功
curl -X POST https://example.com/xmlrpc.php \
-H "Content-Type: text/xml" \
-d '<methodCall><methodName>system.listMethods</methodName></methodCall>'
- 彻底关闭:返回 403(Nginx 挡)或 405 + “XML-RPC services are disabled”
- 只关部分方法:返回的方法列表里没有
pingback.ping/system.multicall
顺手清理已有的 pingback 垃圾
后台文章里的 pingback 评论会堆积:
SELECT COUNT(*) FROM wp_comments WHERE comment_type = 'pingback';
DELETE FROM wp_comments WHERE comment_type = 'pingback';
DELETE FROM wp_comments WHERE comment_type = 'trackback';
常见踩坑与失败案例
- 案例一:某站长直接把
xmlrpc.php文件删了。WordPress 升级后文件又被写回来,之前的防护失效,而他不知道。应该用配置规则挡,而不是删文件。 - 案例二:关了 XML-RPC 之后,客户的 WordPress 手机 App 发不了文章,投诉到建站方。正确做法是先查日志确认有没有合法请求,有就走”方案二/三”只关危险方法。
- Jetpack 报错:Jetpack 的部分功能依赖 xmlrpc,关闭后后台提示连接失败。如果不用 Jetpack 无所谓,用了就只关 pingback 和 multicall。
- 关了还被打:如果是在 WordPress 层(
xmlrpc_enabled)关的,请求仍会进 PHP,消耗资源。高并发攻击时要在 Nginx 层挡,或者在 CDN 层挡(根本不打到源站)。 deny all忘了保留 fastcgi 配置:某些复制的规则导致所有 PHP 请求都被挡。Nginx 的location = /xmlrpc.php只匹配这一个文件,别忘了其他 location 正常配置。- 案例三:某站在
.htaccess里加了规则,但服务器是 Nginx,规则完全不生效,防护是假的。确认服务器类型再写规则。 - trackback 和 pingback 要一起关:很多人只关了 pingback,trackback 垃圾照收。
总结
XML-RPC 是遗留协议,现在的合法用途只剩”第三方客户端远程发布”。处理策略:九成站点直接彻底关闭(Nginx 层的 location = /xmlrpc.php { deny all; } 最省资源);确实用 App 发布的,只 unset 掉 system.multicall 和 pingback.ping;高并发攻击要在 CDN 层挡。判断依据是访问日志里有没有合法来源的请求。两个必须记住的点:不要靠删文件来关闭(升级会恢复),关闭前先确认服务器类型(Nginx 还是 Apache,写错规则等于没防护)。
