block IP

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 条规则"

留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注