OneSSH:面向 AI Agent 的集中式 SSH 网关
最近在折腾让 AI Agent 帮忙管理服务器。直接把 SSH 私钥交给 Agent 风险太高;每台机器单独配置 MCP 又比较麻烦,权限回收和操作审计也不方便,于是做了 OneSSH。
项目地址:
https://github.com/Lynricsy/OneSSH
OneSSH 部署在自己的环境里,对 Agent 暴露标准 MCP 服务,SSH 私钥、密码和主机配置统一留在网关侧。Agent 只拿受限令牌或通过 MCP OAuth 授权,就能在允许的主机范围内执行运维操作。
Web 控制台与主机监控
控制台可以集中管理主机、密钥、令牌和权限,同时查看主机状态与监控覆盖情况。

Agent 能做什么?
- 一个 MCP 入口统一操作多台 Linux 服务器
- 执行命令,并支持后台长任务、状态查询和增量日志
- 读取、编辑、搜索文件,提供类似 Agent 编程工具的基础工具集
- 通过 SFTP 在本地与远端、不同服务器之间传递文件
- 浏览器终端、文件管理、主机状态与监控指标
- 支持跳板机和 SSH 主机指纹校验
- 运维记忆可按主机跨会话保存,方便 Agent 延续上下文
- 可接入 ChatGPT、Claude 等支持远程 MCP / OAuth 的客户端
目前提供的部分 MCP 工具:

Web 端也可以直接浏览远程文件、上传下载和预览图片。

为什么不直接把 SSH 密钥交给 Agent?
OneSSH 把凭据和权限控制集中在网关侧:
- 凭据不出网关:私钥和密码使用 AES-256-GCM 加密存储,只在建立 SSH 连接时解密
- 权限可收敛:每个令牌只允许访问指定主机,执行权限与主机配置权限相互独立
- 随时可撤销:删除网关侧令牌即可失效,不必逐台修改 authorized_keys
- 全程留痕:工具调用和权限拒绝都会进入审计日志;文件正文、编辑内容等敏感数据只记录长度摘要
- 支持 OAuth 2.1:兼容支持 MCP OAuth 的客户端,也可使用手工 Bearer Token
整体架构是“客户端 → OneSSH 网关 → 多台 SSH 主机”,本地使用 SQLite 和 artifacts 保存状态,SSH 凭据不会下发到 Agent:

快速部署
准备好 Docker 和 Docker Compose:
export ONESSH_MASTER_KEY="$(openssl rand -hex 32)"
export ONESSH_ADMIN_PASSWORD="请替换为高强度密码"
docker compose up -d
curl --fail http://localhost:8866/healthz
默认 Compose 会直接拉取 ghcr.io/lynricsy/onessh:latest,无需在部署服务器上构建镜像。
打开 http://服务器地址:8866/ 后,在控制台添加密钥、主机和 Agent 令牌即可使用。
注意:
ONESSH_MASTER_KEY用于加密 SSH 凭据,丢失后已加密的数据无法恢复,生产环境请务必持久化保存。
适合谁?
- 同时管理多台 VPS / Linux 服务器的人
- 想让 AI Agent 参与部署、巡检和故障排查的开发者
- 不希望把 SSH 私钥直接暴露给 Agent 的用户
- 需要细粒度授权、随时撤销和审计留痕的小团队
- 想在 ChatGPT、Claude、Codex 等客户端统一使用服务器工具的人
项目目前还在持续完善,欢迎体验、提 Issue 或提交 PR。如果觉得有用,也欢迎点个 Star ⭐
GitHub:
牛的 bd
666 体验下
集中管权限和审计这个思路挺实用,私钥不用到处塞了。
有用的。
马克一下,说不定以后会用到
支持一下
牛的,让我的Hermes帮我看看哈哈哈~
牛的,不过目前我用的哪吒面板的MCP,一样可以实现agent控制服务器的功能
大佬,我这里部署遇到了一个bug,OneSSH v0.1.8 单二进制部署,网关纳管 12 台主机,监控轮询开启(默认 60s)。启动后监控采样持续报错,database is locked (5) (SQLITE_BUSY) 刷了几百次且一直不停,onessh.db-wal 涨到 4MB+不回收,监控基本是废的(所有采样都失败,hosts_list 里 online 状态不可靠)。我用deepseekv4f找到的bug说是busy_timeout 是 per-connection 的 PRAGMA。db.Exec() 只对连接池里执行这条语句的那一个连接生效;而 database/sql 默认MaxOpenConns=0(不限制),监控多台主机并发采样写库时,新建的连接 busy_timeout=0 → 遇到写锁立即SQLITE_BUSY,不会等待。WAL 模式下读写不互斥,但写写冲突 + checkpoint 抢锁失败 → WAL 越涨越大。给提了个issue
@Wzzz #9 感谢,我看看怎么回事🤔