1. 为什么要配 SSH Key:这玩意到底解决什么问题
先说个最直观的场景。你用git clone拉 GitLab 上的私有仓库,或者每次git push提交代码,GitLab 都要确认“你是不是仓库的合法成员”。确认方式无非两种:账号密码(HTTPS 协议),或者 SSH Key(SSH 协议)。
HTTPS 方式看着简单,但用起来确实烦——每次 push 都要输用户名和密码,要是不小心输错了,还得等 Git 的凭证管理器弹出来改。有些团队把仓库权限挂在某个公共账号上,大家共用一个密码,这时候 SSH Key 的优势就很明显了:你的机器上放一把私钥,GitLab 上登记一把公钥,push 代码时系统自动完成身份验证,全程无感,安全性和便利性都上了个台阶。
SSH Key 本质上是一对非对称加密密钥。私钥留在本地,公钥放到 GitLab 服务器上。你向 GitLab 发起 SSH 连接时,服务器拿公钥加密一个随机数发给你,你的私钥能解开它并返回证明,服务器确认“持有私钥的就是你本人”,认证就通过了。整个过程不传输密码,私钥也永远不会离开你的电脑,比明文密码安全得多。
配置 GitLab SSH Key 具体能解决什么问题?简单列一下:
- 免密 push/pull,告别每次输密码的重复劳动
- 不再依赖账号密码,纯命令行操作更顺手
- 可以把多个不同的仓库账号(比如工作账号和个人账号)区分开,互不干扰
- CI/CD 里部署服务器拉取代码时,用 Deploy Key 或机器账号的 SSH Key 更规范、更安全
这篇文章适合谁看?刚接触 GitLab、被 push 密码折磨过的新手,或者在 Windows 上配过好几次都没成功的老手,都能从这里找到完整的操作流程和避坑经验。下面我按真实操作顺序把过程完整过一遍。
2. 准备工作:先确认这几个前提,别急着敲命令
2.1 检查 Git 和 SSH 客户端是否就位
在生成 Key 之前,先确认基础环境是完整的,否则后面每一步都可能卡住。
- Git 已安装,命令行能执行
git --version - SSH 客户端可用。Linux / macOS 自带 OpenSSH,一般不用装。Windows 10 1809 及以上版本自带 OpenSSH 客户端,Win7/8 需要用 Git Bash(安装 Git 时自带)或者单独装 OpenSSH for Windows
- 能访问公司内部的 GitLab 地址(有的团队用自建实例,域名是内网地址)
检查命令:
git --version ssh -V如果ssh -V报“找不到命令”,说明 SSH 客户端缺了。Windows 用户最快的解决办法是在 Git 官网装 Git Bash,里面的ssh.exe可以直接用。macOS 用户执行ssh -V如果提示没有,运行一下sudo systemsetup -f -setremotelogin on或者直接装 Xcode Command Line Tools,输入xcode-select --install。
2.2 确认 GitLab 账号和邮箱,必须和你本地 Git 配置对应
这一步很多人忽略,但它直接影响后续能否 push 成功。GitLab 账号绑定的邮箱和你本地git config里的user.email最好保持一致,这样每次提交记录都能正确归属到你的账号下。
查看本地配置:
git config --global user.name git config --global user.email如果没配置过,先设置:
git config --global user.name "你的名字" git config --global user.email "你的邮箱"提示:有的"写手"会建议随便填,我个人建议还是认真填。提交记录里的作者信息一旦写错,后面改起来麻烦,而且代码评审时别人看到一堆陌生名字,体验很不好。
2.3 选算法:ed25519 还是 RSA
创建 SSH Key 的时候要先想清楚用哪种算法。目前主流推荐是 ed25519,2011 年由 Daniel J. Bernstein 等人设计的现代椭圆曲线签名算法。它的特点是密钥短、速度快、安全性高,GitHub、GitLab 和各大云厂商都完全支持。
老设备或老系统上的 OpenSSH 版本特别旧(比如 7.0 以下的),可能不支持 ed25519,这时候退回到 RSA。RSA 密钥建议直接生成 4096 位,别看 2048 位也能用,但在 2024 年的环境下,4096 更稳。如果你用的 GitLab 实例版本比较老(10.0 之前),ed25519 有兼容风险,这种情况用 RSA 更保险。
生成 ed25519 密钥的命令:
ssh-keygen -t ed25519 -C "你的邮箱"生成 RSA 4096 的命令:
ssh-keygen -t rsa -b 4096 -C "你的邮箱"这里的-C参数是注释,一般填邮箱,方便你在 GitLab 后台一眼认出这把钥匙是谁的。这不影响密钥功能,纯粹是个标识。
3. 生成 SSH Key 的完整过程,包括参数怎么选
3.1 执行生成命令,会遇到两个交互问题
在终端执行:
ssh-keygen -t ed25519 -C "your_email@example.com"接下来会出现两个交互提示:
第一个提示:Enter file in which to save the key (/home/用户名/.ssh/id_ed25519):
默认路径是~/.ssh/id_ed25519。如果你只有一把 Key,直接回车用默认路径。如果你要管理多把 Key(比如一个工作 GitLab、一个个人 GitLab),建议给文件改个名字,比如id_ed25519_gitlab_work,后面好区分。需要注意的是别用中文和空格。
第二个提示:Enter passphrase (empty for no passphrase):
这就是给私钥加“密码锁”。如果设了 passphrase,每次用这把私钥连接 GitLab 时都要输入一遍(除非你用 ssh-agent 记住了)。有的人嫌麻烦直接回车留空,方便是方便,但私钥文件一旦泄露,别人拿着就能直接访问你的仓库。
我的建议是:本地个人电脑上可以不设,毕竟天天 push 都输密码也很烦。但公司的电脑或服务器上建议设,重要程度高,可以配合 ssh-agent 把 passphrase 缓存起来,既安全又不麻烦。
3.2 生成完后,检查文件是否完整
生成过程结束后,到~/.ssh/目录下检查:
ls -l ~/.ssh/正常情况下会看到两个文件:
id_ed25519:私钥,绝对不要泄露id_ed25519.pub:公钥,需要复制内容贴到 GitLab 后台
查看公钥内容:
cat ~/.ssh/id_ed25519.pub输出长这样:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...你的邮箱把这段内容整行复制,注意是完整的一行,不能漏掉开头的ssh-ed25519,也不要漏掉末尾的邮箱。有些教程教你只复制中间一串 Base64,结果后面连不上,纯属给自己找坑。
Windows 上如果用的是 CMD 的type命令,或者 Git Bash 的cat,复制也行,但要小心换行符问题。建议直接右键复制公钥文件内容到剪贴板,或者用以下命令直接输出:
type %USERPROFILE%\.ssh\id_ed25519.pubmacOS 上可以直接执行:
pbcopy < ~/.ssh/id_ed25519.pub这样公钥内容就直接进剪贴板了。
3.3 关于 ssh-agent:到底要不要用
ssh-agent 是一个帮你缓存私钥 passphrase 的系统服务。如果你设了 passphrase,每次 SSH 连接都要输一次密码;但如果你把私钥加载进 agent,agent 会在内存里记住解密后的私钥,后续连接自动完成,不用反复输入。
要不要用,取决于你的场景:
- 个人电脑,没设 passphrase,不需要 agent
- 公司电脑或服务器,设了 passphrase,macOS / Linux 上建议加载 agent
- 多把 Key 混用,agent 可以帮助指定用哪把钥匙,但它也可能造成“钥匙太多不知道选哪把”的混乱,后面第 5 节会详细说这个问题
把私钥加入 agent 的命令:
ssh-add ~/.ssh/id_ed25519macOS 上如果提示Could not open a connection to your authentication agent,先启动 agent:
eval "$(ssh-agent -s)"Windows 上 Git Bash 同样执行eval "$(ssh-agent -s)",然后再ssh-add。
4. 把公钥填到 GitLab 后台,然后验证连通性
4.1 在 GitLab 后台添加 SSH Key
登录 GitLab,点击右上角头像,进入 Preferences(偏好设置),左侧菜单找到 SSH Keys 入口。不同版本的 GitLab 菜单位置略有差异,新版一般在User Settings > SSH Keys,老版本直接在用户首页右侧。这个入口长期稳定,不会随便变。
页面里有几个字段:
| 字段 | 必填 | 说明 |
|---|---|---|
| Key | 是 | 粘贴完整的公钥内容(.pub文件里的整行) |
| Title | 是 | 给这把钥匙起个名,比如“Work Laptop” |
| Expiration date | 否 | 可选过期时间。建议公司电脑不设,个人设备可以设个一年期,方便以后更换 |
填完后点 Add key。GitLab 一般会当场验证格式,格式不对会直接报错。最常见的错误就是粘贴了私钥内容,或者把换行算进去了,检查一下开头是不是ssh-ed25519或ssh-rsa,结尾有没有多余的空格。
添加成功后会看到这把钥匙的指纹信息,说明 GitLab 已经把你的公钥和账号绑定了。到这里,后台部分的配置其实就已经完成了。
4.2 验证连接:用 ssh -T 测试
在终端执行:
ssh -T git@gitlab.com如果你是自建 GitLab,把域名替换成你自己的,比如:
ssh -T git@gitlab.example.com首次连接会提示确认 known_hosts:
The authenticity of host 'gitlab.com (IP地址)' can't be established. ECDSA key fingerprint is SHA256:xxxxxxxx. Are you sure you want to continue connecting (yes/no)?输入yes回车,确认指纹。之后这台主机的指纹会被记录到~/.ssh/known_hosts文件里,后续连接不会再问。
如果一切正常,GitLab 会回复类似:
Welcome to GitLab, @你的用户名!看到Welcome to GitLab就说明 SSH Key 配置成功了。如果提示别的,别慌,第 6 节会逐一排查。
这里有个细节:连接 GitLab 时用的用户不是你的 GitLab 用户名,而是固定的git。SSH 协议连接 GitLab 时统一用git这个“系统用户”,GitLab 通过你用来认证的公钥识别具体是哪个账号。这是 GitLab、GitHub 这类平台的统一设计,别搞混了。
4.3 测试 clone 和 push 是否正常
验证ssh -T通了之后,最好再完整走一遍 clone 和 push 的流程。
从 GitLab 上复制 SSH 形式的仓库地址,形如:
git@gitlab.com:用户名/仓库名.git然后:
git clone git@gitlab.com:用户名/仓库名.git克隆下来后,在项目里随便改点东西,提交并推送:
cd 仓库名 echo "test" >> README.md git add README.md git commit -m "test ssh key" git push origin main这一步如果顺利,说明你的 SSH Key 已经可以正常使用了。
5. 一次配置多把 Key:工作账号和个人账号怎么共处
这是实际工作中很容易踩坑的点。很多人手上不止一个 GitLab 账号,或者同一个 GitLab 上有个人账号和工作机器账号,每把 Key 的私钥文件名如果都一样,后面会互相覆盖,导致最近生成的那把 Key 把旧的顶替了,旧账号直接连不上。
合理的管理思路是这样的:
5.1 生成多把 Key,文件名区分
ssh-keygen -t ed25519 -C "work@example.com" -f ~/.ssh/id_ed25519_work ssh-keygen -t ed25519 -C "personal@example.com" -f ~/.ssh/id_ed25519_personal关键就是-f参数,指定生成文件的路径和文件名。这样~/.ssh/下会有:
id_ed25519_work id_ed25519_work.pub id_ed25519_personal id_ed25519_personal.pub两把钥匙互不干扰。
5.2 用 config 文件指定不同场景用哪把 Key
在~/.ssh/下新建(或编辑)一个文件,名字就叫config,没有扩展名:
Host gitlab.com HostName gitlab.com User git IdentityFile ~/.ssh/id_ed25519_work IdentitiesOnly yes Host gitlab-personal HostName gitlab.com User git IdentityFile ~/.ssh/id_ed25519_personal IdentitiesOnly yes这里有个概念要先搞清楚:Host后面的名字是你给这个连接配置起的“别名”,HostName是真实连接的服务器域名。当你执行ssh -T git@gitlab-personal时,SSH 会读取Host gitlab-personal这段配置,用~/.ssh/id_ed25519_personal去连接gitlab.com这个服务器。
因此,克隆个人仓库时要用别名:
git clone git@gitlab-personal:用户名/仓库名.git工作仓库还是直接用原来的:
git clone git@gitlab.com:用户名/仓库名.gitIdentitiesOnly yes这行的意思是“只用配置文件里指定的这把 Key,不要尝试其它 Key”。不写这一行的话,SSH 会把~/.ssh/下所有 Key 都试一遍,服务器端公钥比对失败后会换下一把,多来几次容易触发 GitLab 的失败限制,或者出现连接很慢的现象。我一开始没弄明白这个参数,结果工作仓和个人仓的钥匙互相乱配,折腾了一下午。加了这个参数之后,一切清清楚楚。
5.3 多个 GitLab 实例的情况
如果你要同时访问多个不同的 GitLab 实例,比如公司内部的gitlab.company.com和公开的gitlab.com,config 文件可以这样写:
Host gitlab.company.com HostName gitlab.company.com User git IdentityFile ~/.ssh/id_ed25519_company Host gitlab.com HostName gitlab.com User git IdentityFile ~/.ssh/id_ed25519_gitlab这次Host直接写真实的域名,不需要别名,因为两个域名本身就区分开了,SSH 能精确匹配。
5.4 多个账号在同一个 GitLab 实例上
如果你在一台机器上同时持有同一个 GitLab 的个人账号和工作账号(或者多个机器账号),只能用上面的“别名法”。因为你不能用同一个真实域名直接区分两把 Key,只能靠Host别名来分。注意如果Host设为gitlab.com,走默认直连时优先级反而容易乱,用别名是最稳的方式。
很多人觉得多账号配置复杂,其实核心就三件事:文件名分开、config 文件映射好、克隆地址用别名。做好这三件事,多账号切换就像喝水一样自然。
6. 常见的坑和排查方法,我踩过的都在这了
6.1 Permission denied (publickey)
这是最典型的问题。ssh -T git@gitlab.com报错Permission denied (publickey),说明 SSH 尝试了你的 Key,但 GitLab 不认。
排查顺序:
| 可能原因 | 检查方法 | 解决办法 |
|---|---|---|
| 公钥没正确添加到 GitLab | 登录后台 SSH Keys 页面看有没有这条记录 | 重新粘贴.pub文件内容,确保整行完整 |
| 私钥路径不对 | 执行ssh -vT git@gitlab.com看日志里尝试了哪个 IdentityFile | 用-i参数指定路径,或配置 config 文件 |
| 粘贴了私钥而不是公钥 | 打开文件看内容:公钥开头是ssh-ed25519/ssh-rsa,私钥是-----BEGIN OPENSSH PRIVATE KEY----- | 重新复制公钥 |
| 权限问题 | macOS/Linux 上私钥文件权限太开放,SSH 拒绝使用 | chmod 600 ~/.ssh/id_ed25519,chmod 700 ~/.ssh |
这里再补充一个排查命令,信息量很大:
ssh -vT git@gitlab.com加-v参数后,SSH 会打印详细日志。重点看两处:Offering public key是不是你期望的那把 Key 的路径;后面有没有Server accepts key字样。如果看到Offering public key: /home/user/.ssh/id_ed25519,但服务器不接受,那基本可以确定是公钥没在 GitLab 后台登记对。
6.2 Host key verification failed
这个报错一般是 known_hosts 文件里记录了冲突的指纹。比如 GitLab 服务器换过 IP 或证书,或者你之前连的是同一个域名但其实是另一台机器。
解决方法是删掉 known_hosts 里对应记录:
ssh-keygen -R gitlab.com再重新连接,接受新指纹即可。注意-R只影响 known_hosts 文件,不会动你的 Key。
6.3 连接慢或者卡很久
如果你发现ssh -T连 GitLab 卡了好几秒才出结果,常见原因有两个:
- DNS 解析慢,GitLab 域名解析到 IP 的过程耗时过长
- SSH 在尝试多把钥匙,每把都跟服务器校验一遍,N 把钥匙就是 N 次往返
第二个原因尤其在多账号配置时常见。解决办法就是我前面说的IdentitiesOnly yes,或者把不用的 Key 挪出~/.ssh/目录放到别的备份目录。
DNS 慢的话,Windows 上可以检查 hosts 文件是否有对应 IP 映射,或者换 DNS 服务器。如果确实是因为网络原因连不上境外 GitLab,那属于网络基础设施问题,跟 SSH Key 本身关系不大,不在本文讨论范围。
6.4 换了新电脑,Key 怎么迁移
换了新电脑后,不要重新生成 Key 再往 GitLab 后台加一遍吗?可以,但这样旧电脑上的 Key 就失效了(如果在后台删除了)。更简单的做法是把旧电脑~/.ssh/下的私钥、公钥文件原样拷贝到新电脑对应的路径。
拷贝完注意修权限:
chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub然后ssh -T验证即可。这里要提醒一下:私钥文件从旧电脑拷走以后,旧电脑上最好删除掉,避免任何隐私泄露风险。你能想象如果旧电脑丢了一台,别人拿到私钥直接 clone 你的私有仓库吗?虽然 GitLab 可以在后台一键删除旧 Key,但防患于未然总是好的。
6.5 邮箱写错导致提交归属混乱
git commit时提交记录里的邮箱不是你生成 SSH Key 时的-C注释,而是git config user.email的值。所以即使 SSH Key 没问题,如果user.email和 GitLab 账号邮箱不一致,提交记录可能显示为“未关联用户”的灰色头像。
这个问题的表现是 push 成功,但仓库的 contributors 统计里找不到你。解决办法是配置全局邮箱:
git config --global user.email "你的GitLab邮箱"如果已经有历史提交记录归属错误,可以用git filter-branch或者git rebase改历史,但那是另一个大话题了。总之,第一次配置完 SSH Key 后,顺手确认一下子全局邮箱是最划算的习惯。
6.6 公钥后端被占用或重复添加
有时候你添加公钥时 GitLab 报错信息,比如“Key already in use”,说明这把公钥已经绑定在其它账号下。你可以登录那个账号删除,或者重新生成一把新 Key。唯一值得提的是,不要试图直接改公钥内容里的邮箱注释来“骗过”GitLab,GitLab 识别的不是注释,而是公钥的指纹。
7. 配置完之后的几个好习惯
配置完 SSH Key 不代表万事大吉,有几个习惯我强烈建议你养成。
第一,定期检查 GitLab 后台的 SSH Keys 列表。凡是离职的人、不再使用的电脑、换掉的设备,其 Key 一定要及时删掉。GitLab 里删 Key 很容易。这是一个安全卫生问题,很多团队出过类似的事故:离职员工的 Key 没删,结果对方 clone 走了公司私有代码。
第二,私钥永远不要上传到任何云端网盘、代码仓库或聊天工具。有些人习惯把id_ed25519拖到网盘备份,这个习惯很危险。如果一定要备份,至少要用压缩包加密。
第三,给 SSH Key 设置备注名。GitLab 后台的 Title 字段不要随便乱写,规范起名比如“2024-15寸MacBook Pro”,这样后续查哪台机器还在用、哪台早丢了,一目了然。我用的是“设备名+日期”的格式,比如MacBook_202504。
第四,使用ssh-keygen -l -f定期查看本地密钥指纹,和 GitLab 后台显示的指纹比对,有异常及时发现。
ssh-keygen -l -f ~/.ssh/id_ed25519.pub这个命令会输出类似256 SHA256:xxxxxxxxxxxxxx 你的邮箱 (ED25519)的指纹,和后台展示的指纹一致就说明没问题。
8. 最后分享一点我的实际体会
配置 GitLab SSH Key 这件事,从第一次配到用顺手,绝大多数人都要走一遍“生成、添加、失败、排查、成功”的流程。整个过程其实不复杂,核心就是三件事:生成一对密钥、公钥给 GitLab 后台、私钥留在本地。很多人卡住,不是因为不会敲命令,而是不太清楚 SSH 认证背后的原理,导致报错时无从下手。
我在帮团队同事排查的时候发现,90% 的“Permission denied”问题,要么是公钥复制不全,要么是多把 Key 没有在 config 文件里指定。把这两个坑填掉,整个配置流程基本就顺了。
另外还有一个容易被忽略的小问题:如果你在 Windows 上用了多个终端工具,比如 Git Bash、PowerShell、Windows Terminal,它们的~/.ssh目录是不是同一个,取决于HOME环境变量指向哪里。Git Bash 的 HOME 默认是C:\Users\你的用户名,PowerShell 下也是同一个用户目录,但如果你把 HOME 改成别的路径,就可能导致不同终端读到的 Key 不一样,明明配好了却能连上,换个终端就不行了。遇到这种诡异情况,先查环境变量echo $HOME。
这套配置不只在 GitLab 上通用,GitHub、Gitea、Bitbucket 等所有基于 SSH 的 Git 平台,操作逻辑完全一样。你只要会配一次,以后换任何平台都能直接套用。如果你现在正准备配置或正在被某个报错卡住,顺着上面第 6 节的排查表走一遍,应该就能解决问题。配置好之后,命令行里git push一路畅通的感觉,是真的舒服。