新站上线后第一件事不是写文章,而是把门关好。WordPress 默认开着不少"方便但危险"的入口:XML-RPC、用户名枚举、pingback……这篇记录我给本站做的一轮加固——不装任何插件,全部靠后台设置和十几行代码完成。
要点速览
- 后台设置:关注册、关 pingback、评论先审后显。
- 禁用 XML-RPC,堵住批量猜密码的老通道。
- 阻止未登录访客枚举用户名(REST、?author=、站点地图、oEmbed)。
- 统一登录报错、隐藏版本号,少给攻击者一点信息。
先想清楚:攻击者从哪里进来
对个人博客来说,最常见的威胁不是高级漏洞,而是自动化脚本:批量扫描、枚举用户名、再对登录接口撞密码。所以加固的思路很朴素——少暴露信息,少留入口。

第一层:后台设置就能做的
- 关闭用户注册:设置 → 常规,取消"任何人都可以注册",新用户默认角色保持"订阅者"。
- 关闭 pingback / trackback:设置 → 讨论,两项都取消。已发布的文章也要单独关掉。
- 评论先审后显:勾选"评论必须经人工批准",要求填写名字和邮箱,旧文章 30 天后自动关闭评论。
第二层:十几行代码
下面这段放进主题的 functions.php(更稳妥的做法是放进 mu-plugins,换主题也不会丢):
// 禁用 XML-RPC
add_filter( 'xmlrpc_enabled', '__return_false' );
add_filter( 'xmlrpc_methods', '__return_empty_array' );
// 未登录时隐藏用户接口
add_filter( 'rest_endpoints', function ( $e ) {
if ( ! is_user_logged_in() ) {
unset( $e['/wp/v2/users'], $e['/wp/v2/users/(?P<id>[\d]+)'] );
}
return $e;
} );
// ?author=1 和作者页一律跳回首页(优先级 1,抢在规范化跳转之前)
add_action( 'template_redirect', function () {
if ( ! is_user_logged_in() && ( is_author() || isset( $_GET['author'] ) ) ) {
wp_safe_redirect( home_url( '/' ), 301 );
exit;
}
}, 1 );
// 站点地图不列用户;登录报错统一;隐藏版本号
add_filter( 'wp_sitemaps_add_provider', fn( $p, $n ) => 'users' === $n ? false : $p, 10, 2 );
add_filter( 'login_errors', fn() => '用户名或密码不正确。' );
remove_action( 'wp_head', 'wp_generator' );
一个细节:
?author=1的拦截要用优先级 1。否则 WordPress 自己的规范化跳转会先把它重定向到/author/用户名/,用户名照样泄露。
第三层:用未登录身份验证一遍
改完一定要换成"访客视角"验证,登录状态下很多限制是看不出来的:
curl -s -o /dev/null -w "%{http_code}\n" https://你的域名/wp-json/wp/v2/users # 期望 404
curl -s -o /dev/null -w "%{redirect_url}\n" "https://你的域名/?author=1" # 期望跳回首页
curl -s https://你的域名/wp-sitemap.xml | grep users # 期望无输出
curl -s https://你的域名/ | grep generator # 期望无输出
还没做、但值得做的
- 登录限速:在反向代理或 fail2ban 层限制
wp-login.php的失败次数。 - 禁用后台文件编辑:
DISALLOW_FILE_EDIT,防止后台被攻破后直接改代码。 - 定期备份:数据库卷和上传目录,至少保留一份在主机之外。
安全没有终点,但先把最常见的几扇门关上,已经能挡住绝大多数自动化扫描。
