给 NAS 上的 mihomo 换个现代面板
家里 NAS 上的代理内核跑了大半年,面板却一直停留在四年前的版本:一百多个节点平铺在一个下拉框里,想找个延迟低的得一个个点。这篇文章记录换面板、写幂等脚本、自动分组的全过程。为免广告嫌疑,文中不出现具体的服务商与客户端名称。
起因:那个 2022 年的面板
NAS 上的管理面板是浏览器里默认端口打开的那个页面。能用,但实在谈不上好用——节点列表就是一长串纯文本,
一百多个节点塞在一个下拉框里,连「按延迟排序」都没有。
顺手查了一下,这个面板最后一次提交停在 2023 年,最后一个版本是 2022 年 11 月发的。四年没更新,难看是有原因的。
先摸清家底,再动手
换面板之前,第一件事是搞清楚「我到底在跑什么」。这件事的收益远超预期——后面所有的判断都建立在这次摸底上。
几个关键发现:
- 内核是 mihomo(Clash.Meta),控制器 API 开在
:9090,而且没有设访问密码; - 节点是内联在配置里的(不是
proxy-providers),这直接决定了后面分组方案的选择; - 12 个策略组,每组都塞了一百多个节点,也就是说同一份扁平长列表被重复了 12 遍;
- 更关键的是:117 个节点里只有 53 个有过测速记录——一半以上的节点从没测过速。
最后一条基本解释了「选节点为什么这么痛苦」:不是面板不努力,是它压根没帮你测过。
选面板:三个候选
| 面板 | 维护状态 | 特点 |
|---|---|---|
| zashboard | 几乎每天有提交,最新版 2026-09 | 节点卡片网格、右键卡片整组测速、搜索、PWA、可改键位 |
| metacubexd | 活跃,内核官方推荐 | 32 套主题、7 种语言、规则搜索带命中数 |
| yacd-meta | 活跃(yacd 的续命分支) | 界面和原来一样,改动最小 |
| 2022 年后停更 | 就是原来那个 |
最后选了 zashboard,理由是它对「选节点」这个动作的优化最直接:右键节点卡片只测这一个,
右键组卡片整组一起测,然后按延迟排序。
部署:让内核自己托管面板
常规做法是起一个 nginx 容器托管静态文件,但 mihomo 有个更省事的能力:它可以直接把自己的 API 端口当成静态服务器。
1 | |
把面板的静态文件解压到内核工作目录下的 ui/zashboard/,重启即可通过 http://<NAS>:9090/ui/zashboard/ 访问。
三个好处:
- 同源:面板和 API 在同一个端口,不用配跨域,也不用额外维护一个容器;
- 内核日志会明确写出
UI already exists, skip downloading,不会偷偷覆盖你的文件; - 顺带解锁了
unified-delay。
unified-delay 为什么重要:不同协议(Trojan / VLESS / AnyTLS 等)的握手开销不一样,不统一延迟的话,测出来的数字根本没法横向比较,排序也就失去了意义。
解压 release 包时注意:很多包的最外层是 dist/,要让 index.html 直接躺在 ui/zashboard/ 下,否则打开只会看到一个 404 页面。
踩坑:服务商配置会覆盖你的设置
换完面板没两天,更新了一次订阅,然后发现:
- 面板打不开了——新配置把
external-controller从0.0.0.0:9090改成了127.0.0.1:9090; - 局域网其它设备不能再用这个代理了——
allow-lan被改成了false; - 出问题没有任何日志——
log-level被改成了silent。
订阅配置并不「知道」你在拿它做局域网网关。所以需要一个幂等的后处理脚本,每次订阅更新后跑一次:
- 规范化这几个关键项;
- 补齐面板相关设置;
- 重新生成自定义分组;
- 用内核自己的
-t参数校验候选配置,不通过就一个字节都不替换; - 备份 → 替换 → 重启 → 等到内核真正就绪再返回。
第 5 步别省。内核加载 GeoIP 数据库要 10 秒以上,如果脚本重启完立刻返回,紧接着的检查会全部失败,很容易误判成「配置把内核搞崩了」——我就这么误判过一次。
进阶:按落地地区自动分组
面板好看了,但「一百多个节点塞在一个下拉框里」这个问题还在。
节点命名其实有规律:<入口机房>转<落地地区><代号>[协议][倍率:x]。于是写了个脚本,按落地地区自动生成分组:
日本、台湾、香港、美国、新加坡等等,再加一个「省钱组」(倍率 ≤ 0.6 的节点)。
两个关键设计:
- 取最后一次「转」之后的部分作为落地地区。
A转美国X应该归到美国,而不是被名字里的「A」带偏; - 新组名追加到主选择组末尾,而不是插到开头。因为 select 组的默认值是列表第一项,插到开头会静默改变你现有的默认走向——这种 bug 最难查。
脚本还要幂等:重跑时先按名字删掉旧的自建组再重建,两次运行结果字节一致。
改造完的体感是这样的:打开面板,十几个地区分组一目了然,每组里的节点都按测速结果排好序,右键组卡片就能整组重测;
常用的几个组直接放在主选择组的最前面。选节点从「翻一百多行列表」变成了「点两下」。
几条经验
- 先摸家底再动手。 「有多少节点、测过几个、API 有哪些字段」这些问题,决定了后面能用什么方案。比如节点是内联还是 provider,直接决定了分组能不能用
filter。 - 让内核托管面板。 少一个容器、少一个跨域问题,还顺带能同步设置。
- 订阅配置会重置你的设置。 任何「更新后要重做一遍」的事,都该写成幂等脚本,并且必须在替换前用内核自己校验。
- 追加,不要插入。 改别人的策略组时,注意默认值语义。
- 备份先行。 每次替换配置前留一份带时间戳的备份,回滚成本就只剩一条
cp命令。
最后一个教训(关于隐私)
这次折腾里我犯了个错:排查问题时顺手把配置文件的第一行打印了出来,而那一行恰好是带 token 的订阅链接。
在自动化工具里,「打印出来」就等于「上传出去」。
后来给自己定了条规矩,也分享给同样爱折腾的人:
- 涉及凭据的操作,写成脚本让脚本读,只打印聚合结果(数量、状态码、可用率);
- 需要交互输入时用不回显的方式(
getpass/read -rsp),不进命令行参数、不进 shell 历史; - 万不得已要展示,只给「长度 + 前缀几位」;
- 排查任何文件时,先看结构特征(长度、字符集、熵、魔数),不要为了找线索把整个文件 cat 出来。
能自动化是本事,把凭据一起贴出去就是事故了。