🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

多租户实例管家 DreamRift/dsh-hub

DeepSeek Harness
DreamRift72 天前有提交已提供中文文档扫描:含敏感能力

在一台服务器上为多人分配隔离的 dsh 网页实例

34.8/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/18 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查未通过:仓库根目录及浅层子目录均无 dsh 插件清单,无法用 dsh 插件安装命令安装。以下命令仍可尝试,但可能失败。
无法用 dsh 插件命令安装(仓库内无 dsh 插件清单)
git clone https://github.com/DreamRift/dsh-hub.git
按该仓库 README 的原生方式安装;若作者另行发布了 DSH 插件包,请以其文档为准

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · market
装得上吗
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 72 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/10/25) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

仓库根目录及浅层子目录均无 dsh 插件清单,无法用 dsh 插件安装命令安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-hub(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/11/3 23:24:15

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 59 处,展示前 55 条)
  • 读取本地文件
    dsh-hub/spikes/s1-reverse-proxy.mjs:28
    if (fromEnv && existsSync(fromEnv)) return [process.execPath, fromEnv];
  • 读取本地文件
    dsh-hub/spikes/s1-reverse-proxy.mjs:30
    if (existsSync(guess)) return [process.execPath, guess];
  • 发起网络请求
    dsh-hub/spikes/s1-reverse-proxy.mjs:52
    http.get({ host: HOST, port: PROXY_PORT, path }, (res) => {
  • 发起网络请求
    dsh-hub/spikes/s1-reverse-proxy.mjs:63
    const up = http.request({ host: HOST, port: targetPort, path: req.url, method: req.method, headers: req.headers }, (r) => {
  • 发起网络请求
    dsh-hub/spikes/s1-reverse-proxy.mjs:100
    const req = http.request({
  • 发起网络请求
    dsh-hub/spikes/s1-reverse-proxy.mjs:121
    const req = http.request({
  • 执行外部命令来自配置/变量
    dsh-hub/spikes/s1-reverse-proxy.mjs:142
    const child = spawn(binJs, ['web', '--host', HOST, '--port', String(DSH_PORT), '--no-open'], {
  • 删除本地文件递归
    dsh-hub/spikes/s1-reverse-proxy.mjs:189
    rmSync(home, { recursive: true, force: true });
  • 读取本地文件
    dsh-hub/spikes/s2-trusted-host.mjs:21
    try { entries = readdirSync(dir, { withFileTypes: true }); } catch { return; }
  • 读取本地文件
    dsh-hub/spikes/s2-trusted-host.mjs:27
    try { t = readFileSync(p, 'utf8'); } catch { continue; }
  • 读取本地文件
    dsh-hub/spikes/s2-trusted-host.mjs:36
    if (existsSync(rootDir)) walk(rootDir);
  • 执行外部命令固定命令
    dsh-hub/spikes/s4-npx-version.mjs:26
    const which = spawnSync('which', ['npx'], { encoding: 'utf8' });
  • 执行外部命令来自配置/变量
    dsh-hub/spikes/s4-npx-version.mjs:59
    const child = spawn(process.execPath, [npxCli, '--yes', `@deepseek-ai/dsh@${VER}`, ...args], {
  • 删除本地文件递归
    dsh-hub/spikes/s4-npx-version.mjs:108
    rmSync(home, { recursive: true, force: true });
  • 删除本地文件递归
    dsh-hub/spikes/s5-nickname-dir.mjs:49
    rmSync(ROOT, { recursive: true, force: true });
  • 写入本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:50
    mkdirSync(ROOT, { recursive: true });
  • 写入本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:56
    mkdirSync(zhDir, { recursive: true });
  • 写入本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:57
    writeFileSync(join(zhDir, 'note.txt'), '中文目录测试', 'utf8');
  • 读取本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:58
    const zhStat = statSync(zhDir);
  • 读取本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:59
    record('中文昵称直接作目录名(ext4 mkdir+读写)', existsSync(zhDir) && zhStat.isDirectory());
  • 写入本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:89
    renameSync(oldDir, newDir);
  • 读取本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:90
    record('rename() 支持中文目录改名', existsSync(newDir) && readFileSync(join(newDir, 'note.txt'), 'utf8') === '中文目录测试');
  • 读取本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:90
    record('rename() 支持中文目录改名', existsSync(newDir) && readFileSync(join(newDir, 'note.txt'), 'utf8') === '中文目录测试');
  • 写入本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:97
    mkdirSync(restore, { recursive: true });
  • 读取本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:99
    record('tar 备份/还原保留中文目录名', tar.status === 0 && untar.status === 0 && existsSync(join(restore, '张三·改名', 'note.txt')), tar.status === 0 ? '' : `tar exit
  • 读取本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:102
    const listing = readdirSync(restore);
  • 写入本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:107
    for (const sub of ['home', 'workspace', 'logs']) mkdirSync(join(inst, sub), { recursive: true });
  • 删除本地文件
    dsh-hub/spikes/s5-nickname-dir.mjs:113
    try { rmSync(join(ROOT, 'backup.tar'), { force: true }); } catch {}
  • 读取本地文件
    dsh-hub/src/db.ts:22
    if (!existsSync(dataDir)) mkdirSync(dataDir, { recursive: true });
  • 写入本地文件
    dsh-hub/src/db.ts:22
    if (!existsSync(dataDir)) mkdirSync(dataDir, { recursive: true });
  • 写入本地文件
    dsh-hub/src/db.ts:24
    chmodSync(dataDir, 0o700);
  • 写入本地文件
    dsh-hub/src/db.ts:27
    chmodSync(dbPath, 0o600);
  • 读取本地文件
    dsh-hub/src/index.ts:25
    const pkg = JSON.parse(readFileSync(join(here, '..', 'package.json'), 'utf8')) as { version?: string };
  • 读取本地文件
    dsh-hub/src/instances.ts:27
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 写入本地文件
    dsh-hub/src/instances.ts:27
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 写入本地文件
    dsh-hub/src/instances.ts:28
    chmodSync(dir, 0o700);
  • 写入本地文件
    dsh-hub/src/instances.ts:62
    for (const sub of INSTANCE_SUBDIRS) mkdirSync(join(dir, sub), { recursive: true });
  • 删除本地文件递归
    dsh-hub/src/instances.ts:68
    rmSync(dir, { recursive: true, force: true });
  • 删除本地文件递归
    dsh-hub/src/instances.ts:117
    rmSync(instanceDir(dirName, record.id), { recursive: true, force: true });
  • 读取本地文件
    dsh-hub/src/supervisor.ts:84
    if (fromEnv && existsSync(fromEnv)) return fromEnv;
  • 读取本地文件
    dsh-hub/src/supervisor.ts:86
    if (existsSync(guess)) return guess;
  • 读取本地文件
    dsh-hub/src/supervisor.ts:120
    const cmdline = readFileSync(`/proc/${pid}/cmdline`, 'utf8').replace(/ /g, ' ');
  • 写入本地文件
    dsh-hub/src/supervisor.ts:131
    mkdirSync(p, { recursive: true });
  • 写入本地文件
    dsh-hub/src/supervisor.ts:155
    writeFileSync(fd, token);
  • 读取本地文件
    dsh-hub/src/supervisor.ts:171
    if (readFileSync(path, 'utf8').trim() !== token) return;
  • 删除本地文件
    dsh-hub/src/supervisor.ts:176
    try { rmSync(path, { force: true }); } catch { }
  • 写入本地文件
    dsh-hub/src/supervisor.ts:180
    writeFileSync(instancePidfile(record), String(pid));
  • 删除本地文件
    dsh-hub/src/supervisor.ts:184
    try { rmSync(instancePidfile(record), { force: true }); } catch { }
  • 读取本地文件
    dsh-hub/src/supervisor.ts:189
    const n = Number(readFileSync(instancePidfile(record), 'utf8').trim());
  • 写入本地文件
    dsh-hub/src/supervisor.ts:199
    writeFileSync(join(logDir, `start-fail-${ts}.md`), `# 启动失败快照\n\n- 实例: ${record.id}\n- 时间: ${new Date().toISOString()}\n- 原因: ${title}\n\n\`\`\`\n${det
  • 读取本地文件
    dsh-hub/src/supervisor.ts:205
    if (!existsSync(logPath) || statSync(logPath).size <= maxBytes) return;
  • 删除本地文件
    dsh-hub/src/supervisor.ts:208
    rmSync(bak2, { force: true });
  • 写入本地文件
    dsh-hub/src/supervisor.ts:209
    if (existsSync(bak1)) renameSync(bak1, bak2);
  • 写入本地文件
    dsh-hub/src/supervisor.ts:210
    renameSync(logPath, bak1);
  • 执行外部命令来自配置/变量
    dsh-hub/src/supervisor.ts:277
    child = spawn(spawnBin, spawnArgs, {
扫描于 2026/11/3(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 单机多租户实例隔离
  • 实例认证与生命周期管理
  • 配额与审计

README

由 DeepSeek 最新模型翻译生成
DSH Hub · DeepSeek Harness 多租户多实例管理器 在单台 Linux 服务器上为多人提供各自独立的 DeepSeek Harness(dsh web)浏览器实例:网页登录、按用户隔离的昵称目录、实例生命周期(创建/启停/重启/删除/日志/孤儿回收)、管理员后台(用户管理/封禁/配额/版本白名单/审计)。 - 技术栈:Node.js ≥ 24(原生 TypeScript 运行 + 内置 node:sqlite),运行时零依赖 - 当前状态:M0–M2.1 完成(调研/脚手架/认证/生命周期/安全修复);M3 鉴权网关进行中 仓库结构 docs/ 调研笔记 / 开发计划 / Spike 验证记录 / 进展日志 dsh-hub/ 控制面实现(TypeScript 源码 + 冒烟测试 + Spike 脚本) 核心能力 | 能力 | 说明 | | 认证 | 首启向导建管理员;注册开关;session cookie(HttpOnly + SameSite=Lax + 滑动 7 天/绝对 30 天)+ Bearer API token 双轨;写操作 CSRF;登录限速(IP+昵称) | | 角色 | root(管管理员)/ admin(管用户与实例)/ user(仅自己资源);越权一律 403/404 |
展开完整文档(README 剩余 1 节)
DSH Hub · DeepSeek Harness 多租户多实例管理器

在单台 Linux 服务器上为多人提供各自独立的 DeepSeek Harness(dsh web)浏览器实例:网页登录、按用户隔离的昵称目录、实例生命周期(创建/启停/重启/删除/日志/孤儿回收)、管理员后台(用户管理/封禁/配额/版本白名单/审计)。

- 技术栈:Node.js ≥ 24(原生 TypeScript 运行 + 内置 node:sqlite),运行时零依赖
- 当前状态:M0–M2.1 完成(调研/脚手架/认证/生命周期/安全修复);M3 鉴权网关进行中

仓库结构

docs/ 调研笔记 / 开发计划 / Spike 验证记录 / 进展日志 dsh-hub/ 控制面实现(TypeScript 源码 + 冒烟测试 + Spike 脚本)

核心能力

| 能力 | 说明 |
| 认证 | 首启向导建管理员;注册开关;session cookie(HttpOnly + SameSite=Lax + 滑动 7 天/绝对 30 天)+ Bearer API token 双轨;写操作 CSRF;登录限速(IP+昵称) |
| 角色 | root(管管理员)/ admin(管用户与实例)/ user(仅自己资源);越权一律 403/404 |
| 实例 | 每实例独立 DSH_HOME + 端口(4000–4999)+ workspace;spawn dsh web 独立进程组;TCP 探活(180s)+ 失败快照 + 日志轮转;重启后孤儿认领 |
| 配额 | max_instances / max_running 事务化检查(BEGIN IMMEDIATE,并发不超配) |
| 安全 | 封禁即停实例 + 吊销会话与 token;版本白名单(仅显式 semver);进程身份校验防 pid 复用误杀;per-instance 并发互斥 |
| 审计 | 登录/建号/凭据/实例全动作入 audit_logs |

快速开始

cd dsh-hub
npm install # 仅 devDependencies(typescript/@types/node);运行时零依赖
npm run dev # 监听 127.0.0.1:3082
浏览器打开 http://127.0.0.1:3082 → POST /api/auth/setup 建首个管理员(无用户时可用)

环境变量(src/config.ts 集中定义):DSH_HUB_DATA(数据根)、DSH_HUB_HOST、DSH_HUB_PORT、
DSH_HUB_COOKIE_SECURE=1(置于 Caddy/HTTPS 后启用)、DSH_BIN、DSH_HUB_DOMAIN(trusted-host 子域后缀)、DSH_HUB_TRUST_PROXY=1。

测试

cd dsh-hub
bash scripts/m1-smoke.sh # 24 项:认证/角色/CSRF/限速/审计(自带启动 hub) bash scripts/m2-smoke.sh # 29 项:实例生命周期(真实 dsh web 实例) bash scripts/security-regression.sh # 38 项:攻击剧本回归(封禁链路/版本注入/并发/崩溃同步)
npx tsc -p . --noEmit # 类型检查

文档

- docs/01-调研笔记.md:DSH 本体事实与借鉴项目调研
- docs/02-开发计划.md:架构、API 草案、里程碑 M0–M6、风险表
- docs/03-Spike验证记录.md:S1–S5 技术验证结论(WS 隧道/trusted-host 精确匹配等)
- docs/00-进展日志.md:滚动工作状态与断点

路线图

- M3 鉴权网关:子域路由 + 所有权校验 + WS 隧道(/api/events.mux|host)+ 未运行引导页
- M4 管理员后台 UI(React + DSH 设计令牌)
- M5 加固:systemd-run 限额、per-user 账号严格模式、凭据模板、备份文档
- M6 多用户压测与故障注入、部署手册

许可

个人学习项目,公开分享;使用前请自行评估安全与合规风险。
预览分享卡片长什么样 ↓DreamRift/dsh-hub
分享 · DeepSeek Harness Hub
DreamRift/dsh-hub

在一台服务器上为多人分配隔离的 dsh 网页实例

这是你的仓库?认领条目

回到顶部