--- name: ssh-keychain description: SSH key management with macOS Keychain for password-protected keys --- # SSH 密钥与 macOS Keychain 管理 处理带密码的 SSH 密钥,配置自动解锁避免重复输入密码。 ## 问题场景 生成带密码的 SSH 密钥后,每次使用都需要输入密码: ```bash git pull # Enter passphrase for /Users/xxx/.ssh/id_xxx: ``` ## 解决方案 ### 1. 生成带密码的 SSH 密钥 ```bash # 生成密钥(推荐使用 ed25519) ssh-keygen -t ed25519 -f ~/.ssh/id_custom -N "your-passphrase" # 或使用随机密码 PASSPHRASE=$(openssl rand -base64 32) ssh-keygen -t ed25519 -f ~/.ssh/id_custom -N "$PASSPHRASE" ``` ### 2. 配置 SSH 使用 Keychain(关键步骤) 编辑 `~/.ssh/config`: ```ssh-config Host gitea.example.com HostName gitea.example.com User git IdentityFile ~/.ssh/id_custom IdentitiesOnly yes AddKeysToAgent yes UseKeychain yes ``` **重要配置项:** - `AddKeysToAgent yes` - 自动添加到 ssh-agent - `UseKeychain yes` - 使用 macOS Keychain 存储密码 - **不要**使用 `IdentityAgent none`(会禁用 Keychain) ### 3. 添加密钥到 ssh-agent 并保存到 Keychain ```bash # 方法 1:使用 --apple-use-keychain (macOS 12+) ssh-add --apple-use-keychain ~/.ssh/id_custom # 方法 2:使用 -K 选项 (macOS 11 及更早) ssh-add -K ~/.ssh/id_custom ``` 输入密码后,系统会保存到 Keychain,以后自动解锁。 ### 4. 验证配置 ```bash # 检查已加载的密钥 ssh-add -l # 测试 SSH 连接 ssh -T git@gitea.example.com ``` 如果显示 `Hi there, xxx! You've successfully authenticated` 且**没有提示输入密码**,则配置成功。 ## 完整工作流程示例 ### 场景:配置 Gitea SSH 访问 ```bash # 1. 生成带密码的密钥 PASSPHRASE="bkt/52MFsLVSRSHvIXv2WTCKEUaPhD0btDghUY6RnQI=" ssh-keygen -t ed25519 -f ~/.ssh/id_gitea_new -N "$PASSPHRASE" # 2. 配置 SSH # 编辑 ~/.ssh/config,添加: cat >> ~/.ssh/config << 'EOF' Host gitea.refining.dev HostName gitea.refining.dev User git IdentityFile ~/.ssh/id_gitea_new IdentitiesOnly yes AddKeysToAgent yes UseKeychain yes EOF # 3. 添加到 Keychain ssh-add --apple-use-keychain ~/.ssh/id_gitea_new # 输入密码: bkt/52MFsLVSRSHvIXv2WTCKEUaPhD0btDghUY6RnQI= # 4. 验证 ssh -T git@gitea.refining.dev # 5. 后续使用 git 无需输入密码 git pull git push ``` ## 常见错误与解决 ### 错误 1:仍然提示输入密码 **原因:** `~/.ssh/config` 中配置了 `IdentityAgent none` **解决:** 移除 `IdentityAgent none`,添加 `UseKeychain yes` ```ssh-config # ❌ 错误配置 Host gitea.example.com IdentityFile ~/.ssh/id_custom IdentityAgent none # 这会禁用 Keychain # ✅ 正确配置 Host gitea.example.com IdentityFile ~/.ssh/id_custom AddKeysToAgent yes UseKeychain yes ``` ### 错误 2:1Password SSH agent 冲突 如果系统使用 1Password 的 SSH agent(`IdentityAgent "~/Library/Group Containers/.../agent.sock"`): ```ssh-config Host * IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock" Host gitea.example.com HostName gitea.example.com User git IdentityFile ~/.ssh/id_custom IdentitiesOnly yes AddKeysToAgent yes UseKeychain yes # 不使用 1Password agent,直接使用系统 Keychain ``` ### 错误 3:ssh-add 命令不存在 某些 macOS 版本可能不支持 `--apple-use-keychain`: ```bash # 创建或编辑 ~/.ssh/config,添加全局配置 Host * UseKeychain yes AddKeysToAgent yes # 然后直接使用 ssh-add ~/.ssh/id_custom ``` ## 密钥管理最佳实践 ### 文件保存位置 将密钥备份到安全位置(如 iCloud): ```bash # 复制到 iCloud Key 文件夹 KEY_FOLDER="$HOME/Library/Mobile Documents/com~apple~CloudDocs/key" cp ~/.ssh/id_custom "$KEY_FOLDER/id_custom_$(date +%Y%m%d)" cp ~/.ssh/id_custom.pub "$KEY_FOLDER/id_custom_$(date +%Y%m%d).pub" # 创建密码说明文件 cat > "$KEY_FOLDER/id_custom_$(date +%Y%m%d)_info.txt" << EOF SSH Key: id_custom Generated: $(date) Passphrase: $PASSPHRASE Host: gitea.example.com EOF ``` ### 定期检查 ```bash # 列出所有已加载的密钥 ssh-add -l # 检查 SSH 配置 ssh -G gitea.example.com # 测试连接 ssh -vT git@gitea.example.com ``` ### 安全建议 1. **始终使用带密码的密钥** - 防止私钥泄露后被直接使用 2. **不要将私钥提交到 Git** - 添加到 `.gitignore` 3. **定期轮换密钥** - 建议每 6-12 个月 4. **为不同服务使用不同密钥** - 隔离风险 ## 快速参考 | 命令 | 用途 | |------|------| | `ssh-add --apple-use-keychain ~/.ssh/id_custom` | 添加密钥到 Keychain | | `ssh-add -l` | 列出已加载的密钥 | | `ssh-add -D` | 删除所有已加载的密钥 | | `ssh -T git@host` | 测试 SSH 连接 | | `ssh -G host` | 查看 SSH 配置 |