简单粗暴的给你FPR服务限制地区访问,其他同理
2024-02-07 02:23:46
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/bin/bash

# FRP 容器名称
CONTAINER_NAME="frps"
# ipinfo.io 的 API 令牌
IPINFO_TOKEN="你的令牌。每个月能免费使用50K额度,基本够了"
# 目标地区
TARGET_REGION="Sichuan"
# 缓存文件路径
CACHE_FILE="/opt/banIP/ip_region_cache.txt"

# 函数:检查 IP 是否为特殊或保留地址
is_special_ip() {
local ip=$1
if [[ $ip =~ ^(0\.|127\.|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|169\.254\.|::1|fc00::|fe80::) ]]; then
return 0
else
return 1
fi
}

# 函数:从缓存获取 IP 地区
get_region_from_cache() {
local ip=$1
grep "^$ip," $CACHE_FILE | cut -d ',' -f2
}

# 函数:将 IP 地区保存到缓存
save_region_to_cache() {
local ip=$1
local region=$2
echo "$ip,$region" >> $CACHE_FILE
}

docker logs "$CONTAINER_NAME" 2>&1 | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | sort -u | while read -r ip; do
if is_special_ip "$ip"; then
echo "Skipping special or reserved IP: $ip"
continue
fi

# 尝试从缓存获取地区
region=$(get_region_from_cache "$ip")
if [ -z "$region" ]; then
# 缓存中没有找到,使用API查询
region=$(curl -s "https://ipinfo.io/${ip}/region?token=$IPINFO_TOKEN")
save_region_to_cache "$ip" "$region"
fi

echo "IP: $ip, Region: $region"

if [[ "$region" != *"$TARGET_REGION"* ]]; then
echo "Blocking IP: $ip, as it is not in $TARGET_REGION"
# 使用 ufw 屏蔽该 IP
ufw deny from "$ip" to any
fi
done

步骤 1: 创建脚本文件

首先,首先创建一个 /opt/banIP 目录。

1
mkdir -p /opt/banIP

然后,创建脚本文件:

1
nano /opt/banIP/block_non_sichuan_ips.sh

将之前提供的脚本内容粘贴进去,确保替换了 为你的实际 ipinfo.io API 令牌。保存并退出编辑器。

再创建一个缓存目录

1
touch /opt/banIP/ip_region_cache.txt

如果你自定义了目录请注意脚本的中目录是否一致

步骤2设置一个定时运行

1
chmod +x /opt/banIP/block_non_sichuan_ips.sh
1
crontab -e
1
0 * * * * /opt/banIP/block_non_sichuan_ips.sh >> /opt/banIP/block_ips.log 2>&1
  1. 这条 crontab 配置的意思是:

    • 0 分钟时执行,即每个小时的开始。

    • * * * * 表示每小时、每天、每月、每周的任何时间。

    • /opt/banIP/block_non_sichuan_ips.sh 指定脚本的路径。

    • >> /opt/banIP/block_ips.log 2>&1 意味着将标准输出和错误输出都重定向到日志文件。

  2. 保存并退出编辑器: 保存更改并退出编辑器。crontab 服务会自动加载这个新的定时任务。

注意脚本创建成功后自己执行一次,看是否成功