如何构建安全的 WordPress 3:限制登录次数,防止暴力破解
我在「如何构建安全的 WordPress」系列文章前面两篇中,安全首先是不要让攻击者直到你的登录名,所以第一篇「防止用户名暴露」教大家如何在站点的前端页面隐藏用户登录名,接着第二篇通过「隐藏登录失败时「未知用户名」和「密码不正确」错误信息」都改成「用户名或者密码错误」,这样攻击者就无法知道尝试登录的用户名是否真实的用户名了。
做了这两步之后,如果你没有在站点上展示过自己的用户名,那么基本攻击者比较难猜到你的 WordPress 站点登录名了,但是万一攻击者还是猜到你的用户名,对你的站点进行暴力破解,这时候怎么办?
是的,在默认情况下,WordPress 没有防止暴力破解的功能,在登录界面,攻击者可以不停的登录尝试输入账号密码,如果密码不够复杂,攻击者如果被使用暴力破解工具扫描的话,那么很可能很快就会被破解的。
如何防止 WordPress 被暴力破解
现在大部分用户防止 WordPress 用户密码被暴力破解方法是使用一个叫做 Limit Login Attempts 的插件,该插件可以限制登录次数,账号被错误登录次数上了上限之后,用户名或者 IP 就会被限制。
但是 Limit Login Attempts 这个插件把登录尝试错误记录都存在 Options(选项)里面,这样的处理并不是最佳选择,首先可能效率可能会存在一些问题,另外也会填充太多的数据到 Options 表中。
如果服务器安装了 Memcached 的话,我们可以把失败的尝试记录存到 Memcached 里面,这样就可以通过内存缓存去优化登录次数限制功能。
使用 Memcached 优化登录次数限制功能
当用户登录失败的时候,以 IP 作为 key,失败登录次数 +1 作为值,存到内存里面。
add_action('wp_login_failed', function($username){
$key = wpjam_get_ip();
$times = wp_cache_get($key, 'wpjam_login_limit');
$times = $times ?: 0;
wp_cache_set($key, $times+1, 'wpjam_login_limit', MINUTE_IN_SECONDS*15);
});
再次登录的时候,我们检测一下访问者对应的 IP 的失败次数,如果是大于 5 次,就直接报错不能访问了。
add_filter('authenticate', function($user, $username, $password){
$key = wpjam_get_ip();
$times = wp_cache_get($key, 'wpjam_login_limit');
$times = $times ?: 0;
if($times > 5){
remove_filter('authenticate', 'wp_authenticate_username_password', 20, 3);
remove_filter('authenticate', 'wp_authenticate_email_password', 20, 3);
return new WP_Error('too_many_retries', '你已尝试多次失败登录,请15分钟后重试!');
}
return $user;
}, 1, 3 );
登录失败之后的界面如下图所示:

最后附上一点小功能,登录多次失败报错的时候登录框也支持摇头的功能。
add_filter('shake_error_codes', function ($error_codes){
$error_codes[] = 'too_many_retries';
return $error_codes;
});
最后还是那句话,任何站点,安全是最重要的,攻击者可以说无所不在,如果用户名被攻击者获知了,一定要限制登录次数,防止暴力破解。
WPJAM 用户管理插件 已经集上面所有的功能和相关代码,直接启用即可,点击查看 WPJAM 用户管理插件的详细介绍,Modular 主题也集成了,我会在介绍 WordPress 安全这系列文章的时候,将这些安全相关代码也整合到 Modular 主题中,争取打造最安全的 WordPress 主题。
WPJAM Basic 插件已经集成了 Memcached,下载 WPJAM Basic 之后,将 wpjam-basic/template/
目录下的 object-cache.php
文件复制到 wp-content
目录下即可。
专题:WordPress 安全: