Back to home

HomoLand

dsh-remote-access-patch

No description

Stars
0
Language
Shell
Created
Aug 15, 2026
Updated
Aug 15, 2026

Introduction

dsh-remote-access-patch

CI License: MIT

dsh(DeepSeek Harness)的「配置平面」从仅限本机 loopback 放行为可在受信域名下远程读写的一键脚本。

一个可开源的、幂等、可回滚的补丁工具,把 docs/cluster/dsh-external-access-deployment.md 第 6 节的两处手工补丁自动化。

仓库:https://github.com/HomoLand/dsh-remote-access-patch


它解决什么问题

dsh 0.1.0-rc.6 把配置平面限制在本机,有后端 + 前端两层栅栏,即使配了 --trusted-host 域名,远程浏览器仍:

  • 后端:15 个「特权方法」(settings.*agentPreset.*credentials.*host.pickDirectoryllm.discoverModels 等)被 isTrustedApiRequest(request, []) 空信任列表拒绝 → /api/settings.describe 返回 403
  • 前端:connection.isLoopbacklocation.hostname 非回环而为 false,settings scope 落到 "memory"status="unavailable")→ 插件配置卡片不渲染

本脚本放行这两处,让远程登录用户可以正常读写设置与插件配置。

⚠️ 安全前提(必须先读)

dsh 源码注释明说:trustedHostsDNS-rebinding 栅栏,不是认证层;配置平面在「真正的认证层」出现之前保持 loopback-only。

因此只有在 dsh 之前已前置了真正的认证层(如 Authelia forwardAuth + two_factor/TOTP,或等效的 SSO/OIDC 网关)时,本补丁才是安全的:

  • 所有远程请求必须先通过登录 + 二次验证才能到达 dsh;
  • dsh 进程仍应只绑 127.0.0.1,经收口(如 socat)暴露给内网,不直接暴露公网。

没有认证层就不要用本脚本把 dsh 暴露到公网。

前置条件

  • Linux,bash 4+,python3(用于精确替换),grep
  • npm root -g 可解析(或手动传 --dsh-root);
  • 修改 dsh 安装目录需要 root(文件属 root)。

用法

./dsh-remote-access-patch.sh [status|apply|rollback] [选项]
命令作用
status(默认)只读查看两处补丁状态与备份情况
apply应用两处补丁(幂等;首次自动备份 .orig-bak
rollback.orig-bak 恢复原始文件
选项说明
--dsh-root DIRdsh 模块根目录(默认 $(npm root -g)/@deepseek-ai/dsh/node_modules/@deepseek-ai
--service NAME配合 --restart 重启的 systemd 服务(默认 dsh.service
--restart完成后 systemctl restart 该服务(需 root)

环境变量 DSH_ROOT 等价于 --dsh-root

典型流程

# 1) 看现状
sudo ./dsh-remote-access-patch.sh status

# 2) 打补丁并重启
sudo ./dsh-remote-access-patch.sh apply --restart

# 3) 浏览器强制刷新(Ctrl+Shift+R)→ 设置 → 插件,确认卡片已渲染且可编辑

# 4) 需要回滚时
sudo ./dsh-remote-access-patch.sh rollback --restart

补丁内容对照

#文件改动
1(后端)dsh-client-connection/lib/index.jsisTrustedApiRequest(request, [])isTrustedApiRequest(request, trustedHosts)(仅 privileged 方法闸门那一行;第 237 行 Typert interceptor 的 loopback 判定不动
2(前端)dsh-client-ui-settings/lib/client.jsSettingsScopeController(..., connection.isLoopback ? "host" : "memory")SettingsScopeController(..., "host")

设计要点

  • 幂等:重复 apply 不会二次修改,输出 [SKIP]
  • 升级安全:按唯一锚串定位(不依赖行号),dsh 重装覆盖补丁后重新 apply 即可;升级后 .orig-bak 会被刷新为当前版本的原始内容,保证 rollback 回到当前版本未打补丁的状态。
  • 精准:锚串带 PRIVILEGED_METHODS.has(method) 前缀,避免误伤同文件第 237 行另一处 isTrustedApiRequest(request, []);出现多匹配时拒绝执行并报错。
  • 可回滚apply 前先 cp -a.orig-bakrollback 一键恢复。
  • 只读安全status 不写任何文件。

升级 dsh 后

npm install -g @deepseek-ai/dsh 会覆盖两个补丁文件。升级后重新执行:

sudo ./dsh-remote-access-patch.sh status   # 应看到 [TODO] 未打补丁
sudo ./dsh-remote-access-patch.sh apply --restart

开发与测试

本地自测(不依赖真实 dsh 安装,用 test/fixture/ 最小夹具跑完整循环):

make check    # bash -n 语法检查
make test     # 功能自测(status/apply/rollback/幂等/逐字节回滚)
make lint     # shellcheck(需先安装 shellcheck)

CI:.github/workflows/ci.yml 在每次 push / PR 上执行 bash -nshellcheckbash test/run.sh

文件

dsh-remote-access-patch/
├── dsh-remote-access-patch.sh   # 主脚本
├── Makefile                     # check / test / lint
├── test/
│   ├── run.sh                   # 功能自测
│   └── fixture/                 # 最小夹具(含 lookalike 行)
├── .github/workflows/ci.yml     # GitHub Actions CI
├── README.md                    # 本说明
└── LICENSE                      # MIT

License

MIT