nginx+iptables+ipset 封禁頻繁訪問web服務的惡意IP
說明
轉載來源–> https://blog.csdn.net/qq_36698956/article/details/90447648
iptables直接針對ip進行封禁,在ip數量不大的時候是沒什麼問題的,但當有大量ip的時候性能會嚴重下降,iptables是O(N)的性能。而ipset就像一個集合,把需要封閉的ip地址寫入這個集合中,ipset 是O(1)的性能,可以有效解決iptables直接封禁大量IP的性能問題。
安裝配置
-
如果是RedHat/CentOS,首先用yum(Ubuntu/Debian用將yum換爲apt-get既可 )安裝ipset。
yum install ipset -y
-
ipset創建基於ip hash的集合名稱,例如blacklist,timeout 3600 表示封禁3600s; iptables開啓封禁80,443策略
ipset create blacklist hash:ip timeout 3600 # 當然也可以不加timeout 3600 ,也可以只寫ipset create blacklist hash:ip , blacklist 爲集合名稱,可隨意, 不加就是長期封閉 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 # iptables v1.4.7: multiport expection an option # 如果報上面的錯誤,需要按如下寫 -A INPUT -p tcp -m multiport --destination-port 443,80 -m set --match-set blocklist src -j DROP
-
基於自定義訪問頻率閾值或者請求敏感關鍵字來創建自動篩選惡意IP的腳本/data/iptables_ipset_deny.sh。
py腳本
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import os
import time
threshold = 120
# 獲取前1分鐘的時間
date=time.strftime('%Y:%H:%M', time.localtime(time.time()-60))
# date = time.strftime('%Y:%H:%M')
filename = '/usr/share/nginx/logs/xx.access.log '
def popen(command):
return os.popen(command).readlines()
def main():
with open('/tmp/ipset.txt', 'a') as f:
f.write('%s: 日誌搜索...........\n' % (date))
command = "grep %s %s | awk '{counts[$1]++}; END {for(url in counts) print counts[url], url}'" % (date, filename)
for ip in popen(command):
num, ipaddr = ip.split(' ')
num, ipaddr = int(num), ipaddr.strip() # 第一個值是整型, 第二個值應當去掉空格
if num >= threshold:
if all(popen('ipset list | grep %s' % (ipaddr))): # 如果不爲true 那就添加
f.write('每分鐘大於%s次 地址: %s 將被禁止訪問\n' % (threshold, ipaddr))
os.system('/usr/sbin/ipset add blacklist %s &>/dev/null' %(ipaddr))
# popen('ipset add blacklist %s' % (ipaddr))
elif num >= 10:
f.write('訪問次數 %s: %s\n' % (num, ipaddr))
f.write('日誌搜索結束.................\n\n\n')
if __name__ == '__main__':
main()
-
用crontab定時啓動腳本。
echo "* * * * * bash /data/iptables_ipset_deny.sh" >> /etc/crontab # 當然也可以配置crontab一分鐘執行一次定時任務: */1 * * * * bash /data/iptables_ipset_deny.sh
-
查看black地址
ipset list
- 刪除地址
~]# ipset del ipsetname 地址