dsh-admin

August 25, 2026 · View on GitHub

面向局域网(Docker 部署)的多租户 DSH 托管平台 —— 部署到一台内网服务器后,多个用户注册并经管理员审核,各自获得一套相互隔离DeepSeek Harness(DSH)环境,通过 http://<内网IP>:<端口> 访问。

DSH 插件市场 的 cordis-plugin 形态分发,遵守 STANDARD.md

内网无外网环境下,插件市场与插件管理所需的离线插件包可由 dsh-plugin-offline-packager 提供。

它解决什么

DSH 本身是单用户本地工具,没有认证、没有多租户隔离、Web 远程访问缺认证层。dsh-admin 在其之上补一层服务端登录 + 多租户编排:管理员审核注册用户,每个用户落到自己的文件桌面,按文件夹启动 DSH、选择启用哪些插件,在局域网内访问,且彼此文件隔离(已适配手机端)。

核心能力

  • 登录与审核:管理员先行(bootstrap-admin),用户注册后需管理员审核通过;注册开关与邀请码可由管理员随时调整;独立管理台 UI。
  • 账号与会话安全:用户自助改密(其他设备会话自动吊销)、登录设备列表与按设备吊销;管理员可重置用户密码、彻底删除用户(含全部数据);审计日志(登录/审核/改密/插件安装等全动作,可筛选分页)。
  • 每用户隔离的 DSH 环境:主 DSH 负责正常工作;崩溃时按需拉起一次守护 DSH 修复并自动重启;连续崩溃自动熔断(指数退避 + 上限,默认 5 次)后停止重拉、可手动恢复;装插件重启时守护执行主 DSH 给出的 post-restart 命令。
  • 登录桌面:桌面为「DSH / 文件 / 管理」分组启动坞 + 独立「当前文件夹」内容区(大量文件时内部滚动;图标右键菜单支持打开/重命名/移动/下载/删除/属性;各窗口按内容预设尺寸并记忆位置,底部任务栏含管理入口);文件资源管理器(文件/文件夹上传含目录结构、新建、重命名、移动、删除、预览[文本/图片/音视频/PDF]、文本在线编辑保存、文件夹 zip 打包下载、列表排序与全工作区搜索);按文件夹启动/停止/重启 DSH(DSH 窗口显示当前 dsh CLI 版本);每文件夹独立勾选启用的插件(自动检测该用户 profile 中已安装的插件,持久化并注入 cordis patch)。
  • 插件/技能离线市场:管理员上传 GitHub 归档(.tar.gz)收录插件(cordis-plugin)/技能(SKILL.md)/agent 预设,用户在桌面一键安装/更新/卸载到自己的 DSH 环境(自动注册 cordis patch,重启生效)。
  • 内网直连访问DSH_ADMIN_PUBLIC_HOST=<内网IP> + 固定子 DSH 端口段,Docker 直接发布端口;每实例内置 forwarder(剥 Origin / 注入 randomUUID polyfill / 改写 loopback 门 / per-instance 访问令牌门禁)保证非安全上下文可用且不绕过登录。
  • 运维面板:全局实例视图(谁在跑、端口、重启次数、单停不禁号)、每用户磁盘用量统计、/healthz 探活(Docker HEALTHCHECK 已接入);DSH 窗口与运维面板显示当前 dsh CLI 版本(dsh --version 探测,约 1 分钟缓存,免重建热更新 dsh 后自动跟进)。
  • 共享模型配置:管理员统一维护提供方与凭据,用户在桌面一键接收,叶子级合并进自己的 settings.yaml / .credentials.yaml
  • 硬隔离(Linux):每用户独立 OS 账号(setuid 降权),0700 目录真正隔离跨用户读。

架构总览

用户浏览器 → http://<内网IP>:3080 → 编排服务(Fastify + SQLite,单进程)
                                      ├─ 认证 / 审核 / 桌面 / 共享配置 API
                                      └─ http://<内网IP>:<子端口> → forwarder → 子 DSH(127.0.0.1)
每用户子 DSH(主 + 按需守护)只绑回环端口,由 per-instance forwarder 发布到容器 eth0。

编排服务以 child_process 按用户 spawn DSH 子进程,端口随机分配、崩溃自动重启。完整设计见 docs/blueprint.md

快速开始

npm install
npm run build                                        # tsc → lib/
node lib/cli.js bootstrap-admin --username admin --password '<强密码>' --db ./dev.local.db
node lib/cli.js --port 3080 --db ./dev.local.db

访问 http://127.0.0.1:3080/:登录 / 注册 / 管理台 / 桌面(Docker 内网部署流程见 docs/deployment-docker.md)。

配置

环境变量默认说明
DSH_ADMIN_PORT3080编排服务绑定端口
DSH_ADMIN_DATA_ROOT~/.dsh-admin每用户 home/workspace 根(生产 /var/lib/dsh-admin
DSH_ADMIN_DSH_BINdsh子 DSH 启动命令;支持带双引号的命令串(Windows 用 node "<dsh 路径>",见 troubleshooting)
DSH_ADMIN_ISOLATION_MODEsoftsoft 软隔离 / account 账号级硬隔离(Linux,需 root)
DSH_ADMIN_BASE_UID100000账号级隔离的 uid 基数
DSH_ADMIN_PUBLIC_HOST内网 IP;设置后 DSH 链接生成为 http://<内网IP>:<子端口>/?dsh_token=<实例令牌>
DSH_ADMIN_DSH_PORT_MIN/MAX0子 DSH 端口段(Docker 端口映射范围需一致)
DSH_ADMIN_PORT_GUARDfalse回环端口守卫(iptables OUTPUT owner-match,Linux + root,防跨用户直连子 DSH)
DSH_ADMIN_TRUST_PROXYfalse仅当部署在自控反向代理后设 true(否则 X-Forwarded-For 可伪造 rate-limit 键);也可传代理 CIDR 列表
DSH_ADMIN_MAX_FILE1073741824单个上传文件上限(字节,默认 1 GiB);上传走 multipart 流式,不受 JSON body 限制
DSH_ADMIN_PREVIEW_MAX262144文本预览最多读取的字节数(超出截断并提示)
DSH_ADMIN_RESTART_BACKOFF1000崩溃自动重启的基准退避(毫秒,指数增长、封顶 30s)
DSH_ADMIN_MAX_AUTO_RESTARTS5连续自动重启熔断上限(0 = 不熔断);熔断后状态停在 crashed,可手动再启动

其余可调项(dshCommandspawnAsUserCommandrestartBackoffMssessionTtlSecondsmaxUploadBytes 等)见 src/config.ts 与各文档。

文档

开发与测试

npm run build          # tsc → lib/
npm run typecheck      # 仅类型检查
npm run smoke          # 端到端冒烟(fake-dsh 模拟子 DSH)
npm run smoke:dsh-crash        # 崩溃残留清理 + 自动重启
npm run smoke:account         # 注册门禁 / 改密 / 会话 / 审计 / 删用户
npm run smoke:ops             # healthz / 实例视图 / 磁盘统计 / 崩溃熔断
npm run smoke:market          # 插件市场 导入判定 / 安装 / 更新 / 卸载
npm run smoke:shared-config   # 共享配置合并 / 删除同步 / 凭据不下发
# 其余:smoke:auth / smoke:admin / smoke:fs / smoke:plugins / smoke:watchdog / smoke:isolation

代码约定

  • 请求路径文件 IO 一律用 node:fs/promisesstatSync/mkdirSync/writeFileSync 只允许出现在启动/CLI 冷路径);SQLite 沿用 better-sqlite3 的同步模式。
  • 每用户目录布局统一从 src/fs/workspace.ts 取(workspaceRoot / userHomeDir / ensureUserDir),不要手拼 users/<id>/… 路径。
  • 路由 prologue 统一用 resolveUserPath()src/web/middleware/fs-guard.ts):workspace 根 + 越界防护一步完成。
  • 冒烟脚本的 assert / json / sleep / cleanupscripts/helpers.mjs 导入,勿再复制。
  • 前端桌面页的窗口拖拽/缩放/任务栏逻辑在 web/window-manager.js,文件资源管理器(表格/对话框/上传/预览)在 web/file-explorer.js;插入用户可控文本必须过 esc() 转义。

安全

默认软隔离(每用户 $DSH_HOME + session cwd + 沙箱写隔离)。Linux 部署建议开启账号级硬隔离(每用户 OS 账号,闭合同 UID 越权读)。详见 docs/hard-isolation.md

二次开发声明

本项目(dsh-admin)基于以下项目二次开发而来,面向 Docker + 局域网 部署场景重构与增强,感谢上游项目的开源贡献:

许可证

MIT