自从「Nginx 不受 CDN 服务影响获取访客真实 IP」一文以来,Nginx的日志里记录就比较准确了,目前还是仅仅三天不到,明月准备每周都在本地通过 360星图 日志分析(可参考「站长必备的网站日志分析工具:360 星图」一文)工具来分析日志获取恶意请求IP进行 iptables 屏蔽,尽最大努力减少服务器的恶意请求。
使用 iptables 屏蔽IP效率太低,管理起来也非常的繁琐,借助 iptables 的扩展 ipset 可以轻松的解决这个“繁琐”,下面明月就给大家做个简单的使用分享。
ipset安装
yum安装: yum install ipset
创建一个ipset
ipset create myban hash:net
#也可以是hash:ip ,这指的是单个ip,myban是ipset名称
ipset默认可以存储65536个元素,使用maxelem指定数量
ipset create myban hash:net maxelem 1000000
#黑名单
还可以指定 timeout 来表示封禁IP时限,如:
ipset create myban hash:ip timeout 3600
#黑名单里的IP封禁3600秒
查看已创建的ipset
ipset list
加入一个名单ip
ipset add myban 10.60.10.xx
去除名单ip
ipset del myban 10.60.10.xx
创建防火墙规则
让 myban 这个IP集里的ip都无法访问80、443端口(如:CC攻击可用)
iptables -A INPUT -p tcp -m set --match-set myban src -m multiport --dports 443,80 -j DROP
保存 iptables 规则
service iptables save
将ipset规则保存到文件
ipset save myban -f myban.txt
删除ipset
ipset destroy myban
导入ipset规则
ipset restore -f myban.txt
ipset的一个优势是集合可以动态的修改,即使ipset的iptables规则目前已经启动,新加入的ipset的ip也生效。
附赠自动筛选恶意IP的脚本
一个基于自定义访问频率阈值或者请求敏感关键字来创建自动筛选恶意IP的ipset_deny.sh脚本。
- FILES: Nginx的access.log文件
- sensitive: 敏感关键字
- threshold: 一分钟内请求频率阈值
#!/bin/bash
FILES="/data/nginx/logs/access.log"
sensitive="sensitive_word"
threshold=1000
ip_file="/tmp/ip_file"
sensitive_file="/tmp/sensitive_file"
DATE=`date -d '1 minutes ago' +%Y:%H:%M`
grep ${DATE} ${FILES} | awk '{print $1}' | sort | uniq -c | sort -n | tail -n 1 > ${ip_file}
grep ${DATE} ${FILES} | grep -i ${sensitive} | awk '{print $1}' | sort -n | uniq > ${sensitive_file}
ip_file_number=`awk '{print $1}' ${ip_file}`
ip_file_ip=`awk '{print $2}' ${ip_file}`
if [[ $ip_file_number -gt $threshold ]];then
ipset add blacklist ${ip_file_ip} timeout 3600
fi
if [ -s ${sensitive_file} ];then
for sensitive_ip in `cat ${sensitive_file}`
do
ipset add blacklist ${sensitive_ip}
done
fi
最后用crontab定时启动脚本。
echo "* * * * * bash /data/iptables_ipset_deny.sh" >> /etc/crontab
4 条评论
通常情况下每个网站都有各自的log,而access.log并不使用。
access.log是Nginx的日志,一般还是保留为宜!
这过滤脚本太鸡肋了,事后读取nginx log来查记录有什么用?
读取log是为了做到实时性的!