面對大量惡意請求(如暴力破解 wp-login、CC 攻擊),透過分析 Nginx/Apache 存取日誌,自動識別高頻異常 IP 並加入 iptables 封鎖,是低成本有效的應急防禦手段。
mkdir -p /opt/scripts
vi /opt/scripts/block_attack_ips.sh
#!/bin/bash
# 封鎖高頻攻擊 IP 腳本
# 作者:參考社區優化版
# 用途:分析 access.log,自動封鎖異常 IP
# ===== 配置區 =====
LOGFILES=(
"/var/log/nginx/site1_access.log"
"/var/log/nginx/site2_access.log"
)
# 白名單:從 last 取得近期登入 IP,避免誤封自己
WHITELIST=$(last | awk '{print $3}' | grep -E '^[0-9]' | sort -u | xargs)
# 閾值設定
POST_LOGIN_THRESHOLD=100 # wp-login.php 10000筆中超過100次
POST_COMMENT_THRESHOLD=100 # wp-comments-post.php 同
ALL_REQUEST_THRESHOLD=1000 # 全站 10000筆中超過1000次
TAIL_LINES=10000 # 分析最近多少行
# ====================
check_root() {
if [[ $EUID -ne 0 ]]; then
echo "ERROR: This script must run as root"
exit 1
fi
}
block_ips() {
local blacklist=("$@")
if [[ ${#blacklist[@]} -eq 0 ]]; then return; fi
for ip in "${blacklist[@]}"; do
# 跳過白名單
if echo "$WHITELIST" | grep -wq "$ip"; then
echo "SKIP: $ip in whitelist"
continue
fi
# 檢查是否已封鎖
if iptables-save | grep -wq "$ip"; then
echo "SKIP: $ip already blocked"
continue
fi
echo "BLOCK: $ip"
iptables -I INPUT -s "$ip"/32 -p tcp -m tcp --dport 80 -j DROP
iptables -I INPUT -s "$ip"/32 -p tcp -m tcp --dport 443 -j DROP
done
}
analyze_log() {
local logfile="$1"
[[ ! -f "$logfile" ]] && { echo "WARN: $logfile not found"; return; }
# 1. 針對登入頁
local cmd="grep -w POST '$logfile' | tail -n $TAIL_LINES | grep -w 'wp-login.php' | awk '{print \$1}' | sort | uniq -c | awk '(\$1 > $POST_LOGIN_THRESHOLD){print \$2}'"
local blacklist=($(eval "$cmd"))
block_ips "${blacklist[@]}"
# 2. 針對留言頁
cmd="grep -w POST '$logfile' | tail -n $TAIL_LINES | grep -w 'wp-comments-post.php' | awk '{print \$1}' | sort | uniq -c | awk '(\$1 > $POST_COMMENT_THRESHOLD){print \$2}'"
blacklist=($(eval "$cmd"))
block_ips "${blacklist[@]}"
# 3. 全站總請求
cmd="tail -n $TAIL_LINES '$logfile' | awk '{print \$1}' | sort | uniq -c | awk '(\$1 > $ALL_REQUEST_THRESHOLD){print \$2}'"
blacklist=($(eval "$cmd"))
block_ips "${blacklist[@]}"
}
main() {
check_root
for logfile in "${LOGFILES[@]}"; do
analyze_log "$logfile"
done
}
main "$@"
chmod +x /opt/scripts/block_attack_ips.sh
vi /etc/crontab
# 加入:
*/5 * * * * root /opt/scripts/block_attack_ips.sh >> /var/log/block_attack_ips.log 2>&1
# 每天凌晨 1 點重置 iptables(避免規則過多影響效能,視需求決定)
0 1 * * * root /etc/init.d/iptables restart
或使用 crontab -e(root 身分):
*/5 * * * * /opt/scripts/block_attack_ips.sh >> /var/log/block_attack_ips.log 2>&1
0 1 * * * /sbin/iptables -F && /sbin/iptables-save > /etc/sysconfig/iptables
/opt/scripts/whitelist.txt,包含辦公室 IP、監控伺服器、CDN 回源 IP。/etc/sysconfig/iptables 或使用 ipset 管理大量 IP。
# 手動執行測試
/opt/scripts/block_attack_ips.sh
# 查看封鎖規則
iptables -L INPUT -n -v | grep DROP
# 模擬攻擊測試(另一台機器)
for i in {1..200}; do curl -s https://target_ip/wp-login.php; done
# 等待 5 分鐘後檢查是否被封鎖
X-Forwarded-For 或使用 CDN 官方防護。ipset。此方案適合中小型站點作為輕量級應急防禦。長期運維建議導入 WAF(ModSecurity、OpenResty+Lua)、CDN 防護或專業抗 DDoS 服務,構建多層次防禦體系。