Skip to content

Repository files navigation

SSHWarden

SSHWarden 是一个轻量的独立 SSH Agent,目标是把 Bitwarden 中保存的 SSH Key 暴露给本机 ssh / git 使用,同时避免运行完整 Bitwarden Desktop 客户端。

当前项目处于跨平台 baseline 设计和实现推进阶段。现有代码最完整的是 Windows 路径;Linux/macOS 是一等支持目标,但部分控制通道、自启动、存储路径和平台原生解锁能力仍在建设中。

项目目标

SSHWarden 的目标不是复刻完整 Bitwarden Desktop,而是提供一个专注于 SSH Agent 的轻量工具:

  • 从 Bitwarden / Vaultwarden 同步 SSH Key
  • 作为本地 SSH Agent 服务 sshgit、Git commit signing 等客户端
  • 在签名请求时显示授权对话框
  • 支持锁定、解锁、自动锁定和本地加密缓存
  • 支持 Windows、Linux 桌面会话、macOS 三个平台的完整用户体验

当前状态

能力 当前状态
Bitwarden 登录与 SSH Key 同步 已实现
SSH Agent 协议服务 Windows 已实现;Unix socket 有基础实现
签名授权对话框 Slint 跨平台 UI 已实现
PIN 解锁 已实现(信封加密 + 每库随机盐 + 失败延迟/锁定)
Windows Hello 已实现(信封加密模型)
IPC 控制命令 已实现;Windows Named Pipe 与 Unix socket 均含调用方鉴权
Local Key Cache 已实现信封加密模型(格式 v3,PIN 随机盐)
标准平台存储目录 已实现,默认平台标准目录(%APPDATA%/$XDG_CONFIG_HOME/~/Library/Application Support);便携模式可选
自启动 startup enable/disable;Windows/Linux/macOS 均已实现(Linux/macOS 待实机验证)
Shell integration sshwarden env 已实现(sh/fish/powershell/cmd)
macOS native unlock 已实现(Phase 6,Keychain;仍需平台实机验证)
Linux native unlock 已实现(Phase 6,Secret Service;仍需平台实机验证)

设计权威记录见:

llmdoc/ 中包含历史分析和 Bitwarden Desktop 参考资料,不代表 SSHWarden 当前支持状态。

核心概念

Bitwarden Vault

Bitwarden Vault 是 SSH Key 的权威来源。SSHWarden 成功 sync 后,运行时 key set 应镜像 Bitwarden 中当前未删除、未归档的 SSH Key。

Local Key Cache

SSHWarden 会维护一个本地加密 SSH Key 快照,让 Remembered Device 在 Bitwarden 不可达时仍可解锁并签名。

目标模型是 envelope encryption:

Local Cache Key -> 加密 SSH keys

PIN / Windows Hello / macOS Keychain / Linux Secret Service -> 解锁 Local Cache Key

这允许 sync 成功后刷新本地缓存,而不需要长期保存用户 PIN。

Lock / Unlock / Forget

  • Lock:阻止签名并清除本地缓存刷新能力;Key Identity 仍可列出。
  • Unlock:用 PIN 或平台原生方法恢复签名能力。
  • Forget:删除本机记住的 key/session/native unlock material,下次必须重新登录 Bitwarden。

Signing Authorization

签名请求和解锁是两个步骤:

  1. 如果 SSHWarden 已锁定,Signing Request 可以触发 Unlock。
  2. Unlock 成功后,Signing Request 仍可能需要用户 Authorization。
  3. Key List Request 不触发 Unlock;锁定状态下可以列出 Key Identity。

目标平台

SSHWarden 的一等支持平台目标是:

  • Windows 10/11
  • Linux 桌面会话
  • macOS 13+

不把 WSL、BSD、移动端、浏览器环境、纯 headless server 作为 baseline 支持目标。

计划中的 baseline 能力

跨平台 baseline 应在所有一等平台上提供:

  • Bitwarden 登录和 SSH Key sync
  • 本地 SSH Agent endpoint
  • PIN Unlock
  • Signing Request 授权对话框
  • Lock / Unlock / Forget
  • Local Key Cache
  • Control Channel:statuslockunlocksyncset-pinstop 等控制命令
  • Shell Integration:sshwarden env
  • Startup Integration:登录桌面会话后自动启动
  • status 简洁状态报告
  • doctor 跨平台诊断检查

平台原生 unlock 是 baseline 之后的增强路线:

  1. Windows Hello
  2. macOS Keychain + Touch ID / user presence
  3. Linux Secret Service-compatible keyring

当前使用方式

配置

复制配置示例:

cp config.toml.example config.toml

编辑 config.toml,填写 Bitwarden 邮箱、服务器地址等配置。

① 运行 agent(进程生命周期)

sshwarden run                 # 前台运行(Ctrl-C 停止);直接运行 `sshwarden` 等价于此
sshwarden run --background    # 后台运行
sshwarden stop                # 停止后台 agent
sshwarden restart             # 重启后台 agent
sshwarden status              # 查看 agent / vault 状态与下一步建议
sshwarden doctor [--fix]      # 诊断(--fix 执行安全修复,如写入 ~/.ssh/config 的 Include 行)

② Vault 会话(需联网)

sshwarden login               # 登录 Bitwarden、同步、设置本机 PIN(Remembered Device),并把 key 交给运行中的 agent
sshwarden sync                # 从 Bitwarden 同步 key 到运行中的 agent
sshwarden forget              # 删除本机记住的 key/session/PIN

③ 锁定状态(不联网)

sshwarden lock
sshwarden unlock                    # 默认 auto:先平台解锁,再降级到 PIN
sshwarden unlock --method pin
sshwarden unlock --method hello     # Windows
sshwarden unlock --method native    # macOS Keychain / Linux Secret Service
sshwarden set-pin

主密码只在 sshwarden login 中使用;不再有 unlock --password

④ Key 与 Host 绑定(离线对象操作)

当 Bitwarden 里有多把 SSH Key 时,OpenSSH 可能会因为 MaxAuthTries 在尝试完所有 agent key 前断开连接。把 vault key 绑定到 SSH Host 可避免该问题(绑定会生成公开 .pub selector 文件与托管 SSH config):

sshwarden keys                            # 离线列出缓存的 key、绑定的 host、selector 与 ssh-config 状态
sshwarden keys bind github-key github.com   # 用 key 名称或 vault item id 绑定 host
sshwarden keys unbind github-key github.com # 解绑单个 host
sshwarden keys unbind github-key --all      # 解绑全部 host
sshwarden keys ui                         # 图形绑定管理器(需 agent 运行)

也可以通过签名请求里的 Bind & Approve... 图形流程完成绑定。详见 docs/host-bindings.md

⑤ 集成(本机设置)

sshwarden env                 # 打印 shell 环境变量(sh/fish/powershell/cmd)
sshwarden ssh-config          # 查看托管 snippet 路径与 Include 状态
sshwarden ssh-config show     # 打印托管 snippet(默认在 exe 同目录,可用 [ssh_config].managed_path 覆盖)
sshwarden ssh-config write    # 从本地缓存 + 绑定离线重写 snippet 并确保 Include 行
sshwarden ssh-config remove   # 从 ~/.ssh/config 移除 Include 行
sshwarden startup enable      # 登录时自启动(需先 `login` 建立 Remembered Device)
sshwarden startup disable     # 取消自启动
sshwarden config              # 显示配置文件路径

典型首次流程

sshwarden run --background    # 启动后台 agent
sshwarden login               # 登录 + 同步 + 按提示设置 PIN
sshwarden status              # 确认状态
sshwarden startup enable      # 可选:开机自启

与官方 Bitwarden Desktop 的关系

Bitwarden Desktop 已经提供 SSH Agent,但它依赖完整 Electron 桌面客户端。SSHWarden 的目标是提供一个更轻量的独立 agent。

设计上参考官方实现:

  • SSH Key 来自 Bitwarden Vault
  • SSH Agent 的运行时 key set 是 vault 的投影
  • 签名请求需要授权
  • Agent forwarding 始终需要显式授权
  • 锁定状态下可以保留可列出的 Key Identity

不同点:

  • SSHWarden 不依赖 Electron/Angular
  • SSHWarden 需要自己维护轻量 Local Key Cache
  • SSHWarden 的跨平台 daemon/control/startup/shell integration 独立实现

技术栈

  • Rust
  • Tokio
  • Clap
  • Slint
  • bitwarden-russh
  • reqwest
  • tokio-tungstenite
  • AES-256-CBC + HMAC-SHA256
  • Argon2id
  • zeroize

构建

cargo build --release

更多构建信息见 BUILD.md

许可证

本项目基于 Bitwarden clients 的部分代码和设计参考开发,遵循 GPL-3.0 许可证。

About

使用 Bitwarden 保存私钥的轻量 ssh-agent 客户端

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages