
SSH(Secure Shell)密钥认证是与 GitLab 交互最安全、最便捷的方式之一。配置后,每次推拉代码都无需输入密码,同时建立端到端加密连接。本文覆盖从生成密钥到签名提交、多账号共存、疑难排查的完整流程。
适用范围:GitLab.com SaaS 与自建 GitLab(Self-Managed)实例均适用。命令已在 Windows(Git Bash / PowerShell)、macOS 与 Linux 上验证。
1. 前置准备
在开始前,请确认:
| 项目 | 要求 | 验证命令 |
|---|---|---|
| Git | 已安装(2.34+ 推荐) | git --version |
| OpenSSH | 客户端已可用 | ssh -V |
| 终端 | Linux/macOS 原生终端;Windows 使用 Git Bash 或 PowerShell,不要用 CMD | — |
| GitLab 账号 | 可登录并具备添加 SSH Key 权限 | — |
本文使用
~/.ssh/表示用户家目录下的.ssh文件夹。Windows 对应C:\Users\<用户名>\.ssh\。
2. 快速开始(5 步上手)
已熟悉流程的读者可按此快速完成配置,详细说明见后续章节。
# 1. 生成 Ed25519 密钥(按回车使用默认路径,并设置 passphrase)
ssh-keygen -t ed25519 -C "your_email@example.com"# 2. 复制公钥
cat ~/.ssh/id_ed25519.pub # 手动复制输出
# 或
clip < ~/.ssh/id_ed25519.pub # Windows Git Bash
pbcopy < ~/.ssh/id_ed25519.pub # macOS# 3. 登录 GitLab → 头像 → Edit profile → SSH Keys → Add new key,粘贴公钥并保存# 4. 测试连接
ssh -T git@gitlab.com # 应看到 "Welcome to GitLab, @username!"# 5. 克隆/切换远端
git clone git@gitlab.com:username/repo.git
遇到问题请跳转 9. 故障排查。
3. 生成 SSH 密钥对
SSH 密钥对包含一个私钥(保存本地,绝不外泄)和一个公钥(上传 GitLab)。
3.1 选择密钥类型
| 类型 | 推荐度 | 说明 |
|---|---|---|
| Ed25519 | ✅ 首选 | 更安全、生成快、密钥短;GitLab 14.8+ 默认推荐 |
| ECDSA (NIST) | ⚠️ 可用 | 依赖 NIST 曲线,社区争议较大 |
| RSA (≥ 3072 位) | ✅ 兼容 | 兼容老旧客户端;建议 4096 位 |
| DSA / RSA < 2048 | ❌ 禁用 | 已被 GitLab 和 OpenSSH 弃用 |
3.2 执行生成命令
方案 A:Ed25519(推荐)
ssh-keygen -t ed25519 -C "your_email@example.com"
方案 B:RSA(兼容旧系统)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
参数说明:
| 参数 | 含义 |
|---|---|
-t |
密钥类型(ed25519 / rsa) |
-b 4096 |
仅 RSA 需要,指定位数;Ed25519 固定长度 |
-C |
注释,方便区分用途(不影响功能) |
3.3 理解交互提示
- 文件路径:按 Enter 使用默认路径
- Ed25519 →
~/.ssh/id_ed25519 - RSA →
~/.ssh/id_rsa
- Ed25519 →
- passphrase:强烈建议设置。私钥被窃取时,没有密码仍然无法使用。配合 Agent(见第 6 节)可避免重复输入。
- 成功输出:
Your identification has been saved in /home/username/.ssh/id_ed25519 Your public key has been saved in /home/username/.ssh/id_ed25519.pub The key fingerprint is: SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx your_email@example.com
⚠️ 关键安全提示:
.pub结尾的是公钥,可公开;无后缀的是私钥,绝不能上传、提交、粘贴到任何第三方服务。
4. 上传公钥到 GitLab
4.1 复制公钥内容
查看公钥(文件名按实际类型替换):
cat ~/.ssh/id_ed25519.pub
复制完整输出,须包含开头的 ssh-ed25519(或 ssh-rsa)和结尾的邮箱注释。
使用系统剪贴板一键复制:
| 系统 | 命令 |
|---|---|
| macOS | pbcopy < ~/.ssh/id_ed25519.pub |
| Linux (X11) | xclip -sel clip < ~/.ssh/id_ed25519.pub |
| Linux (Wayland) | wl-copy < ~/.ssh/id_ed25519.pub |
| Windows (Git Bash) | clip < ~/.ssh/id_ed25519.pub |
| Windows (PowerShell) | Get-Content ~/.ssh/id_ed25519.pub | Set-Clipboard |
4.2 在 GitLab 网页添加
- 登录 GitLab → 右上角头像 → Edit profile / 偏好设置
- 左侧菜单 → SSH Keys → Add new key
- 填写字段:
| 字段 | 说明 |
|---|---|
| Key | 粘贴公钥全文 |
| Title | 描述性名称,如 MacBook-Pro-2024、WorkLaptop-Win11 |
| Usage type | Authentication & Signing(默认)/ Authentication / Signing(15.7+) |
| Expiration date | 建议设置,便于密钥轮换 |
- 点击 Add key 完成。
5. 测试 SSH 连接
# GitLab SaaS
ssh -T git@gitlab.com# 自建 GitLab(替换为实际域名)
ssh -T git@gitlab.yourcompany.com
- 首次连接会显示主机指纹,核对后输入
yes。可在 GitLab 官方指纹页 核对 gitlab.com 指纹。 - 成功示例:
Welcome to GitLab, @username! - 卡住无响应:加
-v打印调试信息ssh -Tv git@gitlab.com。
6. 配置 SSH Agent
SSH Agent 在当前会话内缓存解锁后的私钥,免去重复输入 passphrase。
6.1 Linux / macOS
eval "$(ssh-agent -s)" # 启动 agent
ssh-add ~/.ssh/id_ed25519 # 添加私钥
ssh-add -l # 查看已加载密钥
macOS 持久化(存入 Keychain,重启仍生效):
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
在 ~/.ssh/config 写入:
Host *UseKeychain yesAddKeysToAgent yesIdentityFile ~/.ssh/id_ed25519
6.2 Windows
Windows 10/11 自带 OpenSSH,但 ssh-agent 服务默认禁用。以管理员身份打开 PowerShell:
Set-Service -Name ssh-agent -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519
可选:让 Git 使用系统 OpenSSH(而非 Git 自带版本):
git config --global core.sshCommand "C:/Windows/System32/OpenSSH/ssh.exe"
7. 日常使用
7.1 克隆项目
git clone git@gitlab.com:username/repository.git
URL 可从项目页面 Clone → Clone with SSH 复制。
7.2 HTTPS 切换到 SSH
git remote set-url origin git@gitlab.com:username/repository.git
git remote -v # 确认已变更
7.3 多账号 / 多实例共存
同一台机器需同时访问 GitLab.com 个人账号 + 公司自建 GitLab 时,用 ~/.ssh/config 区分:
# 公司 GitLab(自建)
Host gitlab-workHostName gitlab.company.comUser gitIdentityFile ~/.ssh/id_ed25519_workIdentitiesOnly yes# 个人 GitLab.com
Host gitlab-personalHostName gitlab.comUser gitIdentityFile ~/.ssh/id_ed25519_personalIdentitiesOnly yes
克隆时使用 Host 别名:
git clone git@gitlab-work:group/repo.git
git clone git@gitlab-personal:username/repo.git
IdentitiesOnly yes很关键:避免 SSH 依次尝试 agent 里所有密钥,触发 GitLab 速率限制或误用错密钥。
8. 进阶:SSH 签名提交
GitLab 15.7+ 支持用 SSH 密钥对 commit / tag 签名,页面会显示 Verified 徽章。
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign true
前提:在 GitLab 中添加该公钥时,Usage type 包含 Signing。
9. 故障排查
9.1 Permission denied (publickey)
按顺序排查:
- 确认远端 URL 是
git@...而非https://...:git remote -v - 确认公钥已正确粘贴到 GitLab,没有换行被截断
- 确认私钥已加载:
ssh-add -l;若未加载则ssh-add ~/.ssh/id_ed25519 - 用
ssh -Tv git@gitlab.com查看实际使用的密钥,常见问题是误用了错 key - 检查文件权限(见 9.5)
9.2 连接超时或被拒绝(22 端口被封)
公司网络、酒店 Wi-Fi、部分校园网会封禁 22 端口。GitLab.com 提供 443 端口 的备用 SSH 入口,编辑 ~/.ssh/config:
Host gitlab.comHostname altssh.gitlab.comUser gitPort 443PreferredAuthentications publickeyIdentityFile ~/.ssh/id_ed25519
自建 GitLab 需自行开启 443 转发,或改用 HTTPS + Personal Access Token。
9.3 仍被要求输入密码
git remote -v若为 HTTPS,请切换为 SSH(见 7.2)- Windows 下每次都要输 passphrase,多半是
ssh-agent服务未启动(见 6.2)
9.4 主机密钥变更警告(可能的中间人攻击)
出现 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 时:
- 先核对 GitLab 官方公布的指纹,确认是否真的变更
- 无误后移除旧记录:
ssh-keygen -R gitlab.com - 再次连接并接受新指纹
9.5 密钥权限过宽(Unprotected private key file)
Linux / macOS:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519 # 私钥
chmod 644 ~/.ssh/id_ed25519.pub # 公钥
chmod 600 ~/.ssh/config
Windows:若报权限错误,右键私钥文件 → 属性 → 安全 → 高级 → 禁用继承 → 只保留当前用户的完全控制。
9.6 自建 GitLab 无法连接
登录 GitLab 服务器检查 git 用户配置:
getent passwd git
# 应输出类似:git:x:998:998::/var/opt/gitlab:/bin/sh(指向 gitlab-shell)
确认 sshd_config 中 PubkeyAuthentication yes 已开启、AuthorizedKeysCommand 配置正确。Omnibus 安装通常已配置好,勿手动编辑 ~git/.ssh/authorized_keys。
9.7 密钥轮换流程
- 在 GitLab SSH Keys 页面查看 Last used 和过期时间
- 轮换步骤:生成新密钥 → 上传到 GitLab → 本地切换
IdentityFile→ 验证可用 → 删除旧公钥 → 本地销毁旧私钥
10. 安全最佳实践
| 实践 | 说明 | |
|---|---|---|
| ✅ | 始终为私钥设置 passphrase | 配合 agent,使用体验几乎无损 |
| ✅ | 每台设备独立密钥 | 丢失设备时可单独吊销 |
| ✅ | 设置密钥过期时间 | 强制周期性轮换 |
| ✅ | 优先使用 Ed25519 | 避免弱算法 |
| ❌ | 不要同步私钥到云盘 / 聊天工具 / Git 仓库 | 私钥一旦泄露即失效 |
| ❌ | 不要多人共享同一把密钥 | 无法审计个人操作 |
| ❌ | 不要在公共 / 他人电脑上加私钥到 agent | 会话结束也可能残留 |
总结
核心路径:生成 Ed25519 密钥 → 上传公钥到 GitLab → 启用 SSH Agent → 配置 ~/.ssh/config。遇到问题优先用 ssh -Tv 输出调试信息,90% 的故障都能定位。
