|
|
3 týždňov pred | |
|---|---|---|
| scripts | 3 týždňov pred | |
| substore | 3 týždňov pred | |
| .gitignore | 1 mesiac pred | |
| CLAUDE.md | 1 mesiac pred | |
| README.md | 3 týždňov pred | |
| build_router_package.sh | 1 mesiac pred | |
| config.local.json | 1 mesiac pred | |
| config.server.json | 3 týždňov pred | |
| config_router.conf | 3 týždňov pred | |
| workflow.md | 1 mesiac pred |
用于选择优选目标并产出运行时文件,支持三种模式:
runtime-state)cfst 模式(本机 cfst -> IP)sh + cfst -> IP + HTTP 暴露)核心脚本:
scripts/domain_updater.py:Python 主入口(api / cfst_local)scripts/run_update_and_commit.sh:服务器模式调度入口(含 git 同步)scripts/install_debian.sh / scripts/uninstall_debian.sh:systemd 安装/卸载scripts/router_local_update.sh:路由器更新入口(BusyBox sh)scripts/router_local_http.sh:路由器 HTTP 入口(BusyBox httpd)build_router_package.sh:路由器部署包打包脚本(生成 vmess.tar.gz)配置文件:
config.server.json:服务器模式config.local.json:本地 Python cfst 模式config_router.conf:BusyBox 路由器模式旧
config.json/config.example.json已废弃。
三种模式都围绕同类输出:
默认目录:
runtime/cfip_runtime/state.json 与 substore_vars.json 用途:
state.json:持久化上次可用值(如 last_good_domain / last_good_ip),用于失败时 fallback。substore_vars.json:给下游(如 Sub-Store)提供轻量变量(当前值、UPDATED_AT、STATUS),避免解析完整 runtime JSON。top_candidates 字段规则(API / CFST):
domain、ip、loss_rate、avg_latency、download_speed、region)。null 占位。score_value、scores、created_raw)仅在有值时输出。python3runtime-statepython3 scripts/domain_updater.py --config config.server.json
bash scripts/run_update_and_commit.sh config.server.json
强制提交:
bash scripts/run_update_and_commit.sh --force-commit config.server.json
# 或
GIT_FORCE_COMMIT=1 bash scripts/run_update_and_commit.sh config.server.json
为了在服务器上实现无人值守的定时域名更新与自动 Git 提交,本项目提供了一套完整的 systemd 服务安装脚本。
systemd(系统服务管理)、runuser(安全切换用户执行)。ca-certificates(若缺失,安装脚本默认会通过 apt-get 自动补全)。你可以使用 sudo bash scripts/install_debian.sh [options] 进行灵活安装:
| 参数选项 | 默认值 | 说明 |
|---|---|---|
--config <path> |
config.server.json |
配置文件路径(若为相对路径,则相对于仓库根目录) |
--interval <value> |
30min |
定时器执行间隔,例如 1h、30min、10s 等 |
--user <name> |
当前 sudo 用户 |
运行 systemd 服务的非 root 系统用户 |
--group <name> |
当前 sudo 用户组 |
运行 systemd 服务的系统用户组 |
--git-push <0\|1> |
1 |
选出新域名并 commit 后,是否自动推送(git push)到远程仓库 |
--git-push-remote <name> |
origin |
推送的 Git 远程仓库名称 |
--git-http-username <u> |
git |
远程 Git 仓库的 HTTPS 认证用户名 |
--git-http-token <token> |
空 | 远程 Git 仓库的 HTTPS 访问令牌(用于非交互式免密推送) |
--git-http-token-file <path> |
空 | 从指定文件中读取 HTTPS 访问令牌,避免命令行泄露敏感信息 |
--git-use-credential-store <0\|1> |
1 |
是否使用 Git 凭据辅助存储(credential.helper store)持久化 Token |
--git-credentials-file <path> |
空 | 自定义凭据存储文件的路径(若不指定,默认保存在服务用户家目录下) |
--no-install-deps |
否 | 跳过 apt-get 依赖包检测与自动安装 |
-h, --help |
- | 显示帮助信息 |
[!IMPORTANT] 关于 Git 自动推送(Push)与凭据认证
- HTTPS 认证(推荐使用 Token):指定
--git-http-token或--git-http-token-file。安装脚本会自动启动git credential approve为指定的运行用户配置全局凭据,且所有 Token 信息都会以安全权限(600)保存在独立配置文件中,杜绝安全隐患。- SSH 认证:如果远程仓库使用 SSH 地址(例如
git@github.com:...),只需在安装时指定--git-use-credential-store 0。只要确保配置的--user用户的 SSH 密钥已被授权到远程 Git 平台即可。- 安全隔离:服务不允许以
root用户身份保存 Git Token。若使用 Token 认证,必须指定非 root 用户(默认即为执行sudo的普通用户)。- Git 安全目录:安装脚本会自动为服务运行用户注入
git config --global --add safe.directory配置,彻底避免 systemd 执行时因目录所有权引起的 Git 安全阻拦错误。
示例 1:最简安装(每 30 分钟自动运行,使用默认配置,支持 Git 推送)
sudo bash scripts/install_debian.sh
示例 2:自定义时间间隔,并通过文件安全读取 GitHub/GitLab 访问令牌
sudo bash scripts/install_debian.sh --interval 10min --git-http-username aurora --git-http-token-file /home/aurora/.github_token
示例 3:纯本地运行,不推送到远程仓库
sudo bash scripts/install_debian.sh --git-push 0
如果你需要卸载 systemd 定时任务和服务,可以使用自带的卸载脚本。该脚本会自动停止正在运行的定时器与服务,移除系统 unit 文件,清理 Git 全局安全路径配置,并重载 systemd。
sudo bash scripts/uninstall_debian.sh [options]
参数选项:
--keep-auth-files:保留安装时生成的环境配置文件(/etc/vmess-domain-rotator.env)与保存凭据的安全目录(/var/lib/vmess-domain-rotator)。若计划稍后重新安装,建议加上此参数。--service-name <name>:指定要卸载的服务基名(默认为 vmess-domain-rotator)。快速卸载示例:
# 彻底卸载(默认清除所有关联的 Token 与配置文件,保留 git 仓库代码)
sudo bash scripts/uninstall_debian.sh
# 卸载服务但保留认证凭据
sudo bash scripts/uninstall_debian.sh --keep-auth-files
部署完成后,你可以通过以下命令对服务进行管理和排错:
# 查看定时器状态与下一次执行时间
sudo systemctl status vmess-domain-rotator.timer
# 查看单次服务运行状态与退出码
sudo systemctl status vmess-domain-rotator.service
# 手动立即触发一次更新(无需等待定时器,方便测试)
sudo systemctl start vmess-domain-rotator.service
# 实时查看运行日志
sudo journalctl -u vmess-domain-rotator.service -f --no-pager
# 查看最近 100 行日志
sudo journalctl -u vmess-domain-rotator.service -n 100 --no-pager
# 语法与配置预检
env PYTHONPYCACHEPREFIX=/tmp/pycache python3 -m py_compile scripts/domain_updater.py
bash -n scripts/run_update_and_commit.sh
# 检查当前配置解析出的实际输出路径
python3 scripts/domain_updater.py --config config.server.json --print-output-settings
# 手动强制提交当前域名(即便域名没有发生变化,也会生成 commit 并推送到 remote)
sudo -u aurora bash scripts/run_update_and_commit.sh --force-commit config.server.json
服务器模式(API)采用结构化的过滤与权衡评分机制,保证筛选出的域名兼顾极低的延迟与极低的丢包率。
record_mapping)通过 config.server.json 中的 record_mapping 块,可以将任意 API 响应中的自定义字段映射为标准字段。目前已映射的标准字段包括:
domain:物理域名/IP。created_at:记录创建时间(支持时区与多种格式解析)。yd_latency / yd_pkg_lost_rate:移动延迟 / 移动丢包率。dx_latency / dx_pkg_lost_rate:电信延迟 / 电信丢包率。lt_latency / lt_pkg_lost_rate:联通延迟 / 联通丢包率。avg_latency / avg_pkg_lost_rate:三网平均延迟 / 平均丢包率。record_filter 与 domain_filter)record_filter):在解析前排除包含特定语义的字段。例如,默认过滤掉 host_provider 为 "CF优选IP" 的记录,或排除特定敏感域名。domain_filter):根据正则表达式排除不合格的物理格式。例如,默认使用正则排除直接为 IPv4 格式的记录,只保留纯域名。scoring)评分机制(以 weighted_average 策略为例)将对剩余的候选域名进行加权评分:
weighted_fields):
在默认的 config.server.json 中,为了优化中国移动线路的访问表现,配置了以下加权项:
yd_latency (权重: 1.0)yd_pkg_lost_rate (权重: 10.0)prefer_lower):设置为 true,分值越低(延迟越低、丢包率越少)则排名越靠前。within_hours):自动过滤掉创建时间超过 24 小时的陈旧测试记录。tie_breakers):当评分相同时,支持按备用字段(如 created_at 降序、domain 升序)进行决胜排序,保证排序的绝对确定性。如果 API 请求超时、解析失败或过滤后无可用域名:
runtime/state.json 中上一次持久化保存的 last_good_domain。error_use_last_good,调度脚本捕获后会以 chore(fallback): 作为前缀提交,方便管理员追溯。scripts/run_update_and_commit.sh、scripts/install_debian.sh、scripts/uninstall_debian.sh 的日志统一为:
[YYYY-MM-DD HH:MM:SS] [vmess-domain-rotator] <message>
Git 提交信息中也会带 UTC 时间戳,例如:
chore: rotate preferred value to example.com (2026-05-11T13:03:16Z)
chore(fallback): rotate preferred value to example.com (2026-05-11T13:03:16Z)
chore(fallback) 表示源端出错、使用了上次的可用值。
cfst 模式python3cfstpython3 scripts/domain_updater.py --config config.local.json
默认配置当前指向:
cfst_local.work_dir = ./cfst_darwin_arm64(macOS ARM;部署时按实际平台修改,如 ./cfst_linux_armv5)cfst_local.binary = ./cfstconfig.local.json -> output.runtime_dir 为准(当前仓库默认 ./runtime)# 输出文件检查(按当前 config.local.json 默认 runtime_dir=./runtime)
cat runtime/current_ip.txt
cat runtime/current_ip.json
cat runtime/state.json
cat runtime/substore_vars.json
# 仅检查输出路径解析
python3 scripts/domain_updater.py --config config.local.json --print-output-settings
cfsthttpd applet)/jffs/vmess/
├── busybox_armv7l
├── config_router.conf
├── scripts/
│ ├── router_local_update.sh
│ └── router_local_http.sh
└── cfst/
├── cfst
├── ip.txt
└── result.csv
config_router.conf)CFST_WORK_DIR / CFST_BIN / CFST_RESULT_FILECFST_SPEED_LIMIT(建议设置,如 5)RUNTIME_DIR / VALUE_TEXT_FILE / VALUE_JSON_FILEBUSYBOX_BIN(如 ./busybox_armv7l)HTTP_PORT(默认 8080)cd /jffs/vmess
sh scripts/router_local_update.sh config_router.conf
sh scripts/router_local_http.sh config_router.conf
说明:
cfst 原始输出(便于排错)cfst,只保留 [router-local] 摘要BUSYBOX_BIN 指向的 BusyBox httpd,不使用 ASUS 系统 httpd/jffs/scripts/services-start)VMESS_DIR="/jffs/vmess"
CONFIG="./config_router.conf"
UPDATE_LOG="/tmp/router_local_update.log"
HTTP_LOG="/tmp/router_http.log"
HTTP_PROCESS_PATTERN='[r]outer_local_http.sh'
start_vmess_http() {
if ps | grep -q "$HTTP_PROCESS_PATTERN"; then
return 0
fi
cd "$VMESS_DIR" || exit 1
nohup sh scripts/router_local_http.sh "$CONFIG" >> "$HTTP_LOG" 2>&1 &
}
cd "$VMESS_DIR" || exit 1
# 避免开机过早导致 result.csv 为空
sleep 60
i=1
while [ "$i" -le 5 ]; do
if sh scripts/router_local_update.sh "$CONFIG" >> "$UPDATE_LOG" 2>&1; then
break
fi
sleep 20
i=$((i + 1))
done
cru d vmess_rotate
cru a vmess_rotate "0 * * * * cd $VMESS_DIR && sh scripts/router_local_update.sh $CONFIG >> $UPDATE_LOG 2>&1"
sleep 10
start_vmess_http
cru d vmess_watchdog
cru a vmess_watchdog "*/5 * * * * if ! ps | grep -q '$HTTP_PROCESS_PATTERN'; then cd $VMESS_DIR && nohup sh scripts/router_local_http.sh $CONFIG >> $HTTP_LOG 2>&1 & fi"
# 基础检查
cd /jffs/vmess
chmod +x busybox_armv7l
./busybox_armv7l --list | grep '^httpd$'
# 更新与结果检查
sh scripts/router_local_update.sh ./config_router.conf
cat cfip_runtime/current_ip.txt
cat cfip_runtime/current_ip.json
cat cfip_runtime/state.json
# HTTP 与端口检查
sh scripts/router_local_http.sh ./config_router.conf
ps | grep router_local_http.sh
netstat -lntp | grep ':8080'
curl http://127.0.0.1:8080/current_ip.txt
# 常见端口冲突处理(Address already in use)
# 1) 改 config_router.conf 的 HTTP_PORT
# 2) 或停止旧进程后重启
scripts/router_local_update.sh 与 scripts/router_local_http.sh 的日志统一为:
[YYYY-MM-DD HH:MM:SS] [router-local|router-http] <message>
[!WARNING] 为什么要配置防擦写优化? 路由器的
/jffs目录是位于 NAND/NOR Flash 物理闪存介质上的。本项目默认每小时执行一次本地cfst测速并生成result.csv。如果将这些临时文件直接写入/jffs,长期高频擦写将严重缩短路由器硬件闪存的寿命。
本项目已经完美支持了绝对路径智能解析与动静分离存储方案。你可以将所有高频读写的临时文件和运行期数据全部重定向至系统的 RAM 内存临时文件系统(/tmp),而仅将最关键的初始化与容灾文件(state.json)保存在闪存上。
修改路由器上的 config_router.conf,将高频写操作的目录与文件路径配置如下:
# 1. 测速工作区与输入文件保存在 flash 上(只读性质)
CFST_WORK_DIR="/jffs/vmess/cfst"
CFST_BIN="./cfst"
CFST_IP_FILE="ip.txt"
# 2. 【核心优化】测速输出 csv 定向到内存系统(/tmp),不磨损硬件!
CFST_RESULT_FILE="/tmp/vmess_result.csv"
# 3. 【核心优化】运行期数据目录全部指向内存,速度飞快且零硬件磨损
RUNTIME_DIR="/tmp/vmess_runtime"
VALUE_TEXT_FILE="current_ip.txt"
VALUE_JSON_FILE="current_ip.json"
EXPORT_VARS_FILE="substore_vars.json"
# 4. 【容灾持久化】将上次可用值 state.json 独立保存在物理闪存中,保证重启后不丢失
# 因为只有在真正检测到 IP 变化并写入成功时才会写一次 Flash,写入频率极低(通常几天或几周写一次),安全无虞。
STATE_FILE="/jffs/vmess/state.json"
/tmp/vmess_runtime 会在每次开机或定时器运行 router_local_update.sh 时,通过 mkdir -p 自动创建,无需手动干预。cfst 会将大量的下载速度数据、中间进度及最终的 vmess_result.csv 写入 RAM 内存,彻底消除闪存介质每小时擦写几百 KB 的问题。httpd 将直接挂载 /tmp/vmess_runtime 目录来服务 Sub-Store。因为数据常驻内存,HTTP 响应速度可以提升至微秒级。/tmp 随之清空。但由于我们把备用状态 state.json 单独放回了物理闪存 /jffs/vmess/state.json,下一次定时器启动时,如果暂时无法连接网络或测速报错,脚本依然能成功从 Flash 读回上次可用的 fallback IP 并完美恢复服务。substore/operator_template.js 支持:
VALUE_SOURCE_MODE = "default":路由器优先,低速时切服务器VALUE_SOURCE_MODE = "server_only":只用服务器VALUE_SOURCE_MODE = "router_only":只用路由器速度阈值使用 MB/s:
ROUTER_MIN_SPEED_MB_PER_S = 5download_speed 纯数字按 MB/s 解释缓存按 VALUE_SOURCE_MODE 隔离,切换模式后不会命中旧缓存。
./build_router_package.sh
可选覆盖:
BUSYBOX_SRC="/path/to/busybox_armv7l" \
CFST_SRC_DIR="/path/to/cfst_dir" \
OUT_TAR="/path/to/vmess.tar.gz" \
./build_router_package.sh
打包内容默认为:
vmess/busybox_armv7lvmess/config_router.confvmess/scripts/router_local_update.shvmess/scripts/router_local_http.shvmess/cfst/*state.json 需持久化,否则 fallback 不可用。httpd,不要依赖系统精简 httpd / nc。git safe.directory 配置。