内容
README.md) | [简体中文](./.md)
# sshmng
sshmng 是一个**统一的 SSH 管理工具**,涵盖了**所有连接方式**——直接连接、`ssh -J` 透明跳转、交互式堡垒、传输代理——在一个**零依赖**的二进制文件中,支持**自动更新**。它既可以作为**MCP 服务器**供 AI 代理(如 Claude Code、Hermes 等)使用,也可以作为 `sshmng ssh` 命令行工具供人类使用,两者共用同一个**配置文件**。当出现问题时,代理会读取错误跟踪,修复配置文件,然后重试——**闭环自愈**,**无需人工干预**。
## 功能特点
- **交互式堡垒真正可用**:大多数 SSH 工具放弃了菜单驱动的堡垒。sshmng 的 `LoginFlow` 决策树(发送 + 预期,通配符或 `re:` 正则表达式)驱动菜单登录到目标——当菜单文本更改时,错误跟踪会返回给代理,以便它可以修复模式并重试
- **自愈配置文件循环**:代理读取 `error` / `login_trace`,调用 `update_*` 修复损坏的 LoginFlow 模式,重试 `login`——在无需人工干预的情况下关闭诊断循环
- **一键设置向导**:`sshmng install` 创建配置文件目录 + 模板,自动检测已安装的 AI 代理(Claude Code、Hermes、OpenCode)并将自身注入到它们的配置文件中,并带有时间戳备份;`sshmng doctor` 验证所有配置是否已连接
- **一个配置,两个接口**:AI 代理的 MCP 服务器(Claude Code、Hermes、OpenCode、Claude Desktop、Cursor),`sshmng ssh` 命令行工具供人类使用。相同的 `config.json`,相同的直接 / 模式 A(`ssh -J`)/ 模式 B(堡垒)模式——只需设置一次服务器,即可从任一侧使用
- **显式会话管理**:`login` → `run_in_session` → `close_session` 三件套;连续命令共享 cwd / env / 后台作业,与一次性 `ssh host cmd` 不同
- **sftp 文件传输**:`upload` / `download` 单个文件通过专用 sftp 通道传输,与 PTY 命令通道分开;当不可用时,降级处理。`upload_dir` / `download_dir` 递归传输目录树,并发(默认为 4),冲突策略覆盖 / 跳过 / 重命名
- **命令诊断**:`run_in_session` 超时自动 Ctrl-C + 排空,返回 `timed_out` / `ctrl_c_sent`;`get_trace` 检索命令历史记录(包括原始输出、ctrl_c_sent)
- **TOFU 主机密钥**:首次连接记录公钥到 `known_hosts`;如果密钥发生变化,则拒绝(“主机密钥已更改,可能的中间人攻击”)
- **配置文件 CRUD**:`list_*` / `get_*` / `update_*` 工具系列管理 SSH 服务器 / 跳转主机 / 代理,遵循 RFC 7396 JSON 合并补丁语义
## 安装与构建
sshmng 是一个单独的二进制文件,无需运行时依赖。请选择以下选项之一:
```bash
# 选项 0:一键安装 — 下载发行版,放置在 PATH 上
# macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/jim58246/sshmng/main/install.sh | bash
# Windows (PowerShell):
irm https://raw.githubusercontent.com/jim58246/sshmng/main/install.ps1 | iex
# 选项 1:下载发行版二进制文件(推荐,无需 Go)
# 从 https://github.com/jim58246/sshmng/releases 中选择适合您的操作系统和架构的二进制文件
chmod +x sshmng
# 选项 2:使用 Go 安装(需要 Go 1.25+)
go install github.com/jim58246/sshmng/cmd/sshmng@latest
# 选项 3:克隆并在本地构建
git clone https://github.com/jim58246/sshmng.git
cd sshmng && go build -o sshmng ./cmd/sshmng
```
**或者让您的 AI 代理为您安装它**:复制 [`docs/agent-install-prompt.md`](docs/agent-install-prompt.md) 中的提示,并将其粘贴到 Claude Code、Cursor、Hermes、OpenCode 中——代理将下载二进制文件,放置在 `PATH` 上,并为您运行 `sshmng install`。
**macOS**:浏览器下载的二进制文件带有 Gatekeeper 隔离属性——在首次使用前运行 `xattr -d com.apple.quarantine sshmng`。`go install` / `go build` 二进制文件不需要此操作(本地编译)。自动更新的二进制文件也不需要此操作(参见 [docs/auto-update.md](docs/auto-update.md))。
获取二进制文件后,运行 `sshmng install` 以创建 `~/.sshmng/` 并注入到已安装的 AI 代理(Claude Code、Hermes、OpenCode 等)。参见 [快速入门](#快速入门)。
**推荐**:在运行 `install` 之前,将二进制文件移动到 `PATH` 上稳定的位置(例如 `mv sshmng /usr/local/bin/`,或依赖 `~/go/bin/` 如果您使用了 `go install`)。`sshmng install` 将二进制文件的绝对路径记录到代理配置文件中,`sshmng doctor` 验证它与正在运行的可执行文件匹配——选择稳定的位置可以避免在后续移动后重新运行安装。
### 从源代码构建
```bash
# 普通构建(版本.Version 为 "dev",禁用自我更新)
go build -o sshmng ./cmd/sshmng
# 通过 ldflags 注入版本(自我更新需要真正的版本号)
go build -ldflags="-X github.com/jim58246/sshmng/internal/version.Version=v1.2.3" -o sshmng ./cmd/sshmng
```
如果没有 ldflags,`version.Version` 默认值为 `"dev"`,在这种情况下,`sshmng update` 和 `mcp` 启动时自动更新的 goroutine 都会被跳过。
运行:
```bash
./sshmng # 打印帮助信息
./sshmng mcp # 启动 MCP 服务器(代理配置文件使用的)
./sshmng # 首次安装向导
./sshmng doctor # 验证设置
./sshmng version # 打印版本 / 提交记录 / 日期
./sshmng version --check # 检查最新版本
./sshmng update # 自我更新到最新发行版
./sshmng mcp --config /path/to/config.json # 使用自定义配置文件启动 MCP 服务器
SSHMNG_HOME=/custom/dir ./sshmng mcp # 使用自定义 home 目录启动 MCP 服务器
./sshmng server list [keywords...] # 列出 SSH 服务器(并按名称/地址/标签进行 AND 匹配)
./sshmng server get <name> # 显示 SSH 服务器详细信息(完整认证信息)
./sshmng jumphost list|get ... # 对跳转主机执行相同操作
./sshmng proxy list|get ... # 对代理执行相同操作
./sshmng ssh <name> [command] # 交互式 SSH 登录;如果有命令,则为非交互式
```
## 快速入门
```bash
# 1. 构建
go build -o sshmng ./cmd/sshmng
# 2. 首次安装(创建 ~/.sshmng/ + 注入到已安装的 AI 代理)
./sshmng install
# 3. 验证配置文件
./sshmng doctor
# 4. 重启您的代理,让它调用 sshmng:
# "list_ssh_servers" → 应返回一个空数组
# "添加一个名为 prod-web-01 的 SSH 服务器,位于 10.0.022,密码为 ..."
# "登录到 prod-web-01 并运行h"
```
非交互式:
```bash
hmng install --yes --agents claude-code,hermes
```
有关手动配置文件回退和每个代理的集成步骤,请参见 [docs/agents.md](docs/agents.md)。
## MCP 工具概述
共 18 个工具:
| 类别 | 工具 | 描述 |
|------|------|------|
| 配置查询 | `list_ssh_servers` / `list_jumphosts` / `list_proxies` | 多关键词 AND 匹配名称/地址/标签(空格分隔,不区分大小写,认证信息已屏蔽) |
| 配置查询 | `get_ssh_server` / `get_jumphost` / `get_proxy` | 按名称查询单个记录(完整认证信息) |
| 配置更新 | `update_ssh_server` / `update_jumphost` / `update_proxy` | RFC 7396 JSON 合并补丁;null 删除,对象合并/创建 |
| 会话 | `login(name)` → `{sid, sftp_available}` | 拨号 + 登录流程 + RC 注入 + sftp 通道设置 |
| 会话 | `run_in_session(sid, cmd, timeout_ms?, max_output_bytes?)` | 运行命令,返回输出/退出代码/timed_out/truncated/total_bytes |
| 会话 | `close_session(sid)` | 强制关闭,会话记录保留 10 分钟 |
| 会话 | `stat()` | 列出所有活动会话摘要(包括 sftp_available) |
| 诊断 | `get_trace(sid, last_n?, trunc_output?)` | 检索命令历史记录(包括 ctrl,原始输出) |
| 文件传输 | `upload src, dst, timeout_ms?)` | → 远程,通过 |
| 文件传输 |(sid, src,_ms?) 远程 → 本 sftp |
| 文件 `upload_dir(s src, dst, concurrency?, timeout_ms?)` | 本地目录树远程,递归 s发默认 4,冲突策略覆盖/跳过/重命名 |
| 文件传输 | `download_dir(sid, src, dst, conflict?, concurrency?, timeout_ms?)` | 远程目录树 → 本地,递归 sftp,并发默认 4,冲突策略覆盖/跳过/重命名 |
> 无 `send_input` / `send_special`:MCP 客户端序列化工具调用,因此在 `run_in_session` 执行期间无法调用这两个工具;命令结束后(正常退出或超时 Ctrl-C),会话已经空闲或关闭,调用它们也会出错。交互式命令(sudo/read/cat>file于 `run_in_session` 的超时 + `get_trace` 进行原始输出诊断,而不是通过 send_input 输入。
## 安全注意事项
- **明文存储**:v1 将密码/通行密码以明文存储在 `config.json` 中,已明确记录;如果不可接受,请使用 `age` / `gpg` 自己加密整个 `config.json`,在使用前解密
- **TOFU 主机密钥**:默认启用;首次连接记录公钥到 `~/.sshmng/known_hosts`;如果密钥发生变化,则拒绝(“主机密钥已更改,可能的中间人攻击”)。可以通过 `host_key_verify: false` 按实体禁用(完全跳过 known_hosts 读取/写入,失去中间人攻击保护——仅适用于受信任的内网堡垒等);删除已记录的密钥仍然需要手动编辑 `~/.sshmng/known_hosts`,无工具支持
- **跟踪包含敏感数据**:`Send`(登录流程阶段)、`Output`(PTY 原始流)可能包含密码;跟踪仅在内存中,保留 10 分钟后自动清理,从不持久化到磁盘
- **stdout 绝不能记录日志**:JSON-RPC 专用于 stdout;操作日志记录到由 `config.log_path` 指定的旋转文件中(10MB / 5 个文件,0600 权限),如果未配置则不记录日志;启动错误记录到 stderr
- **认证范围(v1)**:仅支持密码 + 私钥;不支持键盘交互 / SSH 代理 / SSH 证书 / 2FA(如果您的环境需要这些,请使用 v2 扩展或在 LoginFlow 中硬编码交互)
## 自动更新
sshmng 在 `mcp` 启动时在后台 goroutine 中静默检查更新(仅写入 `log_path` 日志,从不输出到 stdout)。通过 `{"auto_update_enabled": false}` 禁用。手动更新:`sshmng update`。版本检查:`ss version --check`。自定义源:设置 `update_url`(参见 [docs/auto-update.md](docs/auto-update.md) 以获取自托管源布局、macOS 说明和发布流程)。
## 测试与开发
```bash
# 运行所有测试(带有竞争检测器)
go test -race ./...
```
有关测试覆盖率和开发详细信息,请参见 [docs/development.md](docs/development.md)(仅限中文——欢迎翻译)。
## 文档
- [配置参考](docs/configuration.md) —— 完整的 `config.json` 字段参考,模式 A/B 形状约束,示例
- [代理集成指南](docs/agents.md) —— Claude Code、Hermes 代理、OpenCode、Claude Desktop 的详细配置,MCP 检视器调试,首次设置流程,典型调用流程
- [代理安装提示](docs/agent-install-prompt.md) —— 复制粘贴提示,让您的 AI 代理安装 sshmng 端到端
- [自动更新](docs/auto-update.md) —— 自托管 HTTP 源布局,macOS 说明,发布流程
- [架构与开发](docs/development.md) —— 包结构,关键设计,子命令调度,测试覆盖率(仅限中文——欢迎翻译)
- [设计文档](docs/ssh-session-manager-design.md) —— 完整设计规格(PTY 哨兵,登录流程,会话状态机等)(仅限中文——欢迎翻译)
- [实现计划](docs/implementation-plan.md) —— v1 实现进度(仅限中文——欢迎翻译)
## 状态
v1 阶段:客户端独立运行,stdio 单进程,配置文件本地存储。设计文档:[`docs/ssh-session-manager-design.md`](docs/ssh-session-manager-design.md)(仅限中文——欢迎翻译)。
## 贡献
欢迎为 bug 和功能请求打开 [issues](https://github.com/jim58246/sshmng/issues)。
## 许可证
[LICENSE) —— Copyright (c) 20246