PHP代码,拒绝频繁访问

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP代码,拒绝频繁访问相关的知识,希望对你有一定的参考价值。

一个网站性能有限,如果有人恶意去频繁对页面进行刷新,其实对服务器影响是很大的,导致资源使用非常高,直接影响到其他用户的体验。

那么对于这样的一些频繁访问,我们该如何去拒绝它呢?

我总结了两种方法:第一种方式通过Web服务器检查拒绝,第二种方式通过代码进行拦截过滤

通过Web服务器检查拒绝

第一种方式大致原理和思路是这样的,比如我们的Web服务器采用nginx,那个Nginx可以记录用户访问记录,并通过查询分析这个日志可以得出频繁访问用户IP列表。

我们需要做的事情:

做一个定时任务,定时去分析日志文件,将得到的频繁访问用户的IP,并将IP设置到Nginx配置文件中的IP黑名单中,然后进行reload配置文件,当IP类表较大时,可以更新到iptables中去。

日志文件,查询IP的访问次数

[[email protected] www]# grep ‘195.154.216.165‘ 2015-11-28.access.log|wc -l

289

[[email protected]-dig www]#
 1 [[email protected] www]# curl ipinfo.io/195.154.216.165;echo‘‘
 2 {
 3   "ip": "195.154.216.165",
 4   "hostname": "fr.07.gs",
 5   "city": "",
 6   "region": "",
 7   "country": "FR",
 8   "loc": "48.8600,2.3500",
 9   "org": "AS12876 ONLINE S.A.S."
10 }
11 [[email protected] www]# 

Nginx 上,所以可以使用 Nginx 的 Deny 来拒绝攻击者的IP访问。

 1 deny 195.154.211.220;
 2 deny 195.154.188.28;
 3 deny 195.154.188.186;
 4 deny 180.97.106.161;
 5 deny 180.97.106.162;
 6 deny 180.97.106.36;
 7 deny 195.154.180.69;
 8 deny 195.154.211.26;
 9 deny 221.229.166.247;
10 deny 180.97.106.37;
11 deny 195.154.216.164;
12 deny 195.154.216.165;
13 [[email protected] website]# 

通过代码进行拦截过滤

 1 $config[‘request_limit‘][‘open‘] = true; // 开启拦截请求
 2 $config[‘request_limit‘][‘all_request‘] = false; // 拦截所有请求,否则拦截相同请求
 3 $config[‘request_limit‘][‘min_request_interval_time‘] = 10;   // 允许的最小请求间隔 单位S(秒)
 4 $config[‘request_limit‘][‘max_malicious_times‘] = 1;  // 允许的最大恶意请求次数
 5 
 6 function maliciousRequestInterceptor() {
 7     $config = array(
 8         ‘all_request‘=> false, 
 9         ‘min_request_interval_time‘ => 1,
10         ‘max_malicious_times‘ => 10
11     );
12     $request_limit_cfg = C("request_limit");
13     if($request_limit_cfg && is_array($request_limit_cfg)){
14         if($request_limit_cfg[‘open‘] == false){
15             return true;
16         }
17         $config = array_merge($config,$request_limit_cfg);
18     }
19     session_start();
20     $pre_request_url = $_SESSION[‘PRE_REQUEST_URL‘];
21     $pre_request_time = $_SESSION[‘PRE_REQUEST_TIME‘];
22     $cur_request_url = GetCurUrl();
23     if(isset($pre_request_url) && isset($pre_request_time)){
24         if((trim($pre_request_url) == trim($cur_request_url) || $config[‘all_request‘])
25                 && (((microtime(TRUE) - floatval($pre_request_time))) < floatval($config[‘min_request_interval_time‘]))){
26             $request_times = $_SESSION[‘MALICIOUS_REQUEST_TIMES‘];
27             if(isset($request_times)){
28                 $request_times = intval($request_times) + 1;
29             }else{
30                 $request_times = 1;
31             }
32             $_SESSION[‘MALICIOUS_REQUEST_TIMES‘] = $request_times;
33             if ($request_times > $config[‘max_malicious_times‘]) {
34 //                    error_log("intercept a malicious request ".$_SERVER[‘REMOTE_ADDR‘].":".$cur_request_url);
35 //                    header($_SERVER["SERVER_PROTOCOL"]." 403 access denied."); 
36 //                    exit();
37                 return false;
38             }
39         }else{
40             $_SESSION[‘MALICIOUS_REQUEST_TIMES‘] = 0;
41         }
42     }
43     $_SESSION[‘PRE_REQUEST_URL‘] = $cur_request_url;
44     $_SESSION[‘PRE_REQUEST_TIME‘] = microtime(TRUE);
45     return true;
46 }
47 // php获取当前访问的完整url地址
48 function GetCurUrl() {
49     $url = ‘http://‘;
50     if (isset ( $_SERVER [‘HTTPS‘] ) && $_SERVER [‘HTTPS‘] == ‘on‘) {
51         $url = ‘https://‘;
52     }
53     if ($_SERVER [‘SERVER_PORT‘] != ‘80‘) {
54         $url .= $_SERVER [‘HTTP_HOST‘] . ‘:‘ . $_SERVER [‘SERVER_PORT‘] . $_SERVER [‘REQUEST_URI‘];
55     } else {
56         $url .= $_SERVER [‘HTTP_HOST‘] . $_SERVER [‘REQUEST_URI‘];
57     }
58     return $url;
59 }

 

以上是关于PHP代码,拒绝频繁访问的主要内容,如果未能解决你的问题,请参考以下文章

PHP 访问被拒绝

如何使用 PHP 和 IIS 7 访问映射网络驱动器中的文件

PHP登录页面因root用户错误而拒绝访问,并期望参数1为mysqli,bool给定[重复]

超级有用的9个PHP代码片段

尝试访问远程数据库时 mysql_connect 访问被拒绝错误

php--------http 状态代码及其原因