在使用亿安云这种提供多出口 IP 的 VPS 时,出口 IP 会动态变化。如果需要将这些 IP 添加到 IX(Internet Exchange)的白名单中,手动跟踪显然不现实。因而写了两个轻量 Shell 脚本,实现出口 IP 的自动记录便捷查看


一、使用环境

项目 说明
云服务商 亿安云(多出口 IP 方案)
操作系统 Linux(推荐 Debian / Ubuntu / CentOS)
依赖 curlbashsedgrep
用途 持续追踪出口 IP,提取活跃 IP 列表后添加到 IX 白名单

亿安云的多出口 IP 特性意味着你的 VPS 出口 IP 会在一个 IP 池中轮换。对于需要将出口 IP 加入白名单的场景(如野草云 IX),你需要知道当前活跃的所有出口 IP,并在 IP 发生变化时及时更新白名单。

整体思路:

1
2
3
4
5
ip-tracker.sh(后台持续运行,每60秒检测一次出口IP并记录)
↓ 数据写入
outbound_ips.txt(IP + 时间戳)
↓ 数据读取
view-ips.sh(分类显示活跃IP和过期IP,活跃IP可直接复制到白名单)

二、脚本源代码

2.1 ip-tracker.sh — 出口 IP 记录器

这个脚本以后台守护进程方式运行,每隔 60 秒通过 curl ip.sb 检测当前出口 IP,并将结果写入本地数据文件。

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
#!/bin/bash

# 配置
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
DATA_FILE="$SCRIPT_DIR/outbound_ips.txt"
INTERVAL=60 # 检测间隔(秒)

# 数据格式: IP<TAB>最后获取时间

# 创建文件(如果不存在)
touch "$DATA_FILE"

echo "出口IP记录器已启动"
echo "数据文件: $DATA_FILE"
echo "检测间隔: ${INTERVAL}秒"

# 获取IP的函数
fetch_ip() {
curl -4 -s --max-time 10 ip.sb 2>/dev/null
}

# 主循环
while true; do
IP=$(fetch_ip)
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

if [ -n "$IP" ]; then
# 检查IP是否已存在(兼容旧格式无时间戳和新格式有时间戳)
if grep -qE "^${IP}( |$)" "$DATA_FILE" 2>/dev/null; then
# 更新已有IP的时间戳(同时处理旧格式和新格式)
sed -i -E "s|^${IP}(\t.*)?$|${IP}\t${TIMESTAMP}|" "$DATA_FILE"
echo "[$TIMESTAMP] IP已存在,更新时间: $IP"
else
echo -e "${IP}\t${TIMESTAMP}" >> "$DATA_FILE"
echo "[$TIMESTAMP] 新IP: $IP"
fi
else
echo "[$TIMESTAMP] 获取IP失败"
fi

sleep $INTERVAL
done

核心逻辑:

  • 每 60 秒调用 curl -4 -s --max-time 10 ip.sb 获取当前出口 IP
  • 如果 IP 已存在于数据文件中,更新其最后获取时间
  • 如果是新 IP,追加一条新记录
  • 数据格式为 IP<TAB>时间戳,例如:203.0.113.42 2026-03-27 14:30:00

2.2 view-ips.sh — IP 查看器

这个脚本读取记录文件,按时间将 IP 分为活跃(7 天内获取过)和过期两类,方便你快速获取需要加入白名单的 IP 列表。

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/bin/bash

# 配置
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
DATA_FILE="$SCRIPT_DIR/outbound_ips.txt"
EXPIRE_DAYS=7

if [ ! -f "$DATA_FILE" ]; then
echo "数据文件不存在: $DATA_FILE"
exit 1
fi

# 7天前的时间戳(秒)
THRESHOLD=$(date -d "-${EXPIRE_DAYS} days" '+%s' 2>/dev/null)
if [ -z "$THRESHOLD" ]; then
# macOS 兼容
THRESHOLD=$(date -v-${EXPIRE_DAYS}d '+%s' 2>/dev/null)
fi

ACTIVE_IPS=()
EXPIRED_IPS=()
EXPIRED_DETAILS=()

while IFS=$'\t' read -r IP LAST_SEEN; do
[ -z "$IP" ] && continue

if [ -n "$LAST_SEEN" ]; then
# 转换最后获取时间为秒
LAST_EPOCH=$(date -d "$LAST_SEEN" '+%s' 2>/dev/null)
if [ -z "$LAST_EPOCH" ]; then
# macOS 兼容
LAST_EPOCH=$(date -j -f '%Y-%m-%d %H:%M:%S' "$LAST_SEEN" '+%s' 2>/dev/null)
fi

if [ -n "$LAST_EPOCH" ] && [ "$LAST_EPOCH" -lt "$THRESHOLD" ]; then
EXPIRED_IPS+=("$IP")
EXPIRED_DETAILS+=("$IP $LAST_SEEN")
else
ACTIVE_IPS+=("$IP")
fi
else
# 旧格式数据(无时间戳),视为活跃
ACTIVE_IPS+=("$IP")
fi
done < "$DATA_FILE"

echo "=== 活跃出口IP列表 (${EXPIRE_DAYS}天内) ==="
echo ""

if [ ${#ACTIVE_IPS[@]} -gt 0 ]; then
# 去重、排序、用逗号分隔
printf '%s\n' "${ACTIVE_IPS[@]}" | sort -u | tr '\n' ',' | sed 's/,$//'
echo ""
else
echo "(无)"
fi

echo ""
echo "=== 统计信息 ==="
echo "活跃IP数: ${#ACTIVE_IPS[@]}"
echo "过期IP数: ${#EXPIRED_IPS[@]}"
echo "总IP数: $(( ${#ACTIVE_IPS[@]} + ${#EXPIRED_IPS[@]} ))"

if [ ${#EXPIRED_IPS[@]} -gt 0 ]; then
echo ""
echo "=== 已忽略IP (超过${EXPIRE_DAYS}天未获取) ==="
printf '%-18s %s\n' "IP地址" "最后获取时间"
printf '%-18s %s\n' "──────────────" "───────────────────"
for DETAIL in "${EXPIRED_DETAILS[@]}"; do
IP=$(echo "$DETAIL" | cut -f1)
TIME=$(echo "$DETAIL" | cut -f2)
printf '%-18s %s\n' "$IP" "$TIME"
done | sort
fi

核心逻辑:

  • 读取 outbound_ips.txt,按最后获取时间分类
  • 活跃 IP:7 天内被检测到的,以逗号分隔的格式输出(可直接复制粘贴到白名单)
  • 过期 IP:超过 7 天未出现的,显示详细信息供参考

三、部署 ip-tracker.sh 定时运行

推荐使用 systemd 将脚本注册为系统服务,这样它会在开机自启、崩溃自动重启。

3.1 上传脚本并赋予执行权限

1
2
3
4
5
6
# 创建目录
mkdir -p /opt/ip-tracker

# 上传脚本后赋予执行权限
chmod +x /opt/ip-tracker/ip-tracker.sh
chmod +x /opt/ip-tracker/view-ips.sh

3.2 创建 systemd 服务文件

创建 /etc/systemd/system/ip-tracker.service

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=Outbound IP Tracker
After=network.target

[Service]
Type=simple
ExecStart=/opt/ip-tracker/ip-tracker.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

注意: ExecStart 的路径需要与脚本的实际路径一致。示例中使用的是 /opt/ip-tracker/ip-tracker.sh,请根据实际情况修改。

3.3 启动服务

1
2
3
4
5
6
7
8
9
10
11
# 重载 systemd 配置
systemctl daemon-reload

# 启动服务
systemctl start ip-tracker

# 设置开机自启
systemctl enable ip-tracker

# 查看运行状态
systemctl status ip-tracker

3.4 查看运行日志

1
2
3
4
5
# 查看实时日志
journalctl -u ip-tracker -f

# 查看最近 100 行日志
journalctl -u ip-tracker -n 100

正常运行后,日志输出类似:

1
2
3
4
5
6
出口IP记录器已启动
数据文件: /opt/ip-tracker/outbound_ips.txt
检测间隔: 60秒
[2026-03-27 14:30:00] 新IP: 203.0.113.42
[2026-03-27 14:31:00] IP已存在,更新时间: 203.0.113.42
[2026-03-27 14:32:00] 新IP: 198.51.100.7

四、使用 view-ips.sh 查看 IP 地址

运行一段时间后,就可以用查看脚本获取活跃 IP 列表了。

4.1 基本用法

1
2
cd /opt/ip-tracker
./view-ips.sh

输出示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
=== 活跃出口IP列表 (7天内) ===

198.51.100.7,203.0.113.42,203.0.113.88

=== 统计信息 ===
活跃IP数: 3
过期IP数: 1
总IP数: 4

=== 已忽略IP (超过7天未获取) ===
IP地址 最后获取时间
────────────── ───────────────────
192.0.2.15 2026-03-15 09:12:33

4.2 配置调整

如需修改检测间隔或过期天数,编辑脚本顶部的配置项:

脚本 配置项 默认值 说明
ip-tracker.sh INTERVAL 60 IP 检测间隔(秒)
view-ips.sh EXPIRE_DAYS 7 活跃 IP 判定天数

五、数据文件说明

脚本运行后会在同目录下生成 outbound_ips.txt,格式如下:

1
2
3
4
203.0.113.42	2026-03-27 14:30:00
198.51.100.7 2026-03-27 14:32:00
203.0.113.88 2026-03-26 10:15:00
192.0.2.15 2026-03-15 09:12:33

每行一个 IP,以 Tab 分隔 IP 地址和最后获取时间。该文件可手动编辑,也可以直接删除后由脚本自动重新创建。


总结

步骤 操作
1 上传两个脚本到 /opt/ip-tracker/,赋予执行权限
2 创建 systemd 服务,启动 ip-tracker.sh 并设置开机自启
3 运行 view-ips.sh 获取逗号分隔的活跃 IP 列表
4 将活跃 IP 列表粘贴到 IX 白名单配置中
5 定期运行 view-ips.sh 检查是否有新 IP 出现,及时更新白名单

这样就能轻松应对亿安云多出口 IP 的动态变化,确保白名单始终是最新的。