因为我的电脑和服务器都很多,管理多台设备的 SSH 配置一直是个痛点。
以前的做法是手动复制私钥,然后还得维护一份差异巨大的 ~/.ssh/config,不安全又麻烦。
最近我重构了整套方案,达成了以下效果:
- 零私钥落地:私钥只存在于 Bitwarden 内存,硬盘上无私钥文件。
- 配置云同步:公钥和 Config 通过 OneDrive 同步。
- 路径大一统:利用 Symlink 抹平 Windows 和 macOS 的路径差异。
需要提前启用 Bitwarden 的 SSH Agent 功能,参考官方文档:Bitwarden SSH Agent
目录结构策略
私钥交给 Bitwarden 托管,我们只需要同步公钥和通用配置。
在 OneDrive 中建立如下结构:
OneDrive/ |
抹平路径差异
这是最关键的一步。
SSH 配置文件不支持环境变量(如 %OneDrive%),且不同电脑的云同步路径各异(D 盘、C 盘、/Users/...)。
解决方案是在每台电脑的 ~/.ssh/ 下创建一个名为 cloud_ssh 的软链接,指向真实的云同步目录。
Windows
cd ~/.ssh |
macOS / Linux
cd ~/.ssh |
现在,无论在哪个系统,~/.ssh/cloud_ssh 都是通用的路径。
SSH Config 配置
在本地的 ~/.ssh/config 中,只需要一行 Include:
Include ~/.ssh/cloud_ssh/common_config |
然后在 OneDrive 里的 common_config 编写配置:
# example |
这里 IdentityFile 指向的是 .pub 文件。在 SSH Agent 模式下,SSH 客户端会读取这个公钥的指纹,然后去 Bitwarden Agent 里请求对应的私钥。
ForwardAgent yes 允许你在远程服务器上直接使用本地 Bitwarden 托管的 SSH 密钥,而无需在服务器上存放任何私钥。
-
场景:当你 SSH 到 A 服务器后,需要从 A 服务器 git clone 私有仓库或 SSH 到 B 服务器。
-
安全性注意:仅在你信任的服务器上开启。如果服务器管理员具有 Root 权限,理论上他们可以利用已建立的 Socket 连接访问你的本地 Agent。
使用 SSH 密钥进行 Git 提交签名
既然已经实现了 SSH 密钥的统一管理,我们还可以更进一步:用 SSH 密钥代替传统的 GPG 密钥进行 Git 提交签名。
在终端执行以下命令,告诉 Git 使用 SSH 格式进行签名,并指向我们云端同步的公钥:
# 1. 设置签名格式为 ssh |
为了让 GitHub 识别你的签名,需要将公钥再次上传,但类型不同:
-
打开
GitHub Settings->SSH and GPG keys。 -
点击
New SSH Key。 -
Key type务必选择Signing Key。 -
粘贴
github.pub中的内容并保存
你可以创建一个空提交来测试整个流程:
git commit --allow-empty -S -m "test: verify ssh signing" |
现在可能会输出 No signature,这个问题是因为你已经成功签名了,但 Git 在本地尝试验证签名时,不知道该信任哪些公钥。
Git 需要一个名为 allowed_signers 的文件来充当白名单。
在 OneDrive 的 ssh 文件夹(也就是 cloud_ssh 软链接指向的源目录)里,新建一个文本文件,命名为 allowed_signers(注意不要有 .txt 后缀)。
在该文件中添加一行,格式为:<你的邮箱> <公钥内容>。
me@exusiai.top ssh-ed25519 AAAAC3NzaC1lZDI1... |
回到终端,执行以下命令告诉 Git 这个文件的位置:
git config --global gpg.ssh.allowedSignersFile "~/.ssh/cloud_ssh/allowed_signers" |
现在重新运行查看命令:
git log --show-signature -1 |
你应该会看到类似这样的输出:
Good "git" signature for me@exusiai.top with ED25519 key SHA256:... |
疑难杂症
Windows Git 的坑
在 Windows 上配置好后,ssh -T git@github.com 通了,但 git clone 可能会报 error in libcrypto 或 Permission denied。
这是因为 Git for Windows 默认使用内置的 MinGW SSH,它找不到 Bitwarden 的 Agent,也不支持指向 .pub 的配置。
强制 Git 使用 Windows 原生 OpenSSH 即可。
git config --global core.sshCommand "C:/Windows/System32/OpenSSH/ssh.exe" |
与 core.sshCommand 类似,Windows 上的 Git 签名程序也需要强制指向系统原生的 ssh-keygen,否则会因为找不到 Bitwarden 的 Agent 管道而报错:
git config --global gpg.ssh.program "C:/Windows/System32/OpenSSH/ssh-keygen.exe" |