nginx论坛防刷贴的实例

Posted: 2010年6月6日星期日
最近我的一个朋友跟我抱怨他的论坛被一群无聊的人在刷帖,问我有什么好的方法避免这种情况的发生,由于他使用的web服务器是nginx,我就利用web站点的访问log和nginx的目录访问权限规则写了个脚本,实现上面的功能,具体脚本的设计如下:
每5分钟探测当前这一个小时单IP的访问量,如果达到设置的上限,直接返回403错误页面给他,禁止他在接下来的一个小时的访问,并记录下他的ip,若在接下来的一个小时访问量正常,再智能的把他的站点的访问权限放开,允许他继续使用论坛,这样就拒绝了这群无聊的人,当然记得排除自己的ip地址。
附shell脚本实例

#!/bin/sh

LANG=UTF-8
onehourago=`date -d "1 hour ago" +%d\/%b\/%Y:%H`
now=`date +%d\/%b\/%Y:%H`
grep -v 1.1.1.1 /usr/local/nginx/logs/access.log | awk '/$onehourago/{++S[$1]}END{for (a in S) print a, S[a]}' | awk '{if($2>5000) print }' > /tmp/onehoureagodenyip
grep -v 1.1.1.1 /usr/local/nginx/logs/access.log | awk '/$now/{++S[$1]}END{for (a in S) print a, S[a]}' |awk '{if($2>5000) print }' > /tmp/nowdenyip
cat /tmp/onehoureagodenyip >> /tmp/nowdenyip
awk '{print $1}' /tmp/nowdenyip | sort |uniq > /tmp/denyip
cat /dev/null > /usr/local/nginx/conf/acl.conf
if [ ! -z /tmp/denyip ] ; then
for i in `cat /tmp/denyip`
do
echo "deny $i;" >> /usr/local/nginx/conf/acl.conf
done
fi
echo "allow all;" >> /usr/local/nginx/conf/acl.conf
echo "location ~ .*\.php?$ {
include /usr/local/nginx/conf/enable_php5.conf;
}" >> /usr/local/nginx/conf/acl.conf
kill -HUP `ps -ef |grep "nginx: master" |grep -v grep |awk '{print $2}'`

脚本说明:
先在nginx的主配置文件中server断中加入如下的内容:
location ^~ / {
include /usr/local/nginx/conf/acl.conf;
}
排除1.1.1.1的ip,同时当单IP一个小时的访问量达到5000次就屏蔽它(要是你的log中记录的东西不多的话,90%的用户单IP访问量一小时不可能有这么大)。

1 评论:

  1. 阿彪 2010年7月23日 16:32

    日志应该比较小才可以,否则会有性能问题吧