每分鐘掃描 HTTP (80 埠) 連線狀態,偵測單一 IP 連線數超過閾值 (預設 100) 者,自動加入 iptables REJECT 規則,並記錄歷史封鎖清單。
#!/bin/bash
# 自動封鎖高併發攻擊 IP
# 部署:寫入 /root/block_high_conn.sh,chmod +x,加入 crontab */1 * * * *
THRESHOLD=100 # 連線數閾值
PORT=80 # 監控埠
LOG_FILE="/root/block_high_conn.log"
HISTORY_FILE="/root/blocked_ips_history.txt"
CHAIN_NAME="ATTACK_BLOCK"
# 建立專用鏈 (避免污染 INPUT 鏈)
iptables -N $CHAIN_NAME 2>/dev/null
iptables -C INPUT -p tcp --dport $PORT -j $CHAIN_NAME 2>/dev/null || \
iptables -I INPUT -p tcp --dport $PORT -j $CHAIN_NAME
# 取得當前連線數前 10 名 IP
netstat -ant | awk -v port=":$PORT " '$4 ~ port {split($5,a,":"); print a[1]}' | \
sort | uniq -c | sort -nr | head -10 | while read count ip; do
if [ "$count" -gt "$THRESHOLD" ]; then
# 檢查是否已封鎖
if ! iptables -C $CHAIN_NAME -s $ip -j REJECT 2>/dev/null; then
iptables -A $CHAIN_NAME -s $ip -j REJECT
echo "$(date '+%F %T') BLOCK $ip (conn=$count)" >> $LOG_FILE
echo "$ip" >> $HISTORY_FILE
fi
fi
done
# 可選:清理超過 24 小時的封鎖 (防誤封正常爬蟲)
# find $HISTORY_FILE -mmin +1440 -exec ...
| 原版問題 | 優化版改進 |
|---|---|
| 固定只處理前 3 筆 | 動態處理前 10 筆,覆蓋更多攻擊源 |
| 重複 `awk`/`sed` 管線,效能差 | 單一 `awk` 管線完成解析、排序、去重 |
| 無專用鏈,污染 INPUT | 建立 `ATTACK_BLOCK` 鏈,便於管理/清理/審計 |
| 無日誌、無歷史記錄 | 雙重日誌:即時操作日誌 + 歷史 IP 清單 |
| 無白名單機制 | 可擴展:啟動時載入 `/root/whitelist.txt` 排除 |
單一 `iptables` 腳本可作為**輕量級第一道防線**,適合無法部署 WAF/IDS/IPS 的 VPS/小型環境。生產環境建議疊加:雲端 WAF (Cloudflare/AWS Shield) → 邊界防火牆 → 主機端 `fail2ban`/`iptables` → 應用層限流。纵深防禦,單點不敗。