自动封锁采集器、自动评论、垃圾蜘蛛

2014-08-06 17:55:52 +08:00
 Tianpu
被折腾的受不了,大致实现了访问频率稍微高就自动封掉访问,似乎是封一个小时什么比较好,不想为恶意访问的人考虑太多,所以自动解封就不实现了

大致上要耗费1ms的执行时间

实现:php mysql memcached

思路:正常蜘蛛白名单,读到memcached里去,其它的计划任务再检测,频率太高就封掉。

文件结构:
bots.txt 蜘蛛IP数据
white.txt 需要补充到白名单的数据
inc.php需要包含到动态页面的函数
block.php计划任务执行脚本

---------bots.txt-----------------
//googlebot
64.233.160.0-64.233.191.255
66.102.0.0-66.102.15.255
66.249.64.0-66.249.95.255
72.14.192.0-72.14.255.255
74.125.0.0-74.125.255.255
209.85.128.0-209.85.255.255
216.239.32.0-216.239.63.255

//bingbot
64.4.0.0-64.4.63.255
65.52.0.0-65.55.255.255
131.253.21.0-131.253.47.255
157.54.0.0-157.60.255.255
207.46.0.0-207.46.255.255
207.68.128.0-207.68.207.255

//baiduspider
180.76.5.0-180.76.5.255
180.76.6.0-180.76.6.255
220.181.108.0-220.181.108.255
123.125.67.0-123.125.67.255
123.125.71.0-123.125.71.255

//sogouspider
218.30.103.0-218.30.103.255

//yandexbot
199.21.99.0-199.21.99.255

针对用户这么写:
function initipdata(){
global $memd;
$ips = array();
$key = 'bots.txt';
$ips = $memd->get($key);
if(empty($ips)){
$temp = explode("\n",file_get_contents(dirname(__FILE__).'/bots.txt'));
foreach($temp as $raw){
$raw = trim($raw);
if(!empty($raw) && substr($raw,0,2)!='//'){
$ra = explode('-',$raw);
if(long2ip(ip2long($ra[0]))==$ra[0] && long2ip(ip2long($ra[0]))==$ra[0]){
$ips[] = array('s'=>ip2long($ra[0]),'e'=>ip2long($ra[1]));
}
}
}
if(!empty($ips)) $memd->set($key,$ips,86400);
}
return $ips;
}
function ipwarn(){
global $conn,$memd;
$check = false;
$ips = initipdata();
$key = $_SERVER['REMOTE_ADDR'];
$raw = ip2long($key);
foreach($ips as $ip){
if(!$check && $raw>=$ip['s'] && $raw<=$ip['e']){
$check = true;
}
}
if(!$check){
$num = 0;
$num = $memd->get($key);
$num = $num+1;
$memd->set($key,$num,120);
if($num>30){
mysql_query('insert into `_zwarn` (`ip`,`time`) values (\''.addslashes($key).'\',\''.addslashes(time()).'\');',$conn);
}
}
}

然后做个计划任务

function show($s){
echo $s."\r\n";
}
function getipnum($key){
global $memd;
$num = 0;
$num = $memd->get($key);
return $num;
}
function gethost($ip){
$r = '';
$r = gethostbyaddr($ip);
return $r;
}
function checkip($ip,$host){
$white = array('.googlebot.com','.baidu.com','.yandex.com','.sogou.com','.bing.com','.msn.com');
$check = true;
if(!empty($host) && $ip!==$host){
$addr = gethostbyname($host);
if($addr==$ip && str_ireplace($white,'',$host)!=$host){
$check = false;
}
}
return $check;
}
$meta = array();
$sql = 'select * from `_zwarn`;';
$rs = mysql_query($sql,$conn);
while($row=mysql_fetch_object($rs)){
$meta[($row->ip)] = $row->time;
}
foreach(array_keys($meta) as $addr){
$data = array();
$data['addr'] = $addr;
$data['host'] = gethost($data['addr']);
$data['bool'] = checkip($data['addr'],$data['host']);
$data['last'] = 30;
$data['curr'] = getipnum($data['addr']);
$data['time'] = time()-$meta[($data['addr'])];
$data['rate'] = ($data['curr']-$data['last'])/$data['time'];
foreach(array_keys($data) as $key){
show($key.': '.$data[$key]);
}
if($data['bool']){
if($data['rate']>0.5 || $data['curr']>60){
show('iptables -I INPUT -s '.$data['addr'].'/32 -j DROP');
passthru('iptables -I INPUT -s '.$data['addr'].'/32 -j DROP');
mysql_query('insert into `_zblock` (`ip`,`host`) values (\''.addslashes($data['addr']).'\',\''.addslashes($data['host']).'\');');
mysql_query('delete from `_zwarn` where `ip`=\''.addslashes($data['addr']).'\';');
if($data['curr']>0){
$memd->set($data['addr'],0,120);
}
}
if($data['curr']<1){
mysql_query('delete from `_zwarn` where `ip`=\''.addslashes($data['addr']).'\';');
}
}
else{
file_put_contents(dirname(__FILE__).'/white.txt',$data['addr']."\r\n",FILE_APPEND);
mysql_query('delete from `_zwarn` where `ip`=\''.addslashes($data['addr']).'\';');
}
show('');
}
3533 次点击
所在节点    分享创造
13 条回复
X-Force
2014-08-06 18:57:58 +08:00
收藏备用,给楼主加油……
dong3580
2014-08-06 19:18:18 +08:00
先收藏备用,
请教一下楼主,模拟浏览器请求,带上全部user-agent,不频繁,变ip,恐怕效果不佳吧?
Tianpu
2014-08-06 21:14:50 +08:00
@dong3580 如果跟真实访问类似,实在没什么好办法
overlords
2014-08-06 22:25:05 +08:00
@dong3580 这么多的IP哪里搞啊?
iannil
2014-08-07 00:23:41 +08:00
变ip的方法有,但成本一般比较高,常见的方法:
1、多条家用线路重拨获得新ip,这种比较简单
2、购置大量的虚拟机,然后通过proxy中转请求来达到切换ip的目的,这种比较复杂,因为有个路由器和防火墙的关系,需要proxy主动向调度中心发起请求。
3、使用VPN拨号
liuchen9586
2014-08-07 00:48:47 +08:00
收藏备用
66CCFF
2014-08-07 01:25:16 +08:00
@iannil 低成本方法: 淘宝上大量代理
iannil
2014-08-07 01:29:18 +08:00
@66CCFF 代理成本也不低,因为你需要雇佣技术人员针对这些代理写一套检测有效性、分配ip、联合调度等内容的程序。另外,代理也有相同的问题,就是如果要绕过防火墙,必须要由proxy,也就是代理服务器主动发起连接。
yangqi
2014-08-07 01:33:24 +08:00
fail2ban结合nginx/apache log就能搞定吧
Tianpu
2014-08-07 08:02:18 +08:00
@iannil TOR
dong3580
2014-08-07 09:48:53 +08:00
@overlords
@iannil
就算不是变ip,只需要前面几种,爬点东西都会带上全部的user-agent,而且都只开一个线程,访问基本上都是爬完整个page几分钟,有时候几个页面睡会儿,长期挂住。这样根本没法屏蔽。个人觉得防止爬虫太难了。
iannil
2014-08-07 14:30:53 +08:00
@dong3580 是的, 如果完全不考虑效率问题,操作速度以及操作习惯完全与人一致的爬虫是无法屏蔽的。
但是对爬虫来说,效率是必定要考虑的,因为如果爬虫速度比人还慢,就会丢失了一半的价值,另一半的价值是爬虫不知疲倦没有情绪。
iannil
2014-08-07 14:34:50 +08:00
@Tianpu tor是个好办法,但tor的问题在于连接tor的成本过高以及速度上的限制,无法稳定高速的进行抓取操作。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/126445

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX