iptables 简介
我们使用iptables工具实现功能
iptables 是 Linux 系统上最常用的防火墙工具,可以指定策略。
Shell文件创建
vim /usr/local/bin/auto_block_ip.sh
我的目标是每10分钟自动扫描,再10分钟内一个IP访问50次以上就就封禁1天。时间到了后再自动放出来。
第一步 定义部分参数
BAN_IPSET="malicious_ips" # ipset集合名称
SCAN_THRESHOLD=50 # 10分钟内访问50次触发封禁
BAN_DURATION=$((24*60*60)) # 封禁持续时间(秒),24小时
EXCLUDE_IPS="127.0.0.1 0.0.0.0 192.168.253.1" # 排除的IP列表
第二步 创建iptables规则
# 创建ipset集合(如果不存在)
if ! ipset list $BAN_IPSET >/dev/null 2>&1; then
ipset create $BAN_IPSET hash:ip timeout $BAN_DURATION
fi
# 添加iptables规则(如果不存在)
if ! iptables -C INPUT -m set --match-set $BAN_IPSET src -j DROP >/dev/null 2>&1; then
iptables -I INPUT -m set --match-set $BAN_IPSET src -j DROP
fi
第三步 添加IP检测和封禁机制
# 获取所有非排除IP的连接计数
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | grep -vE "$(echo $EXCLUDE_IPS | sed 's/ /|/g')" | uniq -c | \
while read count ip; do
# 检查是否超过阈值且未被封禁
if [ $count -gt $SCAN_THRESHOLD ] && ! ipset test $BAN_IPSET $ip >/dev/null 2>&1; then
# 封禁IP
ipset add $BAN_IPSET $ip timeout $BAN_DURATION
echo "$(date '+%Y-%m-%d %H:%M:%S') - 封禁IP: $ip (访问次数: $count)" >> /var/log/ip_block.log
fi
done
第四步 设置自动执行时间
# 设置定时任务
(crontab -l 2>/dev/null; echo "*/10 * * * * /usr/local/bin/auto_block_ip.sh") | crontab -
第五步 测试脚本功能以及脚本使用命令
# 给脚本执行权限
chmod +x /usr/local/bin/auto_block_ip.sh
# 手动测试脚本
/usr/local/bin/auto_block_ip.sh
# 查看封禁日志
tail -f /var/log/ip_block.log
# 查看当前封禁IP列表
ipset list $BAN_IPSET
# 手动解封IP
ipset del $BAN_IPSET IP地址
# 清空所有封禁
ipset flush $BAN_IPSET
# 删除整个ipset集合
ipset destroy $BAN_IPSE
附:
#!/bin/bash
# 配置参数
BAN_IPSET="malicious_ips"
SCAN_THRESHOLD=50
BAN_DURATION=$((24*60*60))
EXCLUDE_IPS="127.0.0.1 0.0.0.0 192.168.253.1"
# 创建ipset集合
if ! ipset list $BAN_IPSET >/dev/null 2>&1; then
ipset create $BAN_IPSET hash:ip timeout $BAN_DURATION
fi
# 添加iptables规则
if ! iptables -C INPUT -m set --match-set $BAN_IPSET src -j DROP >/dev/null 2>&1; then
iptables -I INPUT -m set --match-set $BAN_IPSET src -j DROP
fi
# 检测并封禁IP
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | grep -vE "$(echo $EXCLUDE_IPS | sed 's/ /|/g')" | uniq -c | \
while read count ip; do
if [ $count -gt $SCAN_THRESHOLD ] && ! ipset test $BAN_IPSET $ip >/dev/null 2>&1; then
ipset add $BAN_IPSET $ip timeout $BAN_DURATION
echo "$(date '+%Y-%m-%d %H:%M:%S') - 封禁IP: $ip (访问次数: $count)" >> /var/log/ip_block.log
fi
done