OneSSH 架构
本文说明 OneSSH 的整体设计、模块边界与端到端执行流程。
威胁模型与安全控制见 安全。
1. 设计目标
- 单一主密码体验:主机与用户配置均加密存储。
- 适合 Git 的加密存储(YAML 中的
ENC[...]字段)。 - 仅内存的运行时密钥缓存(本地 agent)。
- 统一的 SSH 操作(交互式
onessh <alias>、exec、cp、ping,同一配置模型)。 - 默认简单的本地命名空间区分(agent 套接字/capability 由父 shell PID 派生,偏便利性设计,不是同 UID 下的强安全边界)。
2. 高层组件关系
3. 仓库布局(核心模块)
cmd/onessh- 二进制入口、版本与构建信息。
internal/cli- 命令定义、参数解析与适配层接线。
- 承载 agent 协议与 askpass 回退逻辑。
- 批量命令适配(
--all、--tag、--filter、--parallel)。
internal/app- connect、exec、copy、host/user 管理,以及共享 batch 行为的用例服务。
- 负责每次操作的审计决策,并保证审计 sink 失败不影响主流程。
internal/domain- 纯 host/user/auth/tag/default 规则,无 IO。
internal/runtime- 仅描述运行时关注点,例如 IO streams、缓存与审计配置。
internal/ports- 应用层依赖的窄接口,例如 audit 与 identity resolution。
internal/infra- 将端口适配到现有 store、audit、SSH 与 agent 实现。
internal/presenters- 表格、JSON 与 batch 结果输出格式化;不做持久化或传输副作用。
internal/store- 配置加解密、YAML 持久化、KDF/密码处理。
- 数据校验与强制重置安全检查。
internal/audit- 可选审计日志与轮转。
3.1 分层一致性规则
domain保持纯净且确定性。app、cli与测试可以使用它,但它不打开文件、socket 或进程。runtime描述单次运行的关注点(IO streams、cache/audit 设置),不负责持久化配置。app编排用例:校验输入,通过端口解析身份,调用 runner/adapter,并通过 audit 端口记录结果。ports定义应用层拥有的稳定边界,由基础设施层实现。infra适配外部系统与遗留实现(store、audit logger、SSH/agent 执行),避免这些细节反向进入app。presenters只渲染已经计算出的结果。它们不加载配置、不运行 SSH、不修改 store,也不写审计。store仍是加密配置的持久化引擎与事务边界。应用与 CLI 代码应通过 repository/adapter 使用它,而不是重新实现持久化。
4. 数据模型与持久化
存储根目录(默认):~/.config/onessh/data
text
meta.yaml
users/<alias>.yaml
hosts/<alias>.yamlmeta.yaml:KDF 参数与密码校验。users/*.yaml:可复用用户 profile(name、auth)。hosts/*.yaml:目标主机(host、user_ref、port、proxy_jump、env、pre_connect/post_connect钩子、标签)。
敏感值为加密载荷(ENC[...]),文件结构仍便于 diff。
5. 运行时上下文解析
每次执行命令时,OneSSH 按以下顺序解析上下文:
- 解析 CLI 标志与环境变量。
- 解析数据路径。
- 解析 agent 套接字:
- 显式
--agent-socket ONESSH_AGENT_SOCKET- 默认由父 shell PID 派生的套接字。
- 显式
- 解析 agent capability:
- 显式
--agent-capability ONESSH_AGENT_CAPABILITY- 默认由
uid + 父 shell PID派生。
- 显式
- 构建缓存键命名空间:
onessh:passphrase:v1:<canonical-data-path>。
6. 主密码与缓存流程
说明:
- 缓存在内存中(agent 进程),不落盘。
- 缓存按数据路径隔离,不同存储不会误共享口令。
7. 命令执行架构
两大类命令:
- 配置类命令
init、add、update、rm、user *、passwd、show、ls- 主要在解密后的模型上操作,再写回加密存储。
- 远程操作类命令
- 根命令
onessh <alias>(交互式 SSH;无connect子命令),以及exec、cp、ping - 解析主机与用户 profile 后,调用 SSH 传输适配层。
- 根命令
7.1 远程操作流水线
7.2 批量执行模型
- 过滤器产生确定的别名集合。
--parallel限制 goroutine 并发度。- 按主机收集结果,以稳定顺序输出。
- 任一主机失败则整批视为失败。
- 启用审计时,批量
exec、cp与ping会按主机分别记录审计事件。成功主机记为ok,远端执行失败记为fail,身份解析失败导致的跳过记为skip;审计 sink 错误会被有意忽略,不改变命令结果。
8. Agent 与 AskPass 集成
- Agent 传输:Unix 域套接字(
shush)。 - 访问控制:
- agent 端校验对端 UID;
- 可选 capability token 校验。
- Askpass 回退:
- 在 agent 注册短时、单次使用 token;
- 运行时由辅助程序解析 token;
- 结束后清理 token 与临时启动脚本;
- 这是兼容性回退路径,安全性弱于
sshpass -d。
9. 生命周期与清理
logout:清除当前存储的缓存项。logout --all:清除所有 OneSSH 口令命名空间项。agent clear-all:清除 agent 内全部密钥与 token。- 命令级清理会擦除临时密钥缓冲区与短时产物(如适用)。
10. 与安全文档的关系
- 本文侧重架构与执行行为。
- 安全 侧重威胁模型、缓解措施与安全边界。