dsh-hub-pluginv0.8.0

dbssalan/dsh-hub-plugin

安全管理 MIT 最近更新 2026-11-05
0Stars
0Forks
0待解决 Issue
安装命令 dsh plugin --profile web add github:dbssalan/dsh-hub-plugin#e9564612f09283912d91fefddaa5c522ef02d0f5

介绍

把 DSH 安全发布到局域网/公网:访问密码、二维码、设备导航、cloudflared 隧道,全部在设置页里管理。

标签

cloudflared deepseek-harness dsh dsh-plugin remote-access

概述

DSH Hub 远程访问(dsh-hub-plugin)

把本机 DSH(DeepSeek Harness)安全地发布到局域网 / 公网:访问密码、二维码、设备导航页、cloudflared 隧道,全部在 DSH 设置页里管理,不需要命令行。

适合:用手机/平板/另一台电脑,通过浏览器远程使用这台电脑上的 DSH 会话。

特性

  • 访问密码:URL 不含密码,打开后必须输入;登录后 30 天 HttpOnly Cookie(HTTPS 下自动 Secure)
  • 局域网 + 公网:同一 WiFi 直连;公网用 cloudflared(免费随机域名,或命名隧道固定域名)
  • 设备导航页:二维码、分享链接、访问密码,一键复制
  • 远程设备(多机互控):添加另一台装了本插件的电脑,侧边栏浮层里直接操作它的 DSH
  • 桌面版直连:直接发布 Electron 桌面版宿主,不额外起第二个宿主
  • 多宿主冲突提示:启动日志会提示桌面版与 dsh web 同时运行(避免会话写租约互相锁)
  • 插件形态:随 DSH 启停,设置页开关,无需单独开终端
  • 安全默认:默认关闭;密码至少 8 位;管理接口只接受宿主注入的随机令牌,公网无法调用

工作原理

手机 / 平板 / 另一台电脑(浏览器)
        │  https://xxxx.trycloudflare.com(访问密码)
        ▼
   cloudflared 隧道
        ▼
┌──────────────────────────────┐
│ 本机 DSH Hub 反代 :19388      │
│  - 密码页 / 30 天 Cookie      │
│  - Host 改写(绕过 Host 栅栏)│
│  - 设备导航页 / 二维码        │
└──────────────┬───────────────┘
               │ 127.0.0.1:<DSH 端口>
               ▼
┌──────────────────────────────┐
│ DSH 宿主(桌面版或 dsh web)  │
│  - 会话、工作区、插件          │
└──────────────────────────────┘

设置页 ── 同源路由 /dsh-hub/* ──> 宿主插件 ──> 反代子进程

DSH 默认只监听 127.0.0.1,并对 Host 有校验。Hub 在本机做反向代理:把 Host 改写成 127.0.0.1:<port>,同时用本机密钥签发 DSH 认可的会话 Cookie,再把入口保护在访问密码之后。


安装

从 npm 安装(推荐)

dsh-hub-plugin
npm 上的最新版本从 0.8.0 起;如果你看到的是 0.3.x,说明只用过早期发布,请优先用下面的 GitHub 方式或升级。
  • 桌面版:设置 → 插件 → 添加插件,填 dsh-hub-plugin
  • 命令行(web profile):
dsh plugin --profile web add -w dsh-hub-plugin

从 GitHub 安装

https://github.com/dbssAlan/dsh-hub-plugin
  • 桌面版:设置 → 插件 → 添加插件,填上面的仓库地址
  • 命令行(web profile):
dsh plugin --profile web add -w https://github.com/dbssAlan/dsh-hub-plugin

安装后打开:Ctrl + , → 远程访问。

本地目录(开发)

git clone https://github.com/dbssAlan/dsh-hub-plugin.git

桌面版:设置 → 插件 → 安装 → 选择本地目录。

桌面 profile 由 Electron 管理,不能用 dsh plugin --profile desktop 直接安装,请走桌面端插件页。

从源码运行(web profile)

DSH_HOME=/path/to/home dsh plugin --profile web add -w /path/to/dsh-hub-plugin

快速开始

  1. 打开 设置 → 远程访问
  2. 勾选「启用远程访问」
  3. 填访问密码(至少 8 位)
  4. 选隧道模式:off(仅局域网)/ quick(免费随机域名)/ named(固定域名)
  5. 点「保存并重启」
  6. 点「打开设备导航页」看二维码,手机扫码 → 输入密码 → 进入 DSH

手机打开公网地址后输入密码,30 天内免登录。


配置项

首次启动时,Cordis 配置会写入 %DSH_HOME%/dsh-hub-plugin/config.json;之后以设置页 / 该文件为准(JSON 覆盖 YAML)。

字段默认说明
enabledfalse启用远程访问
password""访问密码,至少 8 位
listenPort19388本机反代端口
tunnelquickoff / quick / named
tunnelToken""命名隧道 Token(Cloudflare Zero Trust)
publicUrl""命名隧道对外地址,如 https://dsh.example.com
targetPort0目标 DSH 端口;0 = 自动(当前宿主)

命名隧道(固定域名)

  1. Cloudflare Zero Trust → Networks → Tunnels → Create a tunnel
  2. Public Hostname 指向 http://127.0.0.1:19388(与 listenPort 一致)
  3. 复制 Tunnel Token
  4. 设置页:隧道模式选 named,填入 Token 和你的域名(如 https://dsh.example.com)
  5. 保存并重启
快速隧道的域名每次重启会变;固定域名请用命名隧道。

安全模型

  • 访问密码是唯一门槛,且不在 URL 里;链接被转发也无法直接进入
  • 登录 Cookie:30 天、HttpOnly、SameSite=Lax;HTTPS(含隧道)下自动 Secure
  • 登录失败限速:同一来源 5 次 / 60 秒(隧道场景按 CF-Connecting-IP 识别来源)
  • 管理接口只接受宿主每次启动生成的随机令牌:公网/隧道流量即使回源 127.0.0.1 也调不到 /_config、/_sessions、/_peers
  • 设置页写接口走宿主同源路由 /dsh-hub/*,只接受本机直连浏览器;经 Hub 反代的请求一律 403
  • 访问密码字段支持显示 / 隐藏(保存后点一次即可取回显示),仅本机设置页可用
  • 添加远程设备时会拒绝内网 / 回环 / 云元数据地址(防 SSRF)
  • 只有本机页面嵌入时才放开 iframe 限制,其他网站无法把 DSH 嵌进页面(防点击劫持)
  • 公网入口由 cloudflared 提供 TLS,本机端口不直接暴露

注意:DSH 可以执行本机命令,密码泄露等于电脑控制权。密码明文保存在 config.json(权限 0600),建议用 16 位以上随机串;公网长期使用建议叠加 Cloudflare Access。

更多见 SECURITY.md。


设备会话、二维码与审计

设置页(Ctrl + , → 远程访问)现在包含:

  • 二维码:直接显示当前公网/局域网地址,手机扫码即可打开
  • 设备会话:每台登录过的设备(浏览器 + 系统、IP、最近活跃时间),可逐个撤销或撤销全部 撤销后该设备下一次请求就会被要求重新登录,不影响其他设备
  • 登录审计:设置页显示最近 10 条(接口最多返回 100 条),记录登录成功/失败、撤销、配置变更,写入 %DSH_HOME%/dsh-hub-plugin/audit.jsonl(超过 2 MB 自动轮转为 audit.jsonl.1)
会话 Cookie 名为 dsh-hub-sid,与 DSH 登录 Cookie 一起下发; 撤销只影响 Hub 的会话,不改变 DSH 本身的密钥。

跨平台支持

平台宿主形态状态
Windows桌面版 / dsh web✅ 已验证
macOS桌面版 / dsh web⚠️ 代码已适配,待真机验证
Linuxdsh web⚠️ 代码已适配,待真机验证
手机 / 平板 / 任意浏览器客户端✅ 与系统无关

跨平台适配点:

  • cloudflared 按平台/架构下载:windows-amd64.exe、darwin-amd64/arm64.tgz、linux-amd64/arm64;macOS 自动解压并 chmod 755,下载后按 GitHub Release 的 sha256 校验
  • 端口/进程扫描:Windows 用 netstat/tasklist;macOS/Linux 用 lsof/ss/ps
  • 凭据:要求 ~/.dsh/.credentials.yaml;macOS 若改用系统钥匙串,当前版本会给出明确错误
  • 独立运行:mac/Linux 用 ./dsh-hub.sh,Windows 用 dsh-hub.cmd(等价于直接 node lib/hub-cli.mjs)
  • CI:GitHub Actions 在 ubuntu / macos / windows 三平台跑语法检查 + 端到端测试(scripts/test.mjs)
macOS 桌面版:DSH 桌面端支持插件页安装时,本插件与 Windows 行为一致(宿主会直接传入端口,无需扫描)。 macOS 真机测试清单:docs/macos-testing.md

多机互控与单中心

多机互控(v0.6)

两台电脑都装本插件:

  1. 在 A 的 设置 → 远程访问 → 远程设备 里填 B 的地址(https://B... 或 http://B:19388),点「添加」
  2. 侧边栏底部出现 「远程设备」 按钮,点开是全屏浮层
  3. 浮层顶部切换设备,iframe 里就是 B 的 DSH(首次需在浮层里输入 B 的密码)
  4. 关闭浮层回到本地 DSH

边界:浮层是「远程操作对端 DSH」,不会把 B 的工作区/会话合并进 A 的侧边栏; 会话仍各自存储。对端是跨源 iframe,浏览器第三方 Cookie 策略可能要求每次重新输入 B 的密码; 需要真正的远程工作区挂载/会话同步,见路线图(依赖 DSH 核心扩展)。

单中心(共享同一批会话)

如果希望 A、B 看到同一批工作区/会话/任务:只让一台跑 DSH,另一台用浏览器打开它的地址。 同一时刻一个会话只有一个宿主写入,天然满足「A 或 B 单写」;两台各自跑本地 DSH 再同步则没有跨机租约,不保证单写。


与同类方案的区别

本插件dsh-pocketdsh-remotedsh-mobile
形态DSH 插件DSH 插件DSH 插件 + 云端手机 App
桌面版宿主✅ 直接发布兼容模式需 dsh web需 dsh web
公网通道cloudflaredcloudflared自建/云端中继relay / SSH
移动端 UI原生 Web专门适配完整 Web原生
额外账号/服务无无有relay 服务
多宿主冲突检测✅———

本插件的取舍:零第三方账号、直连桌面版、设置页一体化;移动端 UI 与原生 App 不是它的目标(可作为后续迭代)。


排错

现象处理
设置页显示「连不上宿主管理路由」确认插件已启用、桌面版已重启;必要时 Ctrl + R 刷新页面
公网 401 dsh web authentication required直接访问了不带密码的 URL;先打开登录页输入密码
设置页提示 403 / admin token required宿主与子进程版本不一致(升级后未重启桌面端);重启一次桌面端
局域网地址打不开确认手机与电脑同一 WiFi、系统防火墙放行 19388;v0.8.0 之前的版本局域网会被 403
error 1033 / 隧道连不上本机代理/VPN 的 TUN 模式可能掐断隧道;关 TUN,或给 trycloudflare.com、argotunnel.com 加直连规则
session/writer-held另一个 DSH 宿主占着会话;只保留一个宿主(桌面版或 dsh web)
端口 19388 被占用设置页改 listenPort,或先在 /_health 确认是否已有实例
桌面版重启后公网地址变了快速隧道特性;改用命名隧道固定域名

日志与状态:

  • 日志:%DSH_HOME%/dsh-hub-plugin/hub.log
  • 状态:%DSH_HOME%/dsh-hub-plugin/status.json
  • 健康检查:http://127.0.0.1:<listenPort>/_health

常见问题

Q:为什么不用 SSHJ 或 VPN? 本插件面向「手机/平板随手打开浏览器」;SSH/VPN 在鸿蒙/移动网络下的体验和配置成本更高。需要网格组网可以用 Tailscale,本插件也兼容(把地址换成 tailnet 地址即可)。

Q:要装 cloudflared 吗? 不需要手动装:插件首次建立隧道时会自动下载到 %DSH_HOME%/bin(约 53 MB)。也可以提前用 winget install --id Cloudflare.cloudflared 安装。

Q:会话会和其他设备冲突吗? 不会——所有设备访问的是同一个宿主,共享同一批会话。冲突只发生在「两个 DSH 宿主同时打开同一会话」时,插件会提示并支持停掉 extra 宿主。

Q:能同时用桌面版和 dsh web 吗? 可以,但每个会话只能有一个宿主写入(DSH 的跨进程租约)。建议只保留一个宿主。

Q:手机能免密吗? 首次输入密码后发 30 天 Cookie,期间免密;换浏览器/清 Cookie 需要重新输入。


开发

git clone https://github.com/dbssAlan/dsh-hub-plugin.git
cd dsh-hub-plugin
node --check index.js
node --check client.js
node --check lib/hub-cli.mjs
node scripts/test.mjs        # 端到端:登录/限速/撤销/管理令牌/SSRF/反代/iframe

目录:

index.js           # host 半:Config、/dsh-hub/* 同源路由、子进程生命周期
client.js          # 浏览器半:设置页(settings.section)
lib/hub-cli.mjs    # 反代/密码页/设备页/隧道(可独立运行)
lib/vendor/        # 离线二维码库
locale/            # 插件市场显示用
scripts/test.mjs   # 端到端回归测试(CI 三平台运行)

独立运行(不经插件,便于调试):

node lib/hub-cli.mjs --port 19388 --no-tunnel

独立运行会打印一个管理令牌(每次启动不同)。调试管理接口时带上:

curl -H "x-dsh-hub-admin: <令牌>" http://127.0.0.1:19388/_status

在插件模式里这个令牌由宿主注入,浏览器永远看不到,公网也调不到管理接口。

安全启动/清理测试宿主(重要)

不要按进程名杀进程——测试宿主如果也用 DeepSeek Harness.exe 启动,Get-Process -Name 'DeepSeek Harness' | Stop-Process 会把用户正在用的桌面版一起杀掉。

用仓库里的 scripts/test-host.ps1(普通 node.exe + PID 文件):

pwsh -File scripts/test-host.ps1 -Action start -Port 3099
pwsh -File scripts/test-host.ps1 -Action status
pwsh -File scripts/test-host.ps1 -Action stop

它只清理自己记录的 PID,并且拒绝杀掉非 node.exe 的进程。手工清理时也请用 PID 或端口反查,而不是进程名。


热更新(不重启桌面端)

插件运行时逻辑全在 lib/hub-cli.mjs(子进程),宿主插件只在子进程退出后重建它。因此:

改动文件生效方式
lib/hub-cli.mjs(反代/密码/隧道/设备/会话)设置页点 「重载插件」,或 POST /dsh-hub/reload,或按 PID 结束 19388 监听进程 → 宿主自动重建,无需重启 DSH
index.js(宿主路由/生命周期)需要重启桌面端一次(宿主模块代际)
client.js(设置页 UI)需要重启桌面端一次(客户端模块代际)

重载只需几秒,期间隧道会短暂断开;快速隧道会换一个新地址,命名隧道地址不变。 0.8.0 起管理令牌随宿主启动生成:升级 index.js 后必须重启一次桌面端,否则设置页会提示 403 / admin token required。

手动重载(按 PID,不要按进程名):

$line = netstat -ano | Select-String ':19388s+.*LISTENING'
if ($line) {
  $id = ([string]$line).Trim() -split 's+' | Select-Object -Last 1
  Stop-Process -Id $id -Force
}

路线图

  • [x] v0.1 插件骨架 + 设置页入口
  • [x] v0.2 设置页开关/密码/隧道,保存即生效
  • [x] v0.3 同源路由 /dsh-hub/*,不再跨端口
  • [x] v0.4 PWA(添加到主屏幕)+ 移动端安全区样式
  • [x] v0.5 设备会话与撤销、登录审计、设置页二维码
  • [x] v0.6 远程设备配对、侧边栏浮层互控(iframe)、单中心说明
  • [x] v0.7 跨平台(macOS/Linux)、浮层只占内容区、热重载
  • [x] v0.8 安全收口:管理令牌、局域网修复、SSRF/iframe/Cookie/限速、端到端测试
  • [ ] v0.9 远程设备改为同源反代(消除第三方 Cookie 限制)
  • [ ] v1.0 原生远程工作区挂载 / 跨机会话同步(需 DSH 核心扩展)

手机「添加到主屏幕」

打开远程地址并登录后,在浏览器菜单里选「添加到主屏幕」: iOS Safari 是「分享 → 添加到主屏幕」,Android/华为浏览器是「菜单 → 添加到桌面」。 添加后会以独立窗口打开(无地址栏),体验接近 App。


许可

MIT。二维码库使用 qrcode-generator(MIT),见 lib/vendor/。


English

DSH Hub is a DeepSeek Harness plugin that exposes your local DSH instance to LAN or the public internet behind an access password. It reverse-proxies the DSH host (desktop Electron or dsh web), rewrites the Host header, mints a valid session cookie, and optionally starts a cloudflared quick or named tunnel. Everything is configured from the DSH settings page (Ctrl + , → Remote Access).

Since 0.8.0, admin endpoints (/_status, /_config, /_sessions, /_peers, …) require a per-launch random token injected by the host, so tunnel traffic can no longer reach them even though it originates from 127.0.0.1. LAN access, SSRF protection, Secure cookies, iframe allow-listing and sha256-verified cloudflared downloads are included.

Install:

dsh-hub-plugin

Use DSH's plugin page (desktop) or dsh plugin --profile web add -w dsh-hub-plugin. MIT licensed.

星级评价

0.0 按 GitHub Stars 换算的社区热度,非用户打分
Stars0
Forks0
待解决 Issue0
最近更新2026-11-05

基本信息

作者dbssAlan
版本0.8.0
开源许可MIT
默认分支main
入库时间2026-11-06

插件信息来自公开 GitHub 仓库与 SkillHub,版权归原作者所有;安装前请自行审查仓库代码。