中文EN

dsh-ssh-vault

remote已测通过npmMIT

把 SSH 主机存进 AES-256-GCM 加密保险库,智能体按别名执行命令,口令经 SSH_ASKPASS 交给 ssh 而不进入命令行。仅支持 Windows。

下载量 / Downloads
753
依赖体积 / node_modules
1.89 MB
测试时间 / Tested
2026-11-07
DSH 版本 / Version
0.2.2-rc.1

安装

dsh plugin --profile web add dsh-ssh-vault

沙箱测试结果

阶段结果
1 安装✓
2 列装✓
3 挂载✓
4 启动—

四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。

README

<div align="center">

dsh-ssh-vault

简体中文 | [English](README.md)

![License: MIT](LICENSE)

![Node](package.json)

![DSH plugin](https://github.com/deepseek-ai)

![Version](package.json)

![Tests](test)

</div>

给 DeepSeek Harness 的智能体提供 SSH 能力:主机地址、端口、账号、口令与私钥都存进加密保险库,对话里只用别名。模型永远看不到口令,口令也不会出现在命令行或远端进程列表里。

简介

仅支持 Windows。 保险库数据密钥由 Windows DPAPI 保护,SSH_ASKPASS 辅助程序是 Windows 的 .cmd 包装器;插件声明了 os: ["win32"],在其它平台上直接拒绝启动,而不是把密钥退化成明文。

三个能力合在一个插件里:

  • 模型面向的工具 —— ssh_hosts、ssh_run、ssh_transfer、ssh_probe,让智能体按别名操作远端主机。
  • 设置界面 —— 在「设置 → SSH 连接」里增删改主机、测试连通性。口令经 HTTP body 提交,不进入会话日志。
  • /hosts 命令 —— 人类直接在对话里探测主机、执行命令,不必经过模型。

底层调用本机 OpenSSH 客户端(ssh / scp),不自带 SSH 协议实现。

安装

从 npm 安装。插件已发布为 dsh-ssh-vault;下面这种只写包名的形式会自动解析到 npm registry:

dsh plugin --profile desktop install dsh-ssh-vault

需要固定版本或离线安装时,先用 npm 拉取 tarball,再把文件交给同一条命令:

npm pack dsh-ssh-vault        # 在当前目录生成 dsh-ssh-vault-<version>.tgz
dsh plugin --profile desktop install ./dsh-ssh-vault-<version>.tgz

从本地目录安装。参数是路径,已经在插件目录里时直接用 .:

# 在插件目录内执行
dsh plugin --profile desktop install .

# 或从别处指向该目录
dsh plugin --profile desktop install ../dsh-ssh-vault

# 或从打包好的 tarball 安装
dsh plugin --profile desktop install ./dsh-ssh-vault-<version>.tgz

需要 --profile。 DSH 按 profile 隔离插件集,同一台机器可以有多个 profile(如 desktop 与 cli)。不指定时取决于当前默认 profile,容易出现「装到了别处」。装完用下面的命令确认落点:

dsh plugin --profile desktop list

安装完成后重启 DSH。Host 侧的工具与路由在重启后才会加载。

本插件仅支持 Windows。 package.json 声明了 os: ["win32"],因此在 Linux / macOS 上 dsh plugin ... install 会直接拒绝安装;从源码加载也会因为同样的原因拒绝启动(见[已知限制](#平台与认证))。

环境要求

项 · 要求

Node · ≥ 20

本机 · Windows 10 / 11,且启用 OpenSSH 客户端(ssh -V 能输出版本)

平台 · 仅 Windows(win32)——Linux / macOS 上安装与加载都会被拒绝

快速开始

1. 安装并重启 DSH。

2. 打开 设置 → SSH 连接,点「添加连接」,填别名、地址、端口、账号,选择口令或私钥认证。

卡片上的圆点会自动体检:灰=未检测、黄=检测中、绿=连通、红=不通。

3. 在对话里说一句话,例如:

   用 kali 跑一下 uptime

模型会调用 ssh_run,结果以终端卡片出现在对话中。

口令不要写在对话里。设置界面录入的口令直接进加密保险库,不经过模型上下文。

使用方式

模型调用工具

工具 · 用途 · 典型说法

ssh_hosts · 管理保险库(list / show / add / update / remove) · 「有哪些主机」「改一下 kali 的备注」

ssh_run · 在主机上执行命令,返回 stdout 与 stderr · 「在 kali 上看看磁盘占用」

ssh_transfer · 上传或下载文件(scp),可选 sudo 读写 · 「把这个文件传到 kali 的 /tmp」

ssh_probe · 连接自检,回读系统与能力信息并写入主机元数据 · 「kali 还连得上吗」

ssh_tunnel · 维护本地端口转发(ssh -L) · 「把 kali 的 8787 映射到本地 18787」

ssh_run 的几条约定:

  • 显式 shell 包装。 POSIX 目标默认用 bash --norc -c '<command>':命令固定由 bash 解析一次,不会落到远端登录 shell(fish/zsh)上被改写成另一个意思。login_shell: true 改用 bash -lc(需要 profile 里定义的 PATH 时)。返回里的 remoteShell 会说明这次实际用了什么。

--norc 不是可有可无的:RHEL/CentOS 的 bash 打了 SSH_SOURCE_BASHRC 补丁,SSH 会话里非交互 bash 也会 source ~/.bashrc,用户 .bashrc 里一条失败的 source 就会让每条命令的 stderr 多一行噪声,进而干扰失败诊断。

  • 命令数组。 command_array: ["find", ".", "-name", "*.log"] 会逐元素引号化,远端 shell 不做分词、通配或变量展开,彻底避开双层 shell 的引号陷阱。
  • sudo 三态。 sudo: true 自动选形态;sudo: "wrap" 把整条命令包成 sudo -n bash -c '...';sudo: "script" 写临时脚本再以 root 执行——heredoc、管道、后台任务、多行流程都不会在提权边界上变形,脚本执行完即删,口令经 base64 管道喂给 sudo -S,两端命令行与远端 ps 都看不到;sudo: "prime" 只预热缓存,命令里照旧自己写 sudo。口令始终来自保险库。用了任一形态后不要在命令里再写 sudo。
  • 错误分类。 失败时附一行类别标签(连接 / 认证 / sudo / 远端命令 / 输出截断);sudo 失败还会细分「需要密码 / 不在 sudoers / 没有 sudo」并给出修复命令。
  • 大输出落盘。 超过上限时响应只保留摘要,完整内容写进保险库目录下的 outputs/,并把绝对路径附在结果里。

ssh_transfer 在 scp 之上补了三件事:sudo: true 读写 root-only 文件(远端临时文件中转 + 自动清理);normalize_eol: true 上传前把 CRLF 规范成 LF(Windows 上写的脚本在远端不会报 $'\r': 未找到命令,二进制文件自动跳过);mode / owner / preserve_mode 设置远端权限与属主。

ssh_tunnel 在开隧道之前先读远端 sshd -T 的转发策略:AllowTcpForwarding no 时直接给出「用 sshd_config 的 Match User <user> 放行 LocalForwarding、不要全局改」的可粘贴片段与 PermitOpen 说明,而不是等撞上 administratively prohibited。它维护隧道生命周期(本地端口占用预检、断线事件、指数退避重连、插件卸载时清理),并返回本地可用地址。

在哪里看到效果: ssh_run / ssh_probe / ssh_transfer / ssh_tunnel 的调用会渲染成终端卡片——标题栏是「主机 · 命令」加一个状态点,下方是可滚动的等宽输出区。状态点:蓝=运行中、灰=成功、红=失败(含非零退出码)。

设置界面

「设置 → SSH 连接」提供:

  • 主机列表,含连通状态圆点,悬停看详情
  • 添加 / 编辑 / 删除连接(编辑时别名可改,凭据随之搬迁)
  • 每张卡的「测试连接」,结果同时反映到圆点
  • 「用资源管理器打开」保险库目录
  • 口令认证与私钥认证;私钥可整份上传,由宿主写入保险库并收紧权限

界面语言

插件显示的所有文字都跟随 设置 → 常规 → 语言,这里没有另一套开关。

  • 设置页与对话内的 SSH 卡片从宿主的 locale 服务取词,语言一换立刻跟着变。
  • /hosts 输出、连接诊断、设置接口错误、保险库错误与后台任务状态都由 Host 生成;它们读取同一个持久偏好(locale.preference)并跟随之后的切换,只有在从未选择过语言时才退回请求的 Accept-Language。
  • 面向模型的定义保持英文:工具名、描述与参数 schema 属于模型接口,而不是界面。

/hosts 命令

在输入框里以 / 开头,命令不经模型直接执行。

/hosts                    列出全部主机,按在线 / 离线分组
/hosts kali               探测一台
/hosts kali,win10         探测多台(中英文逗号都行)
/hosts kali; apt update   在 kali 上执行命令
/hosts kali,win10; uptime 在每台可达主机上执行
  • 分隔符支持中英文:, 与 ,、; 与 ;
  • 分号后如果写的是自然语言(例如「帮我看看磁盘」),命令不会执行,会提示你直接把它发给对话——命令的产出不回流给模型,这类请求不能走命令
  • 输出渲染为两张卡片:连接状态、命令执行,各自独立亮灯
  • 在 / 菜单里选中 /hosts 只是「认领」这个命令:输入框里出现命令 token 与提示。再按一次回车=无参执行(列出主机);或者接着输入 别名; shell 命令 作为它的参数。想回到普通提示词,删掉这个命令 token 即可——在那之前输入的内容都会被当作命令参数
  • 首条消息之前,结果显示在输入框上方。 DSH 把「整段记录只有命令行」的会话视为非活跃视图,所以全新会话里单独跑 /hosts 以前看起来像「什么都没发生」,要等发出第一条消息才看到卡片。插件现在会在会话仍空白时把这些 /hosts 卡片(含运行中状态)镜像到输入框上方的 dock;首条消息发出后由对话区接管,不会重复显示
  • 无参执行只在体检缓存为空时现测,且并行、总预算 4 秒;即使多台主机不可达也能在几秒内给出结果

架构

双端形态

这是 Host + Client 双端插件,两半由不同机制加载:

半边 · 入口 · 加载方式

Host · index.js · Cordis 插件,经 cordis.patch.yml 插入 Loader

Client · client.js · 浏览器模块,经 package.json 的 dsh.client 声明后由宿主注入页面

Host 承担全部敏感操作:保险库加解密、调用本机 ssh、Web 路由、命令与工具注册。

Client 只做呈现与表单,不直接执行任何命令。

数据流

flowchart TB
    subgraph entry [入口]
        chat[对话 / 模型工具调

…(truncated)

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:3,最后更新 2026-11-01

链接

GitHub · Homepage · npm

同类插件