what for ...
用 docker 搭建了一个frp,但最近发现有很多不明 IP 的访问,不胜其扰,编个脚本 block 这些 IP。
how to ...
写一个 shell 脚本 block-ip.sh,从 docker 日志中获取 IP 地址,如果是中国的地址则不拦截,不是中国的地址且不在 iptables 中的则实施拦截。为了监控 log 变更,还需要使用 inotify-tools 中的 inotifywait。
#!/bin/bash
# 启动 docker logs -f 命令,并将日志输出重定向到临时文件
docker logs -f frps > /tmp/docker_logs.txt 2>/dev/null &
# 检查 docker logs 命令是否成功启动
if [ $? -ne 0 ]; then
echo "无法启动 docker logs 命令。"
exit 1
fi
# 获取 docker logs 命令的进程 ID
docker_logs_pid=$!
# 函数:清理环境
cleanup() {
echo "运行结束,正在清理..."
kill -9 $docker_logs_pid 2>/dev/null
rm -f /tmp/docker_logs.txt 2>/dev/null
exit 1
}
# 捕获 Ctrl+C 信号
trap cleanup INT
# 日志函数,输出到终端和文件
LOG_FILE="/var/log/block_ip.log"
log() {
local msg=$1
echo "$(date '+%F %T.%3N') $msg" | tee -a $LOG_FILE
}
log "开始运行..."
# 使用 inotifywait 监视临时文件的变化
while inotifywait -qq -e modify /tmp/docker_logs.txt; do
# 在文件发生变化时执行操作
# 获取最新的 Docker 日志中的 IP 地址
ip=$(tail -n 1 /tmp/docker_logs.txt | grep -oE '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})')
if [ -n "$ip" ] && [ "$ip" != "0.0.0.0" ]; then
# 检查 IP 地址是否已经存在于 iptables 规则中
is_existing=$(iptables -C DOCKER-USER -s $ip -j DROP 2>&1 | grep -o $ip)
if [ -n "$is_existing" ]; then
log "IP地址 $ip 已做拦截,无需重复添加。"
else
# 获取 IP 地址归属国家
ip_country=$(curl -s https://ipinfo.io/${ip}/country)
if [ "$ip_country" = "CN" ]; then
log "IP地址 $ip 属于中国,不进行拦截。"
else
iptables -I DOCKER-USER -s $ip -j DROP
log "IP地址 $ip 来自 $ip_country,添加到拦截规则。"
fi
fi
fi
done
用命令执行
nohup ./block-ip.sh > /dev/null 2>&1 &
# 可简写成
nohup ./block-ip.sh &> /dev/null &
and more ...
随着 blocked IP 越来越多,iptables 防火墙的效率降低,速度拖慢,隔一段时间有必要清理一波,毕竟很多 IP 都是尝试登录失败后不会来回头客了的。
#!/bin/bash
# 使用 awk 计数并删除规则
count=$(iptables-save | grep 'DOCKER-USER -s' | awk '
{
# 打印删除命令
gsub(/^-A/, "iptables -D")
print
# 执行删除命令
system($0)
# 增加计数器
count++
}
END {
# 输出计数器
print count
}')
# 输出删除的规则数量
echo -e "已删除:\n$count 条规则"
