Skip to content

[Bug] 华硕固件下热更新订阅使用 /tmp/mnt 路径导致 Mihomo 拒绝加载但任务仍提示成功 #1308

Description

@youveizhou-debug

Verify steps

环境

  • 设备:ASUS TUF-BE3600 V2
  • 固件:ASUS 官方固件 3.0.0.6.102_39407
  • ShellCrash:1.9.5alpha6.3
  • Mihomo:v1.19.28
  • ShellCrash 安装目录:/tmp/mnt/sda1/ShellCrash
  • Mihomo 启动参数:-d /mnt/sda1/ShellCrash -f /tmp/ShellCrash/config.yaml
  • 任务:热更新在线订阅(不重启)

问题描述

执行 task/task.sh hotupdate 时,在线订阅可以正常下载,新配置文件也已正确生成,任务最终返回 0 并提示成功,但正在运行的 Mihomo 节点列表没有更新。

原因是热更新代码向 Mihomo /configs API 提交了 $CRASHDIR/config.$format,在该设备上实际为:

/tmp/mnt/sda1/ShellCrash/config.yaml

而 Mihomo 的 home directory 是 /mnt/sda1/ShellCrash,因此 API 返回 HTTP 400:

path is not subpath of home directory or SAFE_PATHS:
/tmp/mnt/sda1/ShellCrash/config.yaml
allowed paths: [/mnt/sda1/ShellCrash]

但 ShellCrash 仍显示“已成功获取配置文件”,使用户误以为热更新已经生效。

复现步骤

  1. 在华硕官方固件上将 ShellCrash 安装到 /tmp/mnt/sda1/ShellCrash,Mihomo 以 -d /mnt/sda1/ShellCrash 启动。
  2. 更新在线订阅,使节点列表发生变化。
  3. 执行 task/task.sh hotupdate
  4. 检查生成的 config.yaml,其中已有新节点;但查询运行中 Mihomo 的 /proxies,仍是旧节点。
  5. 分别向 /configs?force=true 提交下面两个路径。

实测对比

错误路径:

{"path":"/tmp/mnt/sda1/ShellCrash/config.yaml"}

结果:HTTP 400,运行配置不变。

正确路径:

{"path":"/mnt/sda1/ShellCrash/config.yaml"}

结果:HTTP 204,立即加载成功;运行中的代理条目由 28 个变为 48 个,无需重启核心。

相关代码

当前 scripts/menus/task_cmd.sh 的热更新逻辑使用:

put_save "http://127.0.0.1:$db_port/configs" "{\"path\":\"$CRASHDIR/config.$format\"}"

临时修复与验证

在该设备上将提交路径改为:

"{\"path\":\"${CRASHDIR#/tmp}/config.$format\"}"

随后重新执行完整 hotupdate 流程,节点列表成功更新,核心未重启,原有手动节点选择也保持不变。

更稳妥的正式修复方案可能是:根据 Mihomo 实际的 -d home directory 或 SAFE_PATHS 规范化配置文件路径,而不是直接使用 ShellCrash 的 $CRASHDIR 路径。

预期行为

  • 热更新应将新生成的配置加载到正在运行的 Mihomo。
  • /configs 返回 4xx/5xx 时,任务应返回失败并显示 API 错误,不能只因订阅下载成功就报告整个热更新成功。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions