首页 论坛 WordPress网站如何限制同 IP 访问频率次数提升安全
帖子详情

限制对 WordPress 特定网址的访问频率,比如一个 IP 地址每秒只能访问一次,每分钟一次,甚至每小时一次,可以有利避免对 wp-login.php 进行暴力破解登录、对 admin-ajax.php 恶意提交文章评论、刷手机短信验证码,以及 CC 攻击你的 API 接口等。

当限制请求次数在 1 分钟 1 次之内时,比如:1 分钟 1 次、 1秒 1 次、20 秒 1 次,推荐 使用 Nginx 限制访问频率。当限制频率超过了 1 分钟 1 次,比如 20 分钟 5 次、2 小时 3 次时,就要使用如下方法了。

准备工作

为了提高性能,代码使用了 memcached 缓存数据到服务器的内存,因此你的服务器必须安装 memcached 。宝塔面板—— PHP——扩展选项,找到 memcached 点击安装, 注意看最后一个字母是 d 。PHP 版安装就绪,再去软件商店搜一下,确认软件版的是否也已安装。

代码部署

代码分为两部分,第一部分是自定义一个控制访问频率的函数,第二部分是使用WordPress 动作钩子,将频率控制函数挂在到所需要控制页面 PHP 上。原理不懂没事,只要你明白步骤分两步走就行。

第一步:添加频率控制函数

你可以自行调整防刷新时间、次数、警告次数、解封时间等,在代码中用 // 对关键内容做了注释,一看就能明白在哪里修改。

/**
* 限制URL访问频率的函数,对管理员登录状态以外的访问起效
* 可以通过动作钩子引用此函数,限制特定的页面
*/

function cccitu_waf() {
if(!current_user_can( 'manage_options' )){ //对登录后的网站管理员访问不起作用。该函数是 WordPress 网站独有,非 WordPress 请不要使用此判断
ini_set("display_errors", "Off");
error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING);
extension_loaded('memcached') or die('memcached扩展未安装!');
$logPath = $_SERVER['DOCUMENT_ROOT'] . '/cccitu-waf/cccitu-waf.log'; //日志记录文件保存路径,在网站根目录的 cccitu-waf 文件内内可以查看
$fileht = $_SERVER['DOCUMENT_ROOT'] . '/cccitu-waf/cccitu-ban.log'; //被拉黑IP记录文件保存路径
if (!file_exists($logPath)) {
@mkdir($_SERVER['DOCUMENT_ROOT'] . '/cccitu-waf/', 0777, true);
@file_put_contents($logPath, '');
@file_put_contents($fileht, '');
}
$allowtime = 60; //防刷新时间,以秒为单位,具体数字可以根据需要自行调整
$allownum = 3; //防刷新次数,比如上面设置的房刷新时间为60,这里设置为3,那么60秒访问次数超过3次就会引发警告
$allowRefresh = 1; //在此警告次数之后拉黑IP,写 1 则是警告一次后,将会拉黑该访问IP地址
$bantime = 3600; //封禁时间,超时自动解封,以秒为单位,3600 即为 1个小时后解封该IP地址,注意时间最长不能超过30天
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
$uri = $_SERVER['REQUEST_URI'];
$cache = new Memcached();
$cache->addServer('127.0.0.1', '11211') or die('memcached连接失败!');//如果你更改了memcached 默认的IP或端口,请根据实际情况修改
$inban = $cache->get('cccitu-waf-ban-' . $ip);
if ($inban) {
header("HTTP/1.1 403 Forbidden"); //可以自行修改h1和p标签内的提示内容,当被封IP访问此页面时显示。
exit('<h1>403 Forbidden 非法访问</h1>
<p>非法访问</p>'
);
}
$wafarr = $cache->get('cccitu-waf-' . $ip);
if (!$wafarr) {
$wafarr = [
'path' => $uri,
'time' => time() + $allowtime,
'sum' => 1,
];
$cache->set('cccitu-waf-' . $ip, $wafarr, time() + $allowtime);
} else {
if ($wafarr['sum'] > $allownum) {
$wafsum_arr = $cache->get('cccitu-waf-sum-' . $ip);
if (!$wafsum_arr) {
$wafsum_arr = [
'sum' => 1,
];
$cache->set('cccitu-waf-sum-' . $ip, $wafsum_arr, time() + $bantime);
} else {
if ($wafsum_arr['sum'] > $allowRefresh) {
$cache->set('cccitu-waf-ban-' . $ip, 1, time() + $bantime);
file_put_contents($fileht, $ip . "\n", FILE_APPEND);
} else {
$wafsum_arr['sum']++;
$cache->set('cccitu-waf-sum-' . $ip, $wafsum_arr, time() + $bantime);
}
}
file_put_contents($logPath, $ip . '--' . date('Y-m-d H:i:s', time()) . '--' . $uri . "\n", FILE_APPEND);
header("HTTP/1.1 403 Forbidden");
exit("请求频率QPS超过限制,请酌情访问,多次提醒后会封禁IP!");//可以自行修改提示内容,当访问被警告时,此页面显示。
} else {
$wafarr['sum']++;
$cache->set('cccitu-waf-' . $ip, $wafarr, $wafarr['time']);
}
}
}
}

将以上代码,复制到主题 functions.php 最后一行,如果最后一行是 ?>,则要将代码放在 ?> 的上一行。functions.php 文件在哪里?在服务器 /wp-content/themes/ 目录的主题文件夹中。

如果你无法进入服务器,也可以进入:网站后台——外观——主题编辑器——模板函数(functions.php) 进行操作。

第二步:限制具体的网址

专一:限制 wp-login.php 登录注册

/**
* 使用教程:https://www.cccitu.com/5079.html
* 限制 wp-login.php 的访问频率,可以防止恶意注册和登录暴力破解
*/

add_action('login_enqueue_scripts', function(){
cccitu_waf();
});

专一:限制 admin-ajax.php 数据提交

/**
* 限制使用 admin-ajax.php 进行 ajax 异步加载的数据提交的频率,一般文章评论,短信发送等功能都使用了此功能
* 注意,这里所限制的是通过 post 和 get 提交数据,测试效果时,要以 域名/admin-ajax.php?action=cccitu 的形式访问
*/

add_action('admin_init', function(){
if (wp_doing_ajax()){
cccitu_waf();
}
});

通用:限制 任意一个网址

/**
* 限制任意一个网址
*/

add_action('init', function(){
$cccitu_get_url = $_SERVER['REQUEST_URI'];
$cccitu_waf_check = false;
//例如要限制 https://www.cccitu.com/5065.html ,就将主域名后面的 /5065.html 填写到代替换的单引号内
if(strpos($cccitu_get_url, '待替换') !== false) {
$cccitu_waf_check = true;
break;
}

if ($cccitu_waf_check){
cccitu_waf();
}
});

通用:限制 任意多个网址

/**
* 限制任意多个网址
*/

add_action('init', function(){
//例如要限制 https://****/5065.html ,就将主域名后面的 /5065.html 填写到代替换的单引号内
//当三个网址以上时,自己在括号内以英文的逗号,单引号的形式添加即可,比如('/5065.html','admin-ajax.php','wp-login.php')
$cccitu_waf_kay = array('/5065.html','admin-ajax.php');
$cccitu_get_url = $_SERVER['REQUEST_URI'];
$cccitu_waf_check = false;

foreach($cccitu_waf_kay as $word) {
if(strpos($cccitu_get_url, $word) !== false) {
$cccitu_waf_check = true;
break;
}
}

if ($cccitu_waf_check){
cccitu_waf();
}
});

为尽量减少影响 WordPress 的性能,针对不同的限制需求,写了以上不同的代码,当多个代码都能满足你的需求时,建议优先选择专一的,其次才是通用的。将所选代码同样复制进 functions.php 的最后一行,也就是第一步代码的下面,当第一步和第二步代码都加入后,即可生效。

本文代码来源:https://www.cccitu.com/5079.html

另外还可以使用同样的道理来防止网站被恶意CC攻击

<?php

/**
* 防止频繁请求,防范CC攻击,支持上万并发
* 转载请保留版权,谢谢!
*/

ini_set("display_errors", "Off");
error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING);
extension_loaded('memcached') or die('memcached扩展未安装!');

$logPath = $_SERVER['DOCUMENT_ROOT'] . '/waf/waf.log'; //日志记录文件保存路径,$_SERVER['DOCUMENT_ROOT']是网站根目录
$fileht = $_SERVER['DOCUMENT_ROOT'] . '/waf/ban.log'; //被拉黑IP记录文件保存路径
if (!file_exists($logPath)) {
@mkdir($_SERVER['DOCUMENT_ROOT'] . '/waf/', 0777, true);
@file_put_contents($logPath, '');
@file_put_contents($fileht, '');
}
$allowtime = 2; //防刷新时间(秒)
$allownum = 5; //防刷新次数(比如2秒5次,超过就警告)
$allowRefresh = 10; //在此警告次数之后拉黑IP
$bantime = 600; //封禁时间,超时自动解封(秒)

$ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
$uri = $_SERVER['PHP_SELF'];
$cache = new Memcached();
$cache->addServer('127.0.0.1', '11211') or die('memcached连接失败!');
$inban = $cache->get('waf-ban-' . $ip);
if ($inban) {
header("HTTP/1.1 403 Forbidden");
exit('<h1>403 Forbidden 非法访问</h1>
<p>你的请求似乎不符合常理,已被服务器防火墙拦截,如有疑问请联系管理员QQ523077333</br>如果你在开发测试过程中超频被封IP,请等待'
. ($bantime / 60) . '分钟后自动解封</br>你的IP:' . $ip . '</p>');
}
$wafarr = $cache->get('waf-' . $ip);
if (!$wafarr) {
$wafarr = [
'path' => $uri,
'time' => time() + $allowtime,
'sum' => 1,
];
$cache->set('waf-' . $ip, $wafarr, time() + $allowtime);
} else {
if ($wafarr['sum'] > $allownum) {
$wafsum_arr = $cache->get('waf-sum-' . $ip);
if (!$wafsum_arr) {
$wafsum_arr = [
'sum' => 1,
];
$cache->set('waf-sum-' . $ip, $wafsum_arr, time() + $bantime);
} else {
if ($wafsum_arr['sum'] > $allowRefresh) {
$cache->set('waf-ban-' . $ip, 1, time() + $bantime);
file_put_contents($fileht, $ip . "\n", FILE_APPEND);
} else {
$wafsum_arr['sum']++;
$cache->set('waf-sum-' . $ip, $wafsum_arr, time() + $bantime);
}
}
file_put_contents($logPath, $ip . '--' . date('Y-m-d H:i:s', time()) . '--' . $uri . "\n", FILE_APPEND);
header("HTTP/1.1 403 Forbidden");
exit("请求频率QPS超过限制,请酌情访问,多次提醒后会封禁IP!");
} else {
$wafarr['sum']++;
$cache->set('waf-' . $ip, $wafarr, $wafarr['time']);
}
}

以上代码添加到你网站核心文件中,相当于你网站任何页面都会引用的一个文件。类似于:config.php

WordPress网站添加到根目录的/index.php头部即可。

其他PHP网站根据你的程序逻辑决定。

版权:言论仅代表个人观点,不代表官方立场。转载请注明出处:https://www.52diyhome.com/forum/295966.html

发表评论
暂无评论
  • 0 +

    访问总数

  • 0 +

    会员总数

  • 0 +

    资源总数

  • 0 +

    今日发布

  • 0 +

    本周发布

  • 0 +

    运行天数

资源在于分享,创作来源想象