dsh 局域网访问部署教程

August 16, 2026 · View on GitHub

适用对象:已在 Android 手机 Termux 上部署好 dsh(dsh web 能跑、能在本机用)的用户。 目标:同一 WiFi 下的平板 / 电脑 / 其他手机,用浏览器直接打开手机上的 dsh——看到手机上的对话、能改设置、能建工作区,客户端零安装

一、总体架构

客户端浏览器 ──> http://<手机IP>:3088


        ┌──────────────────────────┐
        │ dsh-lan-proxy.js (0.0.0.0:3088) │  手机端
        │ ① 开关检查 ~/.dsh-lan-on  │
        │ ② Host/Origin 改写成回环  │
        │ ③ 注入 crypto.randomUUID 补丁 │
        └───────────┬──────────────┘

        dsh web (127.0.0.1:3080)   ← dsh 本体,只监听回环
端口进程监听作用
3080dsh web127.0.0.1dsh 本体(CLI 故意禁 --host 0.0.0.0
3088dsh-lan-proxy.js0.0.0.0局域网唯一入口:转发 + 回环改写 + 注入补丁
3090dsh-llm-proxy.js127.0.0.1LLM 代理(可选,用于上游网关适配)
3098dsh-ctl-server.js127.0.0.1控制 API(开关 / 重启 / 状态,供控制台 App 调用)

二、工作原理(为什么必须这么做)

dsh 是单设备设计,局域网访问被三层障碍挡住,必须逐层绕开:

#障碍现象根因解法
1客户端 loopback 门LAN 打开页面后只调 inventory 同步(value:[]),workspace.list / session.list / settings.describe 一个都不发,UI 永远卡"正在加载工作区"客户端 JS 计算 isLoopback(非回环 hostname → false),整个数据流不初始化源码补丁:强制 isLoopback: true
2服务端特权围栏设置 / 凭据 / 建工作区返回 403PRIVILEGED_METHODS 特权表只对回环连接开放(判断写死 []源码补丁:3 处放开为 this.trustedHosts
3🔑 crypto.randomUUID 缺失(真正的元凶)页面 console 反复报 WebSocket is closed before the connection is established,WS 23ms 内被 abort,连接永不建立dsh 客户端用 crypto.randomUUID() 生成 RPC ID,但它只在安全上下文(HTTPS / localhost)存在;LAN 的 http://<IP>:3088 是非安全上下文 → 抛错 → RPC 全崩 → 连接中止代理层:给 HTML <head> 注入 polyfill

双层加固设计

  • 服务端(rebrain.sh 幂等打补丁):解决障碍 1、2——改的是 dsh 包内 JS,升级后重跑即重打
  • 代理层(dsh-lan-proxy.js):解决障碍 3 + Host/Origin 回环改写——不碰 dsh 本体,任何 LAN 设备打开页面即生效

⚠️ 只测 curl = 假阳性:API 层 200 不代表 UI 能用(障碍 1 在客户端 JS,curl 不触发)。必须用真浏览器验证(见第五节)。

三、部署步骤

1. 准备 bundle(5 个文件)

文件作用
dsh-lan-proxy.jsLAN 代理(核心:开关 + 回环改写 + polyfill 注入)
dsh-ctl-server.js控制 API 服务
start-dsh.sh启动脚本(自动检测 wlan0 IP → 起 4 个进程)
rebrain.sh幂等重装脚本:打全部源码补丁 + 部署配置 + 拉起链
dsh-supervise.sh保活监督循环(进程死 5s 自动重启)

2. 推送到手机

cd <bundle目>
for f in dsh-lan-proxy.js dsh-ctl-server.js start-dsh.sh rebrain.sh dsh-supervise.sh; do
  adb push $f /sdcard/Download/$f
done
adb shell "run-as com.termux sh -c '
  for f in dsh-lan-proxy.js dsh-ctl-server.js start-dsh.sh rebrain.sh dsh-supervise.sh; do
    cat /sdcard/Download/\$f > /data/data/com.termux/files/home/dsh-brain-swap/\$f
  done
  rm -f /sdcard/Download/dsh-lan-proxy.js /sdcard/Download/dsh-ctl-server.js /sdcard/Download/start-dsh.sh /sdcard/Download/rebrain.sh /sdcard/Download/dsh-supervise.sh
'"

⚠️ 必须用 cat > 注入:run-as com.termux 的 shell 下 cp 会静默写出 0 字节文件。

3. 打补丁并启动

adb shell "run-as com.termux sh -c '
  pkill -f \"[d]sh-supervise[.]sh\" 2>/dev/null
  sleep 1
  REBRAIN_NO_LAUNCH=1 sh /data/data/com.termux/files/home/dsh-brain-swap/rebrain.sh
'"
# 上面输出 "already patched" / "patched" 即补丁幂等生效
adb shell "run-as com.termux sh -c '
  setsid sh /data/data/com.termux/files/home/dsh-brain-swap/dsh-supervise.sh \
    > /data/data/com.termux/files/home/dsh-supervise.log 2>&1 < /dev/null &
'"
sleep 40   # 冷启动等待

4. 验证部署

# 补丁是否打上
adb shell "run-as com.termux sh -c '
  F=/data/data/com.termux/files/usr/lib/node_modules/@deepseek-ai/dsh/node_modules/@deepseek-ai/dsh-client-connection
  grep -c \"isTrustedApiRequest(request, this.trustedHosts)\" \$F/lib/index.js   # 期望 ≥2
  grep -c \"LAN-patch\" \$F/lib/client.js                                        # 期望 ≥1
  grep -c LOOPBACK_HOST \$HOME/dsh-lan-proxy.js                                  # 期望 ≥1
'"
# 四个端口 + 当前 IP
adb shell "run-as com.termux sh -c '
  export PATH=/data/data/com.termux/files/usr/bin:\$PATH
  for p in 3080 3088 3090 3098; do curl -s -m 2 -o /dev/null -w \"\$p=%{http_code} \" http://127.0.0.1:\$p/; done
  echo; ip route get 1 | grep -oE \"src [0-9.]+\" | cut -d\" \" -f2
'"

4 端口全部 200 = 部署成功,记下输出的 IP。

四、使用

  1. 客户端浏览器打开 http://<手机IP>:3088(IP 变了重新执行上条命令查询;或装配套控制台 App,实时显示大绿色地址)
  2. 即可看到手机上的工作区、对话、设置、模型选择——与手机上操作一致
  3. 首次打开有"内测声明"弹窗,点继续

五、真浏览器验证(判定"能用"的标准)

用电脑 Edge/Chrome 打开 http://<手机IP>:3088全部满足才算通过

  • ✅ 页面出现手机上已有的工作区和对话内容
  • ✅ 开发者工具 Network 里调用了 workspace.list / session.list / settings.describe 等数据 API(≥20 个)
  • ✅ localStorage 出现 dsh.workspace.view.v5 等键
  • ✅ 设置页可打开、可新建工作区、可发消息

只看到页面但"一直加载"= 障碍 1 未解决;设置 403 = 障碍 2 未解决;WS 疯狂重连 = 障碍 3 未解决。对照第二节定位。

六、排查速查

现象原因处理
打不开 http://<IP>:3088IP 不对 / 链死了(系统杀后台)/ 开关关了重查 IP;重启链;开启关
一直"正在加载工作区"代理旧版(无 polyfill)或补丁丢失重跑 rebrain;确认两个 grep -c 通过
设置 / 凭据 403特权围栏补丁没打上重跑 rebrain
手机本地 3080 正常、LAN 全挂多个代理进程抢 3088pkill -f "[d]sh-lan-proxy[.]js" 后重启链,确保只剩 1 个代理进程
发消息 429上游 LLM 限流窗口等几分钟重试,与 LAN 无关

七、安全与回滚

  • 安全:所有改动都在手机 Termux 内、可逆,不碰路由器。注意开关打开期间 WiFi 内网任何设备都能访问手机 dsh——家用 WiFi 无碍,公共网络请关闭开关(~/.dsh-lan-on 删除即关)。
  • 回滚pkill -f "[d]sh-supervise[.]sh" 停链 → 删 ~/.termux/boot/99-dsh.sh 撤自启 → 重装 dsh 包还原补丁 → 删 ~/dsh-*.js~/dsh-brain-swap/ 即完全撤掉。
  • 升级 dsh 后:重跑 rebrain.sh 即自动重打全部补丁(幂等)。

八、致谢

  • 感谢 DeepSeek Harness (dsh) 团队——出色的本地 AI 智能体框架;本方案所有补丁均为对运行文件的独立适配,不修改其任何版权代码,官方升级后重跑 rebrain.sh 即可重打。
  • 感谢 TermuxTermux:Boot——本方案依赖的 Android 终端环境与开机自启机制。
  • 感谢商汤 SenseNova 提供的 OpenAI 兼容网关(可选上游)。
  • 特别感谢本项目的测试与反馈者。

九、友情链接

项目链接说明
DeepSeek Harness (dsh)https://github.com/deepseek-ai/dsh本方案的服务端本体
Termuxhttps://github.com/termux/termux-appAndroid 终端模拟器
Termux:Boothttps://github.com/termux/termux-boot开机自启支持
puppeteerhttps://github.com/puppeteer/puppeteer教程验证章节使用的浏览器自动化工具

如果你有同类项目(dsh 增强 / Termux 工具 / 局域网访问方案),欢迎在 Issue 中提交,我会添加到本表。