網站經常遭受到無用的大量的垃圾流量的騷擾,既造成了流量的浪費,還影響到正常用戶的訪問(嚴重時還會導致apache進程的崩貴)。
首先分析日志,總結出垃圾流量的特征,在apache前端增加nginx代理,利用nginx來完成流量的清理,只有正常的流量才交給後端的apache來處理。
1、根據nginx的訪問日志,根據匹配規則查出來源域名,按照來源域名的在一定時間內的訪問量來確定屏蔽對象將下面的腳本放入到系統定時任務中,定時(2-5分鐘,可根據具體情況做相應調整)執行。
確定一個判斷不正常的流量的數量,凡是大於該數量的來源一律清洗。
當然這裡有可能會有誤判,所以在後面將正常的來源地址過濾掉。
cat purge_traffic.sh
#!/bin/bash
if [ -f /var/log/nginx/www-access.log ]; then
tail -10000 /var/log/nginx/www-access.log | grep -E 'cps_site|tracert.php\?source' | awk -F'"' '{if ($4 ~ /http:/){print $4}}' | awk -F '/' '{print $3}' | grep -v -E '\.xxx\.cn|\.baidu\.com|google\.com' | sort | uniq -c | sort -nr | head -60 > /tmp/cps_site.log
cat /tmp/cps_site.log | awk '{if( $1 > 100 ){print $2}}' > /tmp/purge_cps.log
fi
2、nginx中調用的perl腳本,當請求進來時,通過下面的腳本判斷Referer地址是否來自上面生成的需要清理的域名。
perl判斷腳本,當發現來源地址匹配時返回1
cat purgetraffic.pm
package purgeTraffic;
use nginx;
sub purge {
my $r = shift;
my $ua = $r->header_in("Referer");
if(! $ua ) { return 0; }
open(FILES, "/tmp/purge_cps.log") || return 0;
@cps_file=<FILES>;
close(FILES);
foreach (@cps_file) {
my $eachcps = $_;
chomp $eachcps;
#$r->print($eachcps .'| ');
if ( $ua =~ m/$eachcps/ ) {
#return HTTP_NOT_ALLOWED;
return 1;
}
}
return 0;
}
1;
__END__
3、nginx.conf中調用perl腳本,符合清洗規則的來源直接返回404,
http {
...
perl_modules /etc/nginx;
perl_require purgetraffic.pm;
...
perl_set $purge purgeTraffic::purge;
server {
server_name www.xxx.cn;
if ($purge = 1) { return 404; } #屏蔽垃圾流量
...
}
}
重新加載nginx,完成自動流量清洗
還可以稍微修改一下perl腳本,增加一個白名單,減少誤判的可能。