使用 ipset 強化 iptables 的IP管理
自從「 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