dsh-lab-ssh
English | 简体中文
面向 DeepSeek Harness 和标准 MCP 客户端的受控 SSH 开发插件。
它适用于这样的实验室环境:AI Agent 运行在可联网的个人电脑或工作站上,通过 SSH 使用内网服务器的 GPU、运行环境和指定代码工作区;服务器本身可以保持无法访问公网。
> 当前版本:0.3.0,实验性试用阶段。DeepSeek Harness 仍处于开发预览期,建议固定已经验证的运行时版本。
本项目是独立的社区插件,不是 DeepSeek AI 官方软件包。

解决什么问题
直接把普通 SSH 终端交给 Agent 会同时开放任意主机、任意目录和任意命令,也容易让密码、私钥、内网地址或敏感输出进入模型上下文。
本项目在 Agent 与 SSH 之间增加一层默认拒绝的策略边界:
- Agent 只能选择管理员登记的主机别名,不能提交任意 IP 或域名;
- SSH 主机公钥必须匹配固定的 SHA256 指纹;
- 密码只从环境变量读取,私钥只从本机文件或 SSH Agent 读取;
- 命令必须命中白名单,危险命令会被全局拒绝;
- 文件只能通过目录别名访问,绝对路径和目录穿越会被拒绝;
- 可按目录决定文本写入是否需要审批;
- 可在登记的工作区别名内执行白名单命令;
- 可选的制品桥可以把联网电脑下载并校验的文件转运到离线服务器;
- DeepSeek Harness 与 Codex MCP 可以共享同一份 JSON 策略。
当前能力
| 能力 | 状态 |
|---|---|
| DeepSeek Harness 插件 | 已实现 |
| 标准 stdio MCP 服务 | 已实现 |
| 固定主机别名与 SSH 指纹校验 | 已实现 |
| 密码、私钥、SSH Agent 认证 | 已实现 |
| 命令白名单、自动批准与拒绝规则 | 已实现 |
| stdout/stderr、超时和输出大小限制 | 已实现 |
| 受限目录列表和 UTF-8 文本读取 | 已实现 |
| SHA256 并发保护与原子文本写入 | 已实现 |
| 基于目录别名的命令工作目录 | 已实现 |
| HTTPS + 域名白名单 + SHA256 制品转运 | 第一版已实现,默认关闭 |
| 可视化短期凭据会话 | 仅原型 |
| 持久化审计、角色权限和集中策略 | 尚未实现 |
| 目录批量同步、断点续传和依赖闭包 | 尚未实现 |
自动化测试目前包含 9 个测试文件、25 项测试,覆盖命令策略、路径边界、工作目录包装、SFTP 原子写入、制品入口策略、SSH 认证和主机指纹拒绝。测试不会连接真实实验室服务器或访问公网。
安全模型
固定连接范围
配置中的 name 是模型可见的主机别名。真实地址、主机指纹、凭据变量名和私钥路径不会通过发现工具返回。
命令默认拒绝
远程命令必须完整命中 allowCommands,并且不能命中主机级或全局拒绝规则。内置规则会拒绝典型的递归强制删除、磁盘格式化、覆盖块设备、关机、重启和 fork bomb。
workdir 只负责进入登记过的目录,然后执行独立通过白名单检查的命令。选择工作区不会获得任意 Shell 权限。
文件目录隔离
文件工具只接受目录别名和相对 POSIX 路径。插件会进行规范化路径检查、真实路径检查和符号链接越界检查。
替换已有文本文件必须携带最近一次读取返回的 SHA256。插件先写入独占临时文件,再进行原子替换,防止部分写入和静默覆盖并发修改。
凭据隔离
不要把密码、私钥内容或口令写入 JSON、YAML、TOML、.env、提示词或聊天消息。配置只保存环境变量名、私钥文件路径或 SSH Agent 地址。
保持服务器离线
插件不提供 SOCKS/HTTP 代理、SSH 端口转发、反向隧道或 Agent 转发。可选制品桥在联网电脑上下载 HTTPS 文件,逐跳检查重定向域名,限制大小并强制验证 SHA256,然后原子新建到显式授权的远程目录。
环境要求
- Node.js
^22.19或>=24; - DeepSeek Harness
0.1.0-rc.7或兼容的0.1.x版本; - 使用
dsh plugin时,pnpm位于PATH。
快速开始
1. 构建插件
Set-Location <PLUGIN_DIR>
npm install
npm run build2. 创建私有配置
不要在仓库里直接维护真实服务器配置。把示例复制到用户私有目录:
New-Item -ItemType Directory -Force "$HOME/.dsh" | Out-Null
Copy-Item "<PLUGIN_DIR>/examples/lab-ssh.config.example.json" "$HOME/.dsh/lab-ssh.private.json"
notepad "$HOME/.dsh/lab-ssh.private.json"替换示例中的主机地址、用户名、指纹、认证引用、工作区和命令策略。真实配置文件应限制为当前用户可读,并且不得提交到版本库。
3. 安装到 web profile
npx -y @deepseek-ai/dsh@0.1.0-rc.7 plugin --profile web add <PLUGIN_DIR>然后在 DSH 用户 patch 中指定私有配置:
- id: lab-ssh
config:
configFile: C:/Users/<USER>/.dsh/lab-ssh.private.json4. 设置凭据并启动
$env:LAB_SSH_GPU01_PASSWORD = '<仅在本机输入>'
npx -y @deepseek-ai/dsh@0.1.0-rc.7 web修改 TypeScript 后需要重新执行 npm run build;修改插件配置后需要重启 DSH。
完整的首次使用流程见 [快速使用说明](docs/QUICKSTART.zh-CN.md)。
工具
| 工具 | 用途 |
|---|---|
ssh_list_hosts | 列出脱敏后的主机别名 |
ssh_list_file_roots | 列出目录别名、访问级别和写入策略 |
ssh_list_directory | 列出授权目录下的条目 |
ssh_read_file | 读取有上限的 UTF-8 文本并返回 SHA256 |
ssh_write_file | 创建或原子替换授权目录中的 UTF-8 文本 |
ssh_exec | 在固定主机和可选工作区别名中执行白名单命令 |
ssh_stage_artifact | 经审批下载、校验并转运一个二进制制品 |
当前不提供交互式 Shell、任意文件传输、删除、移动、改权限、后台命令、端口转发或任意网络目标。
配置示例
完整示例见 [examples/lab-ssh.config.example.json](examples/lab-ssh.config.example.json)。核心结构如下:
{
"approvalMode": "unless-auto-approved",
"hosts": [{
"name": "gpu01",
"hostname": "gpu01.internal.example",
"port": 22,
"username": "researcher",
"hostKeySha256": "SHA256:<VERIFIED_FINGERPRINT>",
"passwordEnv": "LAB_SSH_GPU01_PASSWORD",
"fileRoots": [{
"name": "workspace",
"description": "Personal development workspace",
"path": "/srv/lab/workspaces/researcher/project",
"access": "read-write",
"writeApproval": "never",
"artifactUpload": false
}],
"allowCommands": [
"^(pwd|hostname|whoami|uptime|date)$",
"^ls(?: -[A-Za-z]+)*$",
"^git status(?: --short)?$"
],
"autoApproveCommands": [
"^(pwd|hostname|whoami|uptime|date)$",
"^ls(?: -[A-Za-z]+)*$",
"^git status(?: --short)?$"
],
"denyCommands": []
}]
}不要为了方便加入 .*。对构建、测试、训练或服务管理命令,应按照项目和参数设计精确规则。
审批策略
approvalMode 控制 DeepSeek Harness 中的命令审批:
always:所有白名单命令都审批;unless-auto-approved:只有命中autoApproveCommands的命令免审批;never:所有白名单命令免审批,拒绝规则仍然生效。
每个目录的 writeApproval 独立控制文本写入:
always:每次写入审批;never:免逐次审批,只应用于个人、可恢复的开发工作区。
ssh_stage_artifact 始终需要审批。Codex 的 MCP 审批由 .codex/config.toml 独立控制。
离线制品桥
制品桥默认关闭。启用时需要同时配置:
1. artifactBridge.enabled: true; 2. artifactBridge.allowedDomains; 3. 目标根目录为 read-write; 4. 目标根目录设置 artifactUpload: true; 5. 每次调用提供从可信发布渠道独立核验的 SHA256。
第一版只处理单个、已知 URL 和哈希的文件,默认上限为 64 MiB、配置最大为 256 MiB。现阶段不提供缓存、目录同步、依赖解析、分块上传或断点续传。
Codex MCP 接入
项目包含安全空配置 config/lab-ssh.empty.json 和项目级 .codex/config.toml。构建后,在可信项目中重新加载 Codex 即可发现 MCP 服务。正式使用时,应让私有 Codex 配置指向仓库外的真实 JSON,而不是把真实配置提交到项目。
MCP 服务器也可以直接启动:
node <PLUGIN_DIR>/lib/mcp-server.js --config <PRIVATE_CONFIG_PATH>Codex 默认对 ssh_exec、ssh_write_file 和 ssh_stage_artifact 提示审批;只读发现和读取工具可自动批准。
开发与验证
npm install
npm run typecheck
npm test
npm run build
npm run pack:checkWindows 上还可以从 GitHub 重新克隆到系统临时目录,完成一次不复用当前依赖、构建产物、DSH profile 或私有 SSH 配置的干净环境验收:
powershell -ExecutionPolicy Bypass -File scripts/clean-room-test.ps1脚本会使用 hosts: [] 的默认配置,依次执行 npm ci、类型检查、测试、构建、打包检查、隔离 profile 插件安装和 DSH Web HTTP 健康检查。默认使用端口 3180,结束后停止测试进程并删除临时目录。传入 -KeepWorkdir 可以保留现场排查失败。
npm run pack:check 可以查看实际发布包内容。发布前还应执行敏感信息扫描,并确认真实配置、日志、缓存、私钥和 .env 没有进入包或版本库。
项目结构
src/ 插件、MCP、SSH、SFTP 和策略实现
tests/ 单元测试与隔离 SSH 集成测试
examples/ 无真实基础设施信息的配置示例
docs/ 使用说明
config/ 安全空配置;真实部署配置应放在仓库外路线图
- 本机可视化短期凭据会话与系统凭据库;
- 结构化审计、角色权限和集中策略;
- 基于 diff/patch 的文本编辑;
- 审批控制的 mkdir、移动和删除;
- 长任务进度、取消和结果分页;
- Python wheelhouse、Git 归档和 npm 离线缓存工作流;
- 制品清单、缓存、分块、断点续传和传输后复核;
- 多主机、GPU、Slurm 和 Kubernetes 结构化适配器;
- DeepSeek Harness 兼容矩阵、CI 和安全发布流程。
发布与隐私
公开发布前请阅读 [SECURITY.md](SECURITY.md)。仓库默认忽略真实 SSH 配置、.env、构建产物、测试 profile 和压缩包。不要仅依赖 .gitignore;发布前仍应检查 Git 历史和 npm pack --dry-run 输出。
许可证
MIT