iptables封掉少量ip處理是沒什麼問題的,但是當有大量ip***的時候性能就跟不上了,iptables是O(N)的性能。而ipset就像一個集合,把需要封閉的ip地址放入這個集合中,ipset 是O(1)的性能,用的hash方式所以特別快。
一、軟件及安裝
1、iptables(一般linux都已經安裝好的)
2、ipset:
ubuntu:apt-get install ipset
二、ipset的使用
1、查看ip集的列表信息
ipset list
2、創建ip集
ipset create XXXX hash:ip maxelem 100000 timeout 3600
XXXX:ip集的名字
hash:ip :爲指定類型,還有其他好些類型,比如hash:net,hash:net,net等,具體可以man ipset
100000:爲最大保存ip的數量
timeout: 爲封閉ip的默認時間,這個參數可以不寫,這樣就永不解封,除非手動解封
3、增加ip地址到ip集
ipset add xxxx 1.1.1.1
增加網段
ipset add xxxx 1.1.1.0/24
4、刪除指定的ip或網段
ipset del xxxx 1.1.1.1 ipset del xxxx 1.1.1.0/24
5、保存ip集到文件
ipset save xxxx>ipset_list.txt
6、還原ip集
ipset restore <ipset_list.txt
三、自動封禁和解封
1、創建ip集
ipset create forbidip hash:ip timeout 172800
2、創建iptables條目
iptables -A INPUT -p tcp -m set --match-set forbidip src -m multiport --dports 443,80 -j DROP
或者
iptables -A INPUT -p tcp -m set --match-set forbidip src -m multiport -j DROP
3、根據條件判斷需要封閉的ip
條件:在上一分鐘的nginx的請求中,單一ip請求數超過1000及request_uri中包含passwd字符串的ip都直接封禁,1小時後自動解禁。腳本如下
#!/bin/bash FILES="/data/nginx_log/xxxxx/access.log" DATE=`date -d '1 minutes ago' +%Y:%H:%M` grep ${DATE} ${FILES}|awk -F'|' '{print $3}'|sort -n|uniq -c |sort -nr|head -1>/tmp/ips grep ${DATE} ${FILES}|grep -i passwd|awk -F'|' '{print $3}'|sort -n|uniq>/tmp/ippwd NUM=`awk '{print $1}' /tmp/ips` IP=`awk '{print $2}' /tmp/ips` IP2=`cat /tmp/ippwd` threshold=1000 if [[ $NUM -gt $threshold ]];then /sbin/ipset -! add forbidip $IP timeout 3600 fi if [ -s /tmp/ippwd ];then for i in $IP2 do /sbin/ipset -! add forbidip $i done fi
4、腳本自動運行
在crontab中添加此腳本的自動運行
*/1 * * * * bash /path/to/script.sh