RUNBOOK:OpenClash 节点优选与带宽门槛(openwrt / 192.168.31.2)¶
面向"拿着就能做"的值班与日常运维。变更来龙去脉见
docs/SOP-openclash.md第 13 章。 备份台账见backup/README.md。首版 2026-10-01,同日随 v3 放开区域限制一并修订。
1. 服务概览¶
| 项 | 内容 |
|---|---|
| 作用 | 在 OpenClash 的延迟选优之外补上带宽维度,按「带宽 0.6 : 延迟 0.4」打分选节点。区域限制已于 v3 放开(仅排除香港)——实测美国 HY2 类节点带宽优于部分亚太节点(5–6 MB/s vs 714 KB/s),预设区域反会把好节点排除 |
| 组件 | ① clean_nodes.rb(覆写脚本,OpenClash 每次启动时重建策略组与规则);② speed_select.rb(选优脚本,cron 每 5 分钟);③ mihomo API(127.0.0.1:9090) |
| 依赖 | OpenClash 运行中、mihomo v1.19.31、ruby 3.3.10、curl |
| 异常时的业务影响 | 不会断网。脚本失效 = 退回"纯延迟选优"(可能选到低带宽节点),代理仍可用 |
| 重要性 | 中(体验类优化,非可用性关键路径) |
策略组结构(主链路:客户端 → 便宜机场 → 实际节点):
| 组 | 类型 | 说明 |
|---|---|---|
便宜机场 |
select | 主组。常态固定到脚本选出的具体节点(如 泰国-HY2-48),点开组详情看到的是节点名而非组名;仅当该节点不可达时才临时切回 优选 |
优选 |
url-test | 全部候选节点(46 个,仅排除香港),仅作故障兜底——它按延迟选优,会挑到低带宽节点,故不参与常态选路 |
测速 |
select | 仅供选优脚本指定测速出口,不承载用户流量 |
自动选择 |
url-test | 订阅自带的全量 url-test 组,候选池整体不可用时兜底 |
组名
优选/测速为 2026-10-01 v3 命名;此前的亚太优选/亚太测速已随区域放开更名。⚠️ 下游设备出网受本链路直接影响:Harbor 主机(
192.168.31.31)默认路由即192.168.31.2。 但注意:Harbor 的镜像拉取走的是本机 socks5 隧道(1080→ 香港跳板,ssh 22 端口不被 Clash 劫持), 不经本 Clash;其速度问题应在隧道链路上排查(见frp_openvpn_tunnel/),不要在 Clash 侧找原因。
2. 接入与凭据¶
| 项 | 取值 / 位置 |
|---|---|
| SSH | root@192.168.31.2(仅密钥登录,密码认证已关闭) |
| 控制面板 | http://192.168.31.2:9090/ui |
| API 密钥 | 从系统读,不写死:uci -q get openclash.config.dashboard_password |
| 代理认证 | 运行时 yaml 的 authentication 字段(当前形如 <用户>:<口令>),端口见 mixed-port(7893) |
客户端接入示例(显式代理,便于排障):
S=$(uci -q get openclash.config.dashboard_password) # 在 OpenWrt 上取
curl -x "http://<认证>@192.168.31.2:7893" https://github.com
注意:从 OpenWrt 本机用透明代理路径访问会命中订阅自带的
SRC-IP-CIDR,192.168.31.2/32,DIRECT(防回环),属正常现象,不是代理故障;用显式端口(源 127.0.0.1)或从其它设备测。
3. 日常速查表¶
# 服务状态
/etc/init.d/openclash status
# 选优脚本日志(最近 20 行;仅完整测速轮有输出)
tail -20 /root/speed_select.log
# 脚本心跳(每 5 分钟刷新;日志静默时用它判断是否还在跑)
cat /tmp/speed_select.state
# 当前各组的选中项
S=$(uci -q get openclash.config.dashboard_password)
curl -s -H "Authorization: Bearer $S" http://127.0.0.1:9090/proxies | \
ruby -ryaml -e 'd=YAML.load(STDIN.read)["proxies"]; %w[便宜机场 优选 测速 自动选择].each{|k| v=d[k]; puts "#{k}: #{v["type"]} now=#{v["now"]} (#{v["all"].size} 成员)"}'
# 出口归属与带宽(在宿主执行)
curl -s -m 20 -x "http://<认证>@192.168.31.2:7893" https://chatgpt.com/cdn-cgi/trace | grep -E '^(ip|loc|colo)='
curl -s -m 45 -x "http://<认证>@192.168.31.2:7893" -o /dev/null -w 'speed=%{speed_download}\n' 'https://speed.cloudflare.com/__down?bytes=5242880'
# 手动触发一轮完整测速(只预览,不切换主组)
ruby /etc/openclash/custom/speed_select.rb --dry-run
# 手动触发一轮完整测速(真实切换)
ruby /etc/openclash/custom/speed_select.rb --force
4. 日常操作¶
改完 clean_nodes.rb 或要重放覆写链时的完整重启(顺序不可颠倒):
touch /etc/config/openclash
/etc/init.d/openclash stop; sleep 3
uci set openclash.config.enable=1; uci commit openclash
/etc/init.d/openclash start; sleep 40
不要用
restart:stop会把enable置 0,restart踩中会拒启且无显式报错。
临时停用选优脚本(保留配置,只停自动切换):
(crontab -l | grep -v "speed_select.rb") | crontab - # 停用
# 恢复:
(crontab -l 2>/dev/null | grep -v "speed_select.rb"; echo "*/5 * * * * /usr/bin/ruby /etc/openclash/custom/speed_select.rb >/dev/null 2>&1 #speed_select") | crontab -
手动把主组切回自动模式(交回 url-test,不做带宽干预):
S=$(uci -q get openclash.config.dashboard_password)
curl -s -X PUT -H "Authorization: Bearer $S" -H 'Content-Type: application/json' \
-d '{"name":"优选"}' 'http://127.0.0.1:9090/proxies/%E4%BE%BF%E5%AE%9C%E6%9C%BA%E5%9C%BA'
手动固定到某个节点(脚本在下一轮完整测速前不会覆盖它;节点不可达时健康检查会切回 优选):
curl -s -X PUT -H "Authorization: Bearer $S" -H 'Content-Type: application/json' \
-d '{"name":"泰国-HY2-48"}' 'http://127.0.0.1:9090/proxies/%E4%BE%BF%E5%AE%9C%E6%9C%BA%E5%9C%BA'
5. 配置管理¶
| 参数 | 位置 | 默认 | 说明 |
|---|---|---|---|
FULL_INTERVAL |
speed_select.rb 顶部 |
1800 s | 完整测速周期;调小=响应快、流量增 |
TOPN |
同上 | 5 | 除主组当前节点外,另测几个延迟最优候选 |
SPEED_BYTES |
同上 | 3 MB | 单候选下载量;调小=省流量、精度降 |
MIN_BW_BPS |
同上 | 1 MB/s | 带宽门槛;调高需谨慎,贴近实测值会导致误切 |
SWITCH_MARGIN |
同上 | 0.15 | 迟滞:当前节点仍达标且与最优差距在此比例内 → 不切换(抑制测量噪声抖动) |
W_BW / W_LAT |
同上 | 0.6 / 0.4 | 打分权重(带宽 / 延迟) |
HK_NAME |
clean_nodes.rb |
— | 排除香港节点(ChatGPT 受限);当前订阅无香港节点,此规则为订阅变更预留 |
改动后:speed_select.rb 直接生效(cron 下次触发);
clean_nodes.rb 需完整重启(第 4 节)才生效。
流量开销 = (TOPN+1) × SPEED_BYTES × (86400 / FULL_INTERVAL);默认约 0.86 GB/天。
6. 备份与恢复¶
| 对象 | 位置 |
|---|---|
| 覆写脚本 v4 | 远端 /etc/openclash/custom/clean_nodes.rb.bak.20261001-122808;本地 backup/etc/openclash/custom/ |
| 变更前 crontab | 远端 /root/crontab.bak.20261001-122808;本地 backup/root/ |
恢复步骤见 backup/README.md 的「回滚要点」,完整版见 docs/SOP-openclash.md 13.7。
恢复后必须完整重启并验证:组结构回到 3 个、经代理 github=200。
7. 监控与告警¶
| 指标 | 查看方式 | 关注点 |
|---|---|---|
| 脚本存活(心跳) | cat /tmp/speed_select.state 的 last_run |
每 5 分钟刷新;超过 15 分钟未变 = cron 或脚本出问题 |
| 脚本日志 | tail -20 /root/speed_select.log |
仅"完整测速轮"有输出(约 30 分钟一条);无日志不等于没在跑,看心跳 |
| 出口地区 | chatgpt.com/cdn-cgi/trace 的 loc |
出现 HK 即异常(香港应被排除) |
| 当前节点与带宽 | 速查表第 3 条 + 带宽命令 | 带宽长期 < 1 MB/s 说明候选池整体劣化 |
| 策略组健康 | API /proxies/优选 的 history |
全部为 0/超时说明候选池不可用 |
脚本日志会自轮转(超过 512 KB 保留末 500 行)。
8. 故障处置¶
场景 1:出口带宽长期偏低(停在慢节点)¶
症状:下载慢,实测 < 1 MB/s;便宜机场 固定在一个候选池里排名靠后的节点。
诊断
tail -5 /root/speed_select.log # 看最近一次完整测速的候选排名
ruby /etc/openclash/custom/speed_select.rb --dry-run # 当前各候选的实测带宽
处置:先 --force 手动触发一轮;若候选带宽整体偏低 → 机场劣化,非脚本问题,可临时
手动切到 自动选择(订阅自带的 url-test)应急。
验证:带宽恢复 MB/s 量级,github=200。
场景 2:出口落在香港(ChatGPT 不可用)¶
症状:loc=HK。
诊断
S=$(uci -q get openclash.config.dashboard_password)
curl -s -H "Authorization: Bearer $S" http://127.0.0.1:9090/proxies | \
ruby -ryaml -e 'd=YAML.load(STDIN.read)["proxies"]; puts d["优选"]["all"].grep(/香港|HK/)'
处置:预期输出为空(香港已被 HK_NAME 排除)。若非空 → 覆写脚本未生效,重放覆写链(第 4 节)。
验证:loc 不再是 HK。
场景 3:脚本不运行(心跳不刷新)¶
症状:/tmp/speed_select.state 的 last_run 超过 15 分钟未更新。
诊断
crontab -l | grep speed_select # 预期命中一行
ps | grep -c speed_select.rb # 是否有残留锁
ls -ld /tmp/speed_select.lock.d # 锁目录(正常执行时应短暂存在)
env -i /usr/bin/ruby /etc/openclash/custom/speed_select.rb; echo $? # 最小环境试跑,预期 0
处置
- 任务缺失 → 按第 4 节重新写入 cron;
- 有孤儿锁且超过 10 分钟 →
rmdir /tmp/speed_select.lock.d(脚本也会自动清理超 10 分钟的孤儿锁); - 最小环境试跑非 0 → 看输出里的"预检查不通过"原因,多为
uciPATH 或配置路径问题。
验证:env -i 试跑退出码 0,且心跳恢复刷新。
场景 4:代理完全不通¶
症状:经代理访问超时/非 200。
诊断:/etc/init.d/openclash status、tail -50 /tmp/openclash.log。
处置:本变更不是首因(脚本只调 API、不改配置)。优先按 recovery-plan.md 处理;若怀疑是本变更导致,直接执行 backup/README.md 的回滚要点。
验证:github=200、google=302。
9. 安全与权限¶
- API 密钥、代理认证口令属敏感信息,不写入任何文档,一律用
uci get openclash.config.dashboard_password与运行时 yaml 读取; - 脚本以 root 由 cron 运行,仅访问本机
127.0.0.1:9090与本机代理端口,不对外开放; - 脚本不修改任何配置文件,全部副作用只有两个:mihomo 的组选中项、
/tmp/speed_select.state; - 变更涉及的备份文件权限
600(crontab 备份由系统创建)。
10. 容量与性能¶
| 项 | 实测基线(2026-10-01) |
|---|---|
| 完整测速耗时 | 约 17 s(组测速并发测 46 节点 + 6 候选 × 3 MB) |
| 常态流量 | 约 0.86 GB/天(占机场 100 GB 月额度的 ~26%) |
| 落盘 | 脚本 12 KB、日志 ≤ 512 KB(自轮转)、状态文件 < 100 B |
| 已知瓶颈 | 机场节点带宽波动大(同一节点 1.58–4.39 MB/s),单次测速方差偏大 —— 门槛取 1 MB/s、并加 15% 迟滞,都是为了抗这种噪声 |
扩容/调优方向:波动若进一步加剧,可提高 SPEED_BYTES 或对候选做两次测速取较大值(需相应评估流量)。
11. 附录¶
修订记录
| 日期 | 内容 |
|---|---|
| 2026-10-01 | 首版:随"区域限制 + 带宽门槛"变更创建 |
| 2026-10-01 | v3:放开区域限制、组名 亚太优选/亚太测速 → 优选/测速、补迟滞参数与香港场景 |
相关文件
docs/SOP-openclash.md第 13 章(本次变更全过程)backup/README.md(备份台账与回滚要点)speed_select.rb/clean_nodes.rb(源码,与线上一致)frp_openvpn_tunnel/(Harbor 镜像拉取所走的隧道链路,与 Clash 无关)docs/SOP.md、recovery-plan.md(旁路由底座与断网恢复)
来源:
/home/rain/Documents/kvm/openwrt_bypass/openclash-apac-20261001/RUNBOOK.md| 最后更新:2026-10-01 13:17(由build/sync.py同步,请勿在站点侧修改)