让智能体通过别名远程执行命令并传输文件
30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/24 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Dalld/dsh-ssh-plugin该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
是什么
dsh 原生插件 · dev
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 8 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 45 处,展示前 45 条)
- 读取本地文件index.js:183
raw = readFileSync(file, 'utf8') - 写入本地文件index.js:302
mkdirSync(baseSettings.dataDir, { recursive: true }) - 发起网络请求index.js:328
outcome = await approval.request({ - 发起网络请求client.js:83
const response = await fetch(api('/dsh-ssh/api'), { - 读取本地文件lib/transport.js:25
ssh2Version = JSON.parse(readFileSync(require.resolve('ssh2/package.json'), 'utf8')).version - 读取本地文件lib/transport.js:213
knownHostsCount = parseKnownHosts(await readFile(path.join(settings.dataDir, 'known_hosts'), 'utf8')).length - 读取本地文件lib/transport.js:228
await readFile(String(host.keyPath)) - 读取本地文件lib/settings.js:64
const raw = readFileSync(file, 'utf8') - 写入本地文件lib/settings.js:81
mkdirSync(base.dataDir, { recursive: true }) - 写入本地文件lib/settings.js:82
writeFileSync(file, `${JSON.stringify(overlay, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 }) - 写入本地文件lib/audit.js:18
await mkdir(settings.dataDir, { recursive: true }) - 写入本地文件lib/audit.js:30
await appendFile(fileOf(), line, { encoding: 'utf8', mode: 0o600 }) - 读取本地文件lib/audit.js:36
const info = await readFile(fileOf(), 'utf8') - 写入本地文件lib/audit.js:40
await writeFile(fileOf(), `${kept.join('\n')}\n`, { encoding: 'utf8', mode: 0o600 }) - 读取本地文件lib/audit.js:48
const raw = await readFile(fileOf(), 'utf8') - 执行外部命令来自配置/变量lib/shell.js:118
child = spawn(argv[0], argv.slice(1), { - 读取本地文件lib/api.js:261
text = readFileSync(file, 'utf8') - 写入本地文件lib/api.js:279
await mkdir(settings.dataDir, { recursive: true }) - 写入本地文件lib/api.js:283
await copyFile(file, `${file}.bak`) - 写入本地文件lib/api.js:288
await writeFile(tmp, body, { encoding: 'utf8', mode: 0o600 }) - 写入本地文件lib/api.js:289
await rename(tmp, file) - 读取本地文件lib/api.js:294
const raw = await readFile(path.join(settings.dataDir, 'hosts.json'), 'utf8') - 读取本地文件lib/hostkey.js:59
return parseKnownHosts(await readFile(this.file, 'utf8')) - 写入本地文件lib/hostkey.js:84
await mkdir(this.getSettings().dataDir, { recursive: true }) - 写入本地文件lib/hostkey.js:85
await writeFile(this.file, `${filtered.join('\n')}\n`, { encoding: 'utf8', mode: 0o600 }) - 写入本地文件lib/hostkey.js:95
await mkdir(this.getSettings().dataDir, { recursive: true }) - 写入本地文件lib/hostkey.js:97
await writeFile(this.file, body, { encoding: 'utf8', mode: 0o600 }) - 读取本地文件lib/transport-ssh2.js:53
const entries = await readdir(dir, { withFileTypes: true }) - 读取本地文件lib/transport-ssh2.js:330
const info = await stat(options.localPath).catch(() => undefined) - 读取本地文件lib/transport-ssh2.js:358
const local = hashBuffer(await readFile(options.localPath)) - 写入本地文件lib/transport-ssh2.js:369
await mkdir(options.localPath, { recursive: true }) - 读取本地文件lib/transport-ssh2.js:381
const info = await stat(options.localPath) - 读取本地文件lib/transport-ssh2.js:384
const local = hashBuffer(await readFile(options.localPath)) - 写入本地文件lib/transport-ssh2.js:411
await mkdir(localPath, { recursive: true }) - 写入本地文件lib/transport-openssh.js:62
await writeFile(file, pem, { encoding: 'utf8', mode: 0o600 }) - 写入本地文件lib/transport-openssh.js:70
await mkdir(dir, { recursive: true }) - 写入本地文件lib/transport-openssh.js:72
await writeFile(file, '#!/bin/sh\nprintf \'%s\' "$DSH_SSH_ASKPASS_VALUE"\n', { encoding: 'utf8', mode: 0o700 }) - 删除本地文件递归lib/transport-openssh.js:121
await rm(entry.dir, { recursive: true, force: true }) - 写入本地文件lib/transport-openssh.js:132
await mkdir(path.join(settings.dataDir, 'cm'), { recursive: true }) - 读取本地文件lib/transport-openssh.js:175
const info = await stat(options.localPath).catch(() => undefined) - 读取本地文件lib/transport-openssh.js:193
const local = createHash('sha256').update(await readFile(options.localPath)).digest('hex') - 读取本地文件lib/transport-openssh.js:220
const info = await stat(options.localPath) - 读取本地文件lib/transport-openssh.js:223
const local = createHash('sha256').update(await readFile(options.localPath)).digest('hex') - 读取本地文件lib/auth.js:33
await access(file) - 读取本地文件lib/auth.js:37
const pem = await readFile(file, 'utf8')
扫描于 2026/10/31(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
为 DeepSeek Harness 智能体提供 SSH:通过 SSH 执行命令、传输文件,私钥始终留在 Host 进程内。
README
由 DeepSeek 最新模型翻译生成dsh-ssh-plugin
给 DeepSeek Harness(DSH) 智能体用的 SSH 能力:执行命令、上传下载文件,私钥/口令不进入模型上下文。
自带侧栏面板:主机管理、连接测试与连接日志、命令黑名单、危险命令策略、审计记录。
- 传输层:ssh2(默认,跨平台一致、连接复用、原生 SFTP)+ 系统 OpenSSH(可选后端)
- 形态:DSH bundle(Host 半区 + Client 半区),一个包同时提供工具与 UI
- 依赖:仅 ssh2;缺失时自动降级到系统 OpenSSH 客户端
1. 它解决什么问题
让智能体能直接操作服务器(部署、排障、传文件),但模型永远看不到密钥:
| 角色 | 能看到什么 |
| 模型 / 对话 | 只有主机别名(如 9929)和命令输出 |
| 浏览器面板 | 别名、地址、认证引用名(环境变量名 / 凭据名 / 私钥路径),不回显密钥内容 |
| Host 进程 | 真正的私钥与口令;只在本机内存里用于握手 |
2. 快速开始(3 步)
1. 安装(见 §3)→ 刷新 DSH 页面 → 左侧栏出现 SSH 图标
2. 加主机:面板「新增」→ 填别名/地址/用户 → 认证方式选「直接粘贴私钥」或「直接输入密码」→ 测试连接 → 保存
3. 让智能体干活:在对话里说
展开完整文档(README 剩余 1 节)
dsh-ssh-plugin 给 DeepSeek Harness(DSH) 智能体用的 SSH 能力:执行命令、上传下载文件,私钥/口令不进入模型上下文。 自带侧栏面板:主机管理、连接测试与连接日志、命令黑名单、危险命令策略、审计记录。 - 传输层:ssh2(默认,跨平台一致、连接复用、原生 SFTP)+ 系统 OpenSSH(可选后端) - 形态:DSH bundle(Host 半区 + Client 半区),一个包同时提供工具与 UI - 依赖:仅 ssh2;缺失时自动降级到系统 OpenSSH 客户端 1. 它解决什么问题 让智能体能直接操作服务器(部署、排障、传文件),但模型永远看不到密钥: | 角色 | 能看到什么 | | 模型 / 对话 | 只有主机别名(如 9929)和命令输出 | | 浏览器面板 | 别名、地址、认证引用名(环境变量名 / 凭据名 / 私钥路径),不回显密钥内容 | | Host 进程 | 真正的私钥与口令;只在本机内存里用于握手 | 2. 快速开始(3 步) 1. 安装(见 §3)→ 刷新 DSH 页面 → 左侧栏出现 SSH 图标 2. 加主机:面板「新增」→ 填别名/地址/用户 → 认证方式选「直接粘贴私钥」或「直接输入密码」→ 测试连接 → 保存 3. 让智能体干活:在对话里说 连接 9929,帮我部署这个服务 https://github.com/xxx/yyy 模型会自己调用 ssh_hosts / ssh_exec / ssh_put,全程只用别名。 3. 安装与部署 三种方式,按「能否联网」「是否愿意批构建脚本」选。完整版见 DEPLOY.md。 方式 A:拷贝自带依赖的目录(推荐,离线可用) 在有网络的机器上先构建一次(会生成 dist/dsh-ssh-plugin,含 node_modules) git clone https://github.com/Dalld/dsh-ssh-plugin.git cd dsh-ssh-plugin npm install --omit=dev --ignore-scripts npm run prepare:dist # 产物:dist/dsh-ssh-plugin 把 dist/dsh-ssh-plugin 整个目录拷到目标机,然后在目标机 DSH 里: plugin_manager install_bundle D:\dsh-plugins\dsh-ssh-plugin 目录安装走 link:,不会重装依赖,不会触发构建审批,适合离线/内网。 方式 B:直接指向源码目录(开发用) git clone https://github.com/Dalld/dsh-ssh-plugin.git cd dsh-ssh-plugin npm install --omit=dev --ignore-scripts # ssh2 纯 JS 即可,不需要编译 plugin_manager install_bundle <仓库绝对路径> 方式 C:npm 一条命令 plugin_manager install_bundle dsh-ssh-plugin 目标机安装时 pnpm 会自动装 ssh2,首次可能提示 pendingBuilds: cpu-features, ssh2 (可选原生加速模块)。允许即可;不允许也能用,插件自动退回 OpenSSH 后端。 环境要求 | 项 | 要求 | | DSH | ≥ 0.2.1-rc.2 | | Node | ≥ 20(DSH 自带) | | 系统 | Windows 10+ / macOS / Linux | | 可选 | 系统 OpenSSH 客户端(没有 ssh2 时使用) | 4. 面板 | 区域 | 内容 | | 顶栏 | 搜索、刷新、导入 ~/.ssh/config、新增 | | 左栏 | 主机列表(指纹是否已记录、只读标记、分组过滤) | | 右栏 | 主机详情 + 测试连接(含连接日志)+ 编辑/删除 | | 策略卡 | 传输后端、危险命令策略、主机指纹策略、连接复用 | | 黑名单卡 | 正则可增删、可恢复默认(内置 20 条,含 PowerShell 规则) | | 最近活动 | 折叠的审计摘要 | 测试连接会真的连一次并输出日志,例如: [ 0ms] 后端 ssh2 · 目标 root@1.2.3.4:22 [ 0ms] 策略:指纹 accept-new · 超时 20000ms [ 0ms] 已记录主机指纹 SHA256:s2OgX2EON... [ 1729ms] 握手完成 · 主机密钥 SHA256:s2OgX2EON... [ 1729ms] 主机指纹与记录一致 [ 1729ms] 认证成功 · 方式 password:cred [ 3317ms] 远端回显 exit 0 · 1588ms [ 3317ms] 完成 5. 工具(模型可见) | 工具 | 作用 | | ssh_hosts | 列出别名、认证方式、只读/分组、已记录指纹;probe: true 真实连接 | | ssh_exec | 执行命令(支持 stdin、cwd、超时、输出上限) | | ssh_put / ssh_get | 上下传;recursive 传目录,verify 比对 sha256 | | ssh_doctor | 诊断:可用传输层与版本、数据目录、known_hosts、逐主机就绪情况 | 参数 schema 里没有任何密钥字段 —— 模型能给的最敏感情报只是一个别名。 6. 安全模型 1. 认证材料只在 Host 进程解析,共六种来源: keyCred(面板粘贴私钥 → DSH 凭据库)、passwordCred(面板输入密码 → 凭据库)、 keyEnv / passwordEnv(环境变量名)、keyPath(本机私钥文件)、agent(ssh-agent)。 2. 出口统一脱敏:秘密值 → [redacted:secret],dataDir/私钥路径/临时路径 → [redacted:path], PEM 块 → [redacted:private-key]。工具结果、错误信息、连接日志都过这一层。 3. TOFU 指纹:accept-new 下首次连接成功即记录指纹,之后每次比对;不一致直接拒绝连接。 4. 审计:<dataDir>/audit.jsonl(0600)记录 exec/put/get/probe 的时间、退出码、耗时、脱敏命令。 5. 命令策略:dangerPolicy: deny | ask | allow,命中黑名单时拒绝 / 转 DSH 审批 / 放行;主机可设 mode: readonly 拒绝写操作。 边界:智能体自己有文件读写工具,磁盘上存在的私钥它本来就能读。本插件保证的是「不新增副本、不打印位置、不把密钥塞进结果」。黑名单与只读模式是模式匹配,不是沙箱。 7. 配置参考 写在插件行的 config(YAML),或让面板写 <dataDir>/settings.json(面板优先级更高,即时生效)。 config: transport: ssh2 # ssh2 | openssh | auto hostKeyPolicy: accept-new # accept-new | strict | off dangerPolicy: deny # allow | ask | deny audit: true multiplex: false # 仅 OpenSSH 后端(POSIX) defaultTimeoutMs: 30000 connectTimeoutMs: 20000 maxOutputBytes: 200000 hosts: - alias: prod host: 1.2.3.4 port: 22 user: root keyCred: DSH_SSH_PROD_KEY # 面板粘贴私钥后自动生成的引用名 mode: readonly # default | readonly group: prod - alias: winbox host: 10.0.0.12 user: Administrator keyPath: C:\Users\me\.ssh\id_ed25519 shell: powershell # posix | powershell | cmd 单主机可选:keyEnv keyPath keyCred passphraseEnv passwordEnv passwordCred agent timeoutMs connectTimeoutMs maxOutputBytes defaultCwd shell mode group enabled。 配置是严格的:未知字段、非法 host/user/port、坏 JSON 都会明确报错,不静默忽略。 数据目录 <profile>/ssh/:hosts.json、known_hosts、settings.json、audit.jsonl、cm/(OpenSSH 复用套接字)。 迁移到新机器时,前三个文件可整目录拷贝;凭据库里的密钥/密码不可迁移,需要重填,或改用 keyPath / keyEnv。 8. 与同类方案的比较 | | 本插件(ssh2 默认) | 纯 OpenSSH 命令行 | 桌面终端(WezTerm/Tabby) | | 模型可用 | ✅ 工具化 | ✅ 但需自己拼命令 | ❌ | | 连接复用 | ✅ 进程内连接池 | 仅 POSIX | ✅ | | SFTP | ✅ 原生 | scp | ✅ | | 密钥隔离 | ✅ 不落盘、脱敏 | ✅ 文件 | — | | 算法面 | libssh2(FIDO/新 KEX 滞后) | 跟系统 | 两者皆有 | transport: auto 会在 ssh2 缺失时自动降到 OpenSSH。 9. 已知限制 - 黑名单/只读是模式匹配,能被绕过;不要当作安全边界。 - known_hosts 只处理本插件写入的明文条目(哈希化 |1|… 条目匹配不到)。 - Windows 上 OpenSSH 后端没有连接复用与可靠口令认证(用 ssh2 即可)。 - 目录递归传输、断点续传、端口转发工具尚未实现。 - 面板文案目前为中文,未走 Client locale 服务。 10. 开发 npm install --omit=dev --ignore-scripts node test/smoke.mjs # 离线测试:工具注册、策略、指纹库、设置、面板 API、脱敏 真机验证记录见 DEPLOY.md。 License MIT
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
Dalld/dsh-ssh-plugin
让智能体通过别名远程执行命令并传输文件
相关插件 · 开发 / 工程
隐私简历生成器reactive-resume/reactive-resume
Reactive Resume 已迁至 GitHub 上的…
★ 45,125已汉化MCP
71.7
AI 架构文档生成器sopaco/deepwiki-rs
🚀 Litho 已进化为 Terrain —— 给你的 AI 智能体一张会呼吸的代码库地图。
★ 3,157已汉化DSH
70.8
长时任务执行闭环AMAP-ML/LongHorizon-Harness
面向 Computer-Use Agent 的 Loop Engineering
★ 1,764已汉化DSH
70.5
AI 编程纪律方法包GanyuanRan/Aegis
让 AI 编程 agent 变得可信:少返工、更安全、说“完成”前先给证据。
★ 1,384已汉化DSH
69.6
多代理编排运行时Enderfga/claw-orchestrator
面向编程智能体的运行时。把 Claude Code、Codex、Antigravity、Grok…
★ 586已汉化MCP
69.4
记忆进化插件csyangwen/dsh-memory-evolve
dsh-memory-evolve 使用场景指南
★ 461已汉化DSH
67.9