以下是一个用于自动屏蔽频繁访问网站的恶意IP的Shell脚本,通过分析Web服务器(如Nginx/Apache)的访问日志并结合iptables实现实时防护:
脚本功能
1、监控Web访问日志,检测短时间内高频访问的IP
2、自动将恶意IP加入iptables黑名单
3、支持自定义检测阈值、封锁时间和日志路径
4、避免重复封锁IP,记录操作日志
脚本代码
#!/bin/bash
# 自动屏蔽高频访问IP的防护脚本
# 配置参数
LOG_FILE="/var/log/nginx/access.log" # 访问日志路径
THRESHOLD=100 # 触发封锁的请求次数阈值
TIME_WINDOW=60 # 检测时间窗口(秒)
BAN_TIME=3600 # 封锁时长(秒)
WHITELIST=("127.0.0.1" "192.168.1.1") # IP白名单
FIREWALL_CMD="iptables" # 防火墙命令(可选ipset)
# 日志与临时文件
LOG_DIR="/var/log/iptables_blocker"
BLOCK_LOG="$LOG_DIR/blocked_ips.log"
TMP_IP_LIST="/tmp/block_ips.txt"
# 创建日志目录
mkdir -p "$LOG_DIR"
# 函数:检查是否为有效IPv4地址
is_valid_ip() {
local ip=$1
local stat=1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
IFS='.' read -ra ip_parts <<< "$ip"
[[ ${ip_parts[0]} -le 255 && ${ip_parts[1]} -le 255 && \
${ip_parts[2]} -le 255 && ${ip_parts[3]} -le 255 ]]
stat=$?
fi
return $stat
}
# 函数:检查IP是否在白名单
is_whitelisted() {
local ip=$1
for allowed_ip in "${WHITELIST[@]}"; do
[[ "$ip" == "$allowed_ip" ]] && return 0
done
return 1
}
# 主检测逻辑
detect_and_block() {
# 获取当前时间(时间戳格式)
current_time=$(date +%s)
# 分析最近TIME_WINDOW秒内的日志,提取访问量超阈值的IP
awk -v window="$TIME_WINDOW" -v now="$current_time" '
{
# 解析日志时间(假设日志时间格式为[05/Oct/2023:14:30:22 +0800])
gsub(/\[/, "", $4);
log_time = substr($4, 1, 20);
cmd = "date -d \"" log_time "\" +%s";
cmd | getline timestamp;
close(cmd);
if (now - timestamp <= window) {
print $1;
}
}' "$LOG_FILE" | sort | uniq -c | awk -v threshold="$THRESHOLD" '$1 > threshold {print $2}' > "$TMP_IP_LIST"
# 处理每个待屏蔽IP
while read ip; do
if is_valid_ip "$ip" && ! is_whitelisted "$ip"; then
# 检查是否已封锁
if ! $FIREWALL_CMD -C INPUT -s "$ip" -j DROP 2>/dev/null; then
# 添加iptables规则
$FIREWALL_CMD -A INPUT -s "$ip" -j DROP
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 屏蔽IP: $ip" >> "$BLOCK_LOG"
# 设置自动解封(可选)
echo "$FIREWALL_CMD -D INPUT -s "$ip" -j DROP" | at now + "$BAN_TIME" minutes 2>/dev/null
fi
fi
done < "$TMP_IP_LIST"
}
# 执行检测
detect_and_block
# 清理临时文件
rm -f "$TMP_IP_LIST"
使用说明
1、配置参数
修改 LOG_FILE 为你的Web服务器访问日志路径(支持Nginx/Apache)
调整 THRESHOLD 和 TIME_WINDOW 定义触发条件(如60秒内100次请求)
在 WHITELIST 中添加需豁免的IP(如管理服务器IP)
2、脚本权限
chmod +x ip_blocker.sh
sudo ./ip_blocker.sh # 需要root权限运行
3、定时任务
通过crontab每5分钟执行一次:
*/5 * * * * root /path/to/ip_blocker.sh
4、查看封锁记录
tail -f /var/log/iptables_blocker/blocked_ips.log
扩展功能
1. 使用ipset提升性能(应对大量IP)
# 创建ipset集合
ipset create block_list hash:ip timeout 3600
# 修改脚本中的防火墙规则
FIREWALL_CMD="iptables -m set --match-set block_list src"
ipset add block_list $ip
2. 邮件/钉钉告警
# 在屏蔽IP时发送通知
echo "检测到恶意IP: $ip,已自动封锁" | \
mail -s "安全告警" admin@example.com
# 钉钉机器人通知(需替换WEBHOOK_URL)
WEBHOOK_URL="https://oapi.dingtalk.com/robot/send?access_token=xxx"
curl -s "$WEBHOOK_URL" -H 'Content-Type: application/json' -d "{
'msgtype': 'text',
'text': {'content': '封锁恶意IP: $ip'}
}"
3. 自动解封
# 使用at命令在BAN_TIME分钟后自动解封
echo "iptables -D INPUT -s $ip -j DROP" | at now + "$BAN_TIME" minutes
注意事项
1、日志格式适配
脚本假设日志时间格式为 [05/Oct/2023:14:30:22 +0800],如格式不同需调整awk解析逻辑。
2、性能优化
对于高流量网站,建议使用 ipset 或 fail2ban 替代直接操作iptables。
3、误封风险
阈值设置需结合业务场景,避免误封CDN或搜索引擎IP。
4、防火墙规则持久化
iptables规则重启后会丢失,需使用 iptables-save 保存:
iptables-save > /etc/iptables/rules.v4
5、法律合规
确保符合当地法律法规,禁止未授权扫描和封锁。
通过此脚本,您可以有效防御CC攻击、爬虫高频请求等恶意行为,保障Web服务的稳定性。建议结合其他安全措施(如WAF)构建多层防护体系。