这几天感觉网站非常的卡,刚开始我以为是网络问题,经过几天的排查和观察可以肯定不是网络,于是进服务器后台一看,好家伙,CPU占用爆表,导致触发了服务商的CPU限制,不知道是哪里的问题。

卸载了好几个插件无果,又登录上服务器把一些感觉有问题的文件给全删了,CPU占用降了一半,还是比以前占用高不少。使用终端命令“top”观察了一下,是一个php-fpm偶发占用很大的CPU,而且还是很有规律的,间隔时间都一样,查日志发现大量莫名其妙访问“/wp-cron.php?doing_wp_cron=xxxx”类似的记录,IP地址全是CloudFlare的CDN地址。然后装个插件“WP Crontrol”一看,好家伙,一堆定时任务……

把一堆无用的定时任务删除之后,CPU下降了不少但还是比平常高,去查看防火墙实时流量,好家伙,不断有人在爆破。

我定睛一看IP地址,好家伙,全是CloudFlare分配的IP地址,而且还是自己爆破自己?

又经过一番分析,终于发现套了CDN后的一个大坑——获取不到真实的用户IP。

使用CDN获取不到真实IP

Wordfence这个垃圾安全插件这么落后,竟然只是用远程地址来做IP检测,难怪Wordfence一直不block任由它爆破,自己是白名单嘛……那么这样一来,那以前不是一直是裸奔?卧槽,细思极恐!

在网上搜索了一番,在wp-config.php 文件中增加下面代码就可以获取 CDN 后访客的真实 IP。这个函数的核心是用解析后的 HTTP_X_FORWARDED_FOR 替换 REMOTE_ADDR。

// WordPress 使用 CDN 后获取访客真实 IP
if( !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ) {
    $get_HTTP_X_FORWARDED_FOR = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    $_SERVER['REMOTE_ADDR'] = trim($get_HTTP_X_FORWARDED_FOR[0]);
}

这下终于检测出真实IP了,原来是来自香港IP的一个机器人。

然后问题又来了,我观察了一段时间,Wordfence就是不block,然后我手动block,才几分钟它又不block了,好家伙。

既然问题已经发现,后面有空我再研究下了。

又再次详细看了一下Wordfence的设置,原来“常规Wordfence选项”中有个“Wordfence如何获得客户端IP(用户真实IP)”这个设置, 默认的选项是:让Wordfence使用最安全的方法来获取访问者IP地址。 防止欺骗并适用于大多数网站。

最后面还有一个选项:使用Cloudflare“CF-Connecting-IP”HTTP标头获取访客IP。 仅在您使用Cloudflare时使用。

我去,好家伙!原来我一直在裸奔,白装了个安全插件。

防止xmlrpc.php被扫描

查看实时流量,发现大量访问xmlrpc.php和wp-login.php,经查询,xmlrpc.php这个文件存在XML-RPC pingbacks 攻击的问题,以及会绕过WordPress的登录次数限制,难怪前面防火墙一直不block。

彻底屏蔽有以下6种方法:

  • 直接删除xmlrpc.php文件;
  • 通过安装插件关闭;
  • 在当前主题的 functions.php 文件里面添加:add_filter('xmlrpc_enabled', '__return_false');
  • 使用Apache服务器的可以通过在 .htaccess 文件前面添加:
<Files xmlrpc.php>
Order Allow,Deny
Deny from all
</Files>
  • 使用nginx服务器的可以在网站配置文件 .config 添加规则:
location ~* ^/xmlrpc.php$ {
return 403;
}
  • 在WordPress的wp-config.php文件添加:
if(strpos($_SERVER['REQUEST_URI'], 'xmlrpc.php') !== false)
    $protocol   = $_SERVER['SERVER_PROTOCOL'] ?? '';

    if(!in_array($protocol, ['HTTP/1.1', 'HTTP/2', 'HTTP/2.0', 'HTTP/3'], true)){
        $protocol   = 'HTTP/1.0';
    }

    header("$protocol 403 Forbidden", true, 403);
    die;
}

我是直接用了最后一种。

立即屏蔽尝试以这些用户名登录的用户的IP

Wordfence 上设置了立即屏蔽IP的,然而并没有什么卵用……

最终结论

总体观察下来,屏蔽xmlrpc.php的效果是最好的,立竿见影,少了很多登录尝试,Wordfence免费版本真没什么卵用……