寫一個 shell 腳本,創建腳本文件?/usr/local/bin/check_conn.sh
#!/bin/bash
if [[ $EUID -ne 0 ]]; thenecho "This script must be run as root." >&2exit 1
fi
# 連接數閾值
THRESHOLD=50# 白名單 IP(空格分隔)
WHITELIST_IPS="0.0.0.0 127.0.0.1"# 日志文件
ABUSE_LOG="/var/log/conn_abuse.log"# 封禁時間(秒)
BAN_TIME=86400# 獲取當前時間戳
NOW=$(date +%s)echo "[$(date '+%Y-%m-%d %H:%M:%S')] iptables 定時任務執行" >> "$ABUSE_LOG"# 統計連接數
netstat -ant | awk '{print $5}' | cut -d: -f1 | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | \sort | uniq -c | sort -nr | while read count ip; doecho "$ip $count"# 過濾非法行或白名單 IP[[ ! "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] && continuefor white_ip in $WHITELIST_IPS; do[[ "$ip" == "$white_ip" ]] && continue 2done# 判斷是否超過閾值if [[ "$count" -gt "$THRESHOLD" ]]; then# 檢查是否已被封禁sudo iptables -L -n --line-numbers | grep "$ip"| grep DROP 2>/dev/nullif [[ $? -ne 0 ]]; thenecho "[$(date '+%Y-%m-%d %H:%M:%S')] Blocking $ip with $count connections" >> "$ABUSE_LOG"echo "----$ip--------$count"# 添加 iptables 封禁sudo iptables -I INPUT -s "$ip" -j DROP && echo "[debug]INPUT drop success for $ip" >> "$ABUSE_LOG"sudo iptables -I FORWARD -s "$ip" -j DROP && echo "[debug]FORWARD drop success for $ip" >> "$ABUSE_LOG"sudo iptables -I OUTPUT -d "$ip" -j DROP && echo "[debug]OUTPUT drop success for $ip" >> "$ABUSE_LOG"# 強制斷開現有連接(使用 conntrack 工具)if command -v conntrack &>/dev/null; thenconntrack -D -s "$ip" && echo "[debug]conntrack -D -s $ip" >> "$ABUSE_LOG"conntrack -D -d "$ip" && echo "[debug]conntrack -D -d $ip" >> "$ABUSE_LOG"fi# 設置定時任務自動解封echo "sudo iptables -D INPUT -s $ip -j DROP; sudo iptables -D FORWARD -s $ip -j DROP; sudo iptables -D OUTPUT -d $ip -j DROP" | \at NOW + $((BAN_TIME / 60)) minutes 2>/dev/nullfifi
done
配合 cron
定時執行這個腳本:
*/2 * * * * /usr/local/bin/check_conn.sh
?腳本功能介紹
-
定義變量:設置連接數閾值(200)、白名單IP、日志路徑和封禁時間(24小時)。
-
統計連接數:使用
netstat
獲取所有TCP連接,提取遠程IP并統計連接數。 -
過濾白名單和本地IP:跳過白名單中的IP,并檢查IP格式的有效性。
-
封禁處理:若IP連接數超過閾值且未被封禁,則通過
iptables
封禁,并記錄日志。 -
斷開現有連接:使用
conntrack
強制終止現有連接(如果可用)。 -
自動解封:使用
at
命令在封禁時間后移除iptables
規則。