iptables+ipset自動封閉和解封頻繁訪問web服務的惡意IP
轉載自https://blog.csdn.net/firehive/article/details/81260169
iptables直接針對ip進行封禁,在ip數量不大的時候是沒什麼問題的,但當有大量ip的時候效能會嚴重下降,iptables是O(N)的效能。而ipset就像一個集合,把需要封閉的ip地址寫入這個集合中,ipset 是O(1)的效能,可以有效解決iptables直接封禁大量IP的效能問題。
1. 如果是RedHat/CentOS,首先用yum(Ubuntu/Debian用將yum換為apt-get既可 )安裝ipset。
yum install ipset -y
2.ipset建立基於ip hash的集合名稱
例如 blacklist表示集合的名字是blacklist
hashsize 4096 表示初始值為4096個,如果滿了,這個 hash 會自動擴容為之前的兩倍。最大能儲存的數量是 maxelem指定的值;hashsize 的預設值是 1024
maxelem 1000000表示最大元素個數為100000 ,ipset預設值為65536
timeout 3600 表示封禁3600s;
iptables開啟封禁80,443策略。
ipset create blacklist hash:ip hashsize 4096 maxelem 1000000 timeout 3600 iptables -A INPUT -p tcp -m set --match-set blacklist src -m multiport --dports 443,80 -j DROP
如果我們不希望有過期時間,可以不加timeout這個引數
ipset create blacklist hash:ip
當然,也可以封禁黑名單IP的所有請求。
iptables -A INPUT -m set --match-set blacklist src -j DROP
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
4. 用crontab定時啟動指令碼。
echo "* * * * * bash /data/iptables_ipset_deny.sh" >> /etc/crontab
注意:在自己的實際操作過程中發現,寫好的從nginx中分析得到的黑名單ip指令碼加入到ipset中;如果是手動執行這個指令碼的話,是正常的,如果做成定時任務,就一直沒有成功,ipset中沒有新增ip;搗鼓了好半天,發現是需要指定ipset這個命令路徑在/usr/sbin下面,因此在指令碼中加上指令碼的完整路徑即可,如/usr/sbin/ipset add blacklist x.x.x.x
這裡需要了解/usr/sbin和/usr/bin的區別了:/sbin目錄下的命令通常只有管理員才可以執行,/bin下的命令管理員和一般的使用者都可以使用
ipset 命令
ipset create blacklist hash:ip,port hashsize 4096 maxelem 1000000 timeout 100 #加入集合
ipset del blacklist x.x.x.x # 從 blacklist 集合中刪除內容
ipset list blacklist # 檢視 blacklist 集合內容
ipset list # 檢視所有集合的內容
ipset flush blacklist # 清空 blacklist 集合
ipset flush # 清空所有集合
ipset destroy blacklist # 銷燬 blacklist 集合
ipset destroy # 銷燬所有集合
如ipset save blacklist > 1.txt # 輸出 banip 集合內容到1.txt
ipset save > 1.txt # 輸出所有集合內容到1.txt
ipset save blacklist # 輸出 blacklist 集合內容到標準輸出
ipset save # 輸出所有集合內容到標準輸出
ipset restore # 根據輸入內容恢復集合內容
如 ipset restore <1.txt # 根據1.txt內容恢復集合內容
service ipset save #執行 add,del 這類添刪操作後都需要儲存
service ipset restart #重啟ipset
ipset test blacklist x.x.x.x. #測試x.x.x.x.這個ip是否在blacklist集合中
其他關於ipset不錯的文章
Linux iptables 擴充套件 ipset 使用教程http://www.zhoutao.org/blog/2017/11/757.html
linux 基於ipset+iptables 保護api介面被暴力訪問https://blog.csdn.net/huliwho/article/details/80975549