封禁恶意IP访问在我司实践总结

1.需求分析

随着公司业务量的增长,有些人可能就会动些小心思搞你一下,爬虫或者恶意访问你,如何限制这些用户访问呢,今天做下总结,大体有三种方案:代码层面;http服务器(以nginx为例);服务器网络层面

2.代码层面:

就是编写代码统计单位时间内,用户访问的总次数,把访问比较频繁的挑出来,拒绝服务,比如代码中用redis,key是访问用户的ip地址,value是单位时间内访问次数,超过阈值,就给用户提示访问过于频繁,拒绝访问。但这种缺点很明显,就是有很多的代码开发量,对原有业务代码侵入性太强,所有实用价值我个人觉得不是太高。

详细了解可以参考这篇博文:

https://blog.csdn.net/qq_26545305/article/details/88219889

3.Nginx

这种方法的思路是,找到访问频繁的ip地址,然后将其加入禁止访问名单。

3.1查找服务器所有访问者ip方法:

awk '{print $1}' nginx_access.log |sort |uniq -c|sort -n

nginx.access.log 为nginx访问日志文件所在路径

会到如下结果,前面是ip的访问次数,后面是ip,很明显我们需要把访问次数多的ip并且不是蜘蛛的ip屏蔽掉,如下面结果,
若 66.249.79.84 不为蜘蛛则需要屏蔽:

     89 106.75.133.167
     90 118.123.114.57
     91 101.78.0.210
     92 116.113.124.59
     92 119.90.24.73
     92 124.119.87.204
     119 173.242.117.145
     4320 66.249.79.84

3.2 屏蔽IP的方法:

在nginx的安装目录下面,新建屏蔽ip文件,命名为guolv_ip.conf,以后新增加屏蔽ip只需编辑这个文件即可。
加入如下内容并保存:

deny 66.249.79.84 ; 

在nginx的配置文件nginx.conf中加入如下配置,可以放到http, server, location, limit_except语句块,需要注意相对路径,本例当中nginx.conf,guolv_ip.conf在同一个目录中。

include guolv_ip.conf; 

保存nginx.conf文件,然后测试现在的nginx配置文件是否是合法的:

nginx -t

如果配置没有问题,就会输出:

the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
configuration file /usr/local/nginx/conf/nginx.conf test is successful

如果配置有问题就需要检查下哪儿有语法问题,如果没有问题,需要执行下面命令,重载 nginx 配置文件:

service nginx  reload

3.3 注意:

屏蔽ip的配置文件既可以屏蔽单个ip,也可以屏蔽ip段,或者只允许某个ip或者某个ip段访问。

//屏蔽单个ip访问

deny IP; 

//允许单个ip访问

allow IP; 

//屏蔽所有ip访问

deny all; 

//允许所有ip访问

allow all; 

//屏蔽整个段即从123.0.0.1到123.255.255.254访问的命令

deny 123.0.0.0/8

//屏蔽IP段即从123.45.0.1到123.45.255.254访问的命令

deny 124.45.0.0/16

//屏蔽IP段即从123.45.6.1到123.45.6.254访问的命令

deny 123.45.6.0/24

//如果你想实现这样的应用,除了几个IP外,其他全部拒绝,
//那需要你在guolv_ip.conf中这样写

allow 1.1.1.1; 
allow 1.1.1.2;
deny all; 

单独网站屏蔽IP的方法,把include guolv_ip.conf; 放到网址对应的在server{}语句块,
所有网站屏蔽IP的方法,把include guolv_ip.conf; 放到http {}语句块。

可以看到这种方式,已经比写代码实现方便了很多,对业务层面无侵入性,但是还有问题,就是不够智能,必须有人手动指定某些ip可以访问或者禁止访问才行,有没有更好的方式呢,大杀器——ipsets

4.ipset

ipset是iptables的扩展,iptables可以直接针对ip进行封禁,在ip数量不大的时候是没什么问题的,但当有大量ip的时候性能会严重下降,iptables是O(N)的性能。而ipset就像一个集合,把需要封闭的ip地址写入这个集合中,ipset 是O(1)的性能,可以有效解决iptables直接封禁大量IP的性能问题。下面介绍使用:

4.1 安装

如果是RedHat/CentOS,首先用yum(Ubuntu/Debian用将yum换为apt-get既可 )安装ipset。

yum install ipset -y

4.2 创建封禁策略

ipset创建基于ip hash的集合名称,例如blacklist,timeout 3600 表示封禁3600s;  iptables开启封禁80,443策略。

ipset create blacklist hash:ip timeout 3600
iptables -A INPUT -p tcp -m set --match-set blacklist src -m multiport --dports 443,80 -j DROP

当然,也可以封禁黑名单IP的所有请求。

iptables -I INPUT -p tcp -m set --match-set blacklist src -m multiport -j DROP

4.3 定义脚本自动筛选

基于自定义访问频率阈值或者请求敏感关键字来创建自动筛选恶意IP的脚本/data/iptables_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
  1. 用crontab定时启动脚本。
echo "* * * * * bash /data/iptables_ipset_deny.sh" >> /etc/crontab

可以参考:https://github.com/firehol/blocklist-ipsets

猜你喜欢

转载自blog.csdn.net/u014532775/article/details/93123706
今日推荐