GitLab SSH Key生成与配置完全指南:从原理到避坑实践
2026/9/18 16:26:05 网站建设 项目流程

1. 先聊清楚:GitLab到底是什么,为什么每个团队都在用

第一次接触GitLab的人,十有八九会把Git、GitHub和GitLab混成一锅粥。我当年也经历过这个阶段,对着终端里的git命令一脸懵,完全搞不清楚它和网页上那个代码仓库到底是什么关系。这里先用最直白的话把这三者的关系捋顺。

Git本身是一个分布式版本控制系统,它负责在你本地跟踪代码的每一次改动,记录谁在什么时候改了什么文件。它不依赖于任何服务器,你甚至可以在断网状态下用Git管理自己的项目。而GitLab和GitHub都是基于Git的代码托管平台,它们把本地的Git仓库同步到远程服务器上,提供网页端的代码浏览、分支管理、合并请求、问题跟踪等功能。如果拿拍照来类比,Git是相机本身,负责按下快门记录瞬间,而GitLab和GitHub是相册,让你把照片洗出来、分类归档、分享给别人看。

GitLab和GitHub最大的区别在于:GitHub是SaaS服务,代码托管在人家服务器上,私有仓库数量有限,而且很多企业级功能要付费;而GitLab是开源软件,你可以把它安装在自己的服务器上,数据完全由自己掌控。这就是为什么大量公司会选择在内部搭建一套GitLab,代码不出内网,安全可控,同时还能利用GitLab自带的CI/CD流水线能力实现自动化部署。

标题里提到的“ssh key生成及使用”是使用GitLab绕不开的第一步。很多新手在克隆代码时习惯了输入用户名密码的HTTPS方式,但一旦涉及自动化部署、频繁pull/push、或者公司强制要求安全认证,SSH Key就成了必经之路。这篇内容就围绕GitLab的基本使用方式展开,重点带你走通SSH Key的生成、配置、排查全流程,挨个把坑踩平。

2. 为什么强烈推荐用SSH Key连GitLab

2.1 HTTPS和SSH两种连接方式,到底差在哪

在你把一个远程仓库克隆到本地之前,Git需要确认“你确实是这个项目的成员”。GitLab支持两种认证方式:

第一种是HTTPS方式,链接长这样:https://gitlab.com/yourgroup/project.git。每次执行git push或者git pull的时候,Git都会弹出窗口让你输入GitLab的用户名和密码(实际是Token或个人访问令牌)。如果装了Git的凭据管理器,它能帮你把密码记住,不用每次手动输,但这种方式本质上还是“账号密码+服务器验证”。

第二种就是SSH方式,链接长这样:git@gitlab.com:yourgroup/project.git。它用的是公钥加密和私钥签名的认证机制,你只需要提前把公钥配置到GitLab账号里,之后的每一次连接都走密钥自动认证,不会再弹出任何密码输入框。

两种方式的体验差异,就好比一个是每次进小区都要在门卫那儿登记身份证,另一个是刷脸进门,一次录入,之后畅通无阻。

2.2 SSH Key的工作原理,用生活例子讲明白

SSH Key是一对非对称加密钥匙,包含一个私钥和一个公钥。私钥保存在你本地电脑上(默认在~/.ssh/id_ed25519),绝对绝对不能泄露;公钥则是一串明文文本,你可以大方地把它配置到GitLab上。

它的认证过程是这样的:当你向GitLab发起SSH连接时,服务器会生成一段随机数据发送给你,你的SSH客户端用私钥对这段数据进行签名,然后把签名结果发回给服务器。服务器用你预先配置的公钥验证这段签名,如果验证通过,说明“持私钥的人确实是公钥的主人”,于是认证成功。

这个机制和保险柜的原理很像:公钥是保险柜的锁,任何人都可以看到锁长什么样,但只有拿着正确钥匙(私钥)的人才能打开柜子。你不需要把钥匙交给别人,只需要让服务器记住“这把锁认哪把钥匙”,后续的身份验证就全部自动化了。

2.3 为什么说配置SSH Key是开发效率的分水岭

在实际开发中,SSH Key的优势体现在几个非常具体的场景里。

第一个场景是日常开发中的高频push操作。用HTTPS方式如果没配凭据管理器,每次都输Token不仅烦,还容易输错;配了凭据管理器,多账号切换又容易出错。SSH方式一劳永逸,绑定一次,以后无感操作。

第二个场景是CI/CD自动化。Jenkins、GitLab Runner这类自动化工具在拉取代码时,需要一个无人值守的认证方式。账号密码会过期、Token轮换需要改配置,而SSH Key只要不被吊销,就能一直稳定工作。很多团队最初的自动化构建跑不起来,排查到最后发现就是认证方式选错了。

第三个场景是安全合规。私钥不出本地机器,公钥才传给服务器,整个认证链条里没有明文密码在网络中传输,安全等级明显高于用户名密码。

3. SSH Key生成实操:从零到一

3.1 生成之前,先看看自己有没有“老钥匙”

在动手生成新Key之前,我强烈建议你先检查一下本地是否已经存在SSH Key。很多新手不查直接一路回车,生成了新的密钥对,然后把公钥配置到GitLab上,结果发现之前配的GitHub、服务器或者其他平台的连接全断了——因为新的密钥对覆盖了旧的。

打开终端,执行下面这个命令:

ls -al ~/.ssh

这条命令会列出.ssh目录下的所有文件。如果你看到id_rsaid_rsa.pubid_ed25519id_ed25519.pub这类文件,说明本地已经有一对密钥了。其中.pub后缀的是公钥,没有后缀的是私钥。

此时你有两个选择:

  • 如果之前生成的Key还在正常使用,完全可以直接沿用,跳到下一节把公钥配置到GitLab即可。
  • 如果确定这些Key已经废弃了,或者你就是想给GitLab单独生成一把独立的Key(强烈推荐,后面会讲原因),那可以跳过旧文件,用另一个名字生成新Key。

3.2 正式生成:选择合适的加密算法和管理口令

现代GitLab环境我推荐直接生成ED25519类型的密钥,命令如下:

ssh-keygen -t ed25519 -C "你的邮箱地址"

-t ed25519指定密钥类型为Ed25519,这是一种比传统RSA更安全、性能更好、密钥长度更短的算法。-C后面的备注信息会写进公钥文件的末尾,方便你在GitLab服务器上识别这把Key是哪个设备、哪个用途的,比如-C "work-laptop"或者-C "root@ubuntu-server"

执行命令后,终端会提示你输入保存密钥的文件路径:

Generating public/private ed25519 key pair. Enter file in which to save the key (/home/user/.ssh/id_ed25519):

这里我建议不要直接回车用默认文件名,而是给它一个能区分场景的名字,比如~/.ssh/id_ed25519_gitlab。原因在于,如果你同时使用GitHub、Gitee、公司GitLab等多个代码平台,每个平台用一把独立的Key,后续通过配置文件来分流,会省去很多管理上的麻烦。这个方案我下面会详细展开。

接着系统会询问是否设置passphrase:

Enter passphrase (empty for no passphrase): Enter same passphrase again:

passphrase是给私钥再加一层密码保护。即使有人拷贝了你的私钥文件,没有passphrase也无法使用。但代价是每次使用SSH Key时都要输一次密码,体验稍打折扣。

我的建议是:个人开发机可以留空,方便快捷;公司配发的电脑或者有高安全要求的服务器,务必设置passphrase。还有一个折中方案是用ssh-agent把解锁过的私钥加载到内存里,设置一个较长的存活时间,既安全又不用反复输密码。

生成完成后,再次查看.ssh目录,你会看到两个新文件:

id_ed25519_gitlab # 私钥,留在本地 id_ed25519_gitlab.pub # 公钥,可以给别人

千万记住:私钥文件权限应该是600,公钥文件权限是644。如果你发现权限不对,可以执行chmod 600 ~/.ssh/id_ed25519_gitlab修正。Linux和macOS对密钥文件权限很敏感,权限太开放直接拒绝使用。

3.3 查看公钥内容的正确姿势

公钥文件就是一段纯文本,你可以用任何文本编辑器打开。终端里查看最方便:

cat ~/.ssh/id_ed25519_gitlab.pub

输出内容长这样:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINxxxxxxxxxxxxxxxxxxxxx work-laptop

ssh-ed25519开头,到最后的备注信息结束,这一整行都是公钥。复制的时候要完整复制,不能漏掉任何字符,尤其不能漏掉开头的算法标识和结尾的注释部分。很多人在这一步翻车,复制的时候只复制了一部分,导致配置到GitLab上之后一直认证失败。

4. 把公钥配置到GitLab:3分钟搞定

4.1 在GitLab网页上添加公钥

登录GitLab后,点击右上角的头像,在下拉菜单中选择“Preferences”(偏好设置),这是旧版GitLab的入口。新版GitLab中,这个菜单可能叫“Edit Profile”或者直接显示你的用户名。

在偏好设置页面左侧菜单中找到“SSH Keys”选项(中文界面叫“SSH密钥”)。点击进入后,你会看到一个表单,包含三个字段:

  • Key:粘贴你刚才复制的完整公钥内容
  • Title:给这把Key起个名字,方便识别,建议格式是“设备名-用途”,例如office-pc-mainhome-macbookci-runner
  • Expiration date:过期日期,可选。如果不填就永不过期。出于安全考虑,公司服务器或者CI Runner这类长期使用的Key建议设置一个定期轮换的过期时间,比如一年

填写完成后点击“Add key”绿色按钮,页面刷新后,你的公钥就出现在密钥列表中了。

4.2 验证SSH连接是否正常

配置完公钥后,别急着克隆代码,先验证一下连接是否打通:

ssh -T git@gitlab.com

如果你是连接自己公司内网搭建的GitLab,域名换成对应的内网地址,比如:

ssh -T git@gitlab.yourcompany.com

第一次连接时,系统会提示确认远程主机的指纹信息:

The authenticity of host 'gitlab.com (xxx.xxx.xxx.xxx)' can't be established. ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxx. Are you sure you want to continue connecting (yes/no)?

这里输入yes并回车,之后系统才会输出连接结果。如果一切正常,你会看到类似这样的欢迎信息:

Welcome to GitLab, @yourusername!

看到这行字,就说明SSH认证已经全部打通,接下来就能愉快地克隆和推送代码了。

4.3 一次配置,管理多个平台密钥的进阶方案

很多开发者的实际情况是:GitHub有自己的项目,公司GitLab有业务代码,可能还有一台自己买的云服务器。每个平台需要用不同的SSH Key,以免一个私钥泄露导致所有平台全部沦陷。

这时候就需要在~/.ssh/config文件里做分流配置。如果.ssh目录下没有这个文件,手动创建一个即可。配置内容示例:

# GitHub Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519_github # 公司GitLab Host gitlab.yourcompany.com HostName gitlab.yourcompany.com User git IdentityFile ~/.ssh/id_ed25519_gitlab # 个人云服务器 Host myserver HostName 203.0.113.10 User root IdentityFile ~/.ssh/id_ed25519_server

配置完成后,SSH客户端会根据你连接的主机名自动匹配对应的私钥,互不干扰。这也是我前面强调要为不同平台生成独立Key的原因。

5. SSH Key配置完成后,日常开发的核心操作

5.1 克隆代码:SSH链接和HTTPS链接的区分

在GitLab项目主页点击“Clone”按钮,会弹出两个Tab:Clone with HTTPS和Clone with SSH。如果你完成了上面的SSH配置,就直接复制SSH链接。

举个例子,HTTPS链接长这样:

https://gitlab.com/yourgroup/project.git

SSH链接长这样:

git@gitlab.com:yourgroup/project.git

克隆命令完全一样:

git clone git@gitlab.com:yourgroup/project.git

区别在哪?HTTPS克隆下来之后,每次git push可能都要验证身份;SSH克隆下来之后,push操作全程静默完成,不需要手动输入任何凭据。这个差异在日常使用中感知非常明显。

5.2 一次完整的代码提交流程

配合SSH Key,一次标准的代码提交推送流程非常顺畅。假设你已经克隆了项目,并且创建了一个新功能分支:

# 1. 查看当前状态 git status # 2. 添加所有改动到暂存区 git add . # 3. 提交到本地仓库,附带清晰的提交信息 git commit -m "feat: 添加用户登录功能" # 4. 推送本地分支到远程仓库 git push origin feature-login

推送完成后,你去GitLab网页上刷新项目页面,就能看到远程分支已经更新。之后通常是在网页上发起一个Merge Request(合并请求),邀请同事评审代码,评审通过后合并到主分支。

5.3 分支管理:创建、切换、合并、删除

在实际团队协作中,分支操作频率很高。日常常用的命令如下:

创建并切换到一个新分支:

git checkout -b feature-xxx

切回主分支:

git checkout main

把功能分支合并到当前分支:

git merge feature-xxx

推送本地分支到远程并设置上游跟踪:

git push -u origin feature-xxx

删除本地分支:

git branch -d feature-xxx

删除远程分支:

git push origin --delete feature-xxx

这些命令和是否配置SSH Key没有直接关系,但SSH连接让整个流程更顺畅,特别是频繁push、pull切换分支的时候,不用反复验证身份,体验上的提升非常明显。

5.4 解决日常开发里最让人头疼的合并冲突

冲突是多人协作里完全绕不开的问题。两个人都改了同一个文件的同一段代码,Git无法自动合并,只能让人工介入。

假设你在feature-login分支上修改了Login.java,同事在主分支上也改了同一个文件的同一个方法,合并时就会出现冲突。

解决方案是:先把远程主分支的最新代码拉取下来,然后在本地解决冲突。

# 1. 切到主分支,拉取最新代码 git checkout main git pull origin main # 2. 切回功能分支 git checkout feature-login # 3. 把主分支合并到功能分支,此时可能产生冲突 git merge main

如果冲突产生了,Git会在冲突文件中用<<<<<<< HEAD>>>>>>> main这样的标记把两边的内容标识出来。这时候用VS Code或者其他编辑器打开文件,逐处确认保留哪一边的代码、还是两边都保留并手动整合。解决完所有冲突后:

git add . git commit -m "merge: 解决与主分支的冲突" git push origin feature-login

这几十行命令覆盖了本地日常开发中最核心的操作流程,足够应付绝大多数场景。

6. 踩坑经验:SSH Key使用中高频出现的几个问题

6.1 Permission denied (publickey)

这是最经典的报错,出现频率堪称SSH问题之王。它表示服务器验证公钥失败,可能性很多:

  • 公钥粘贴的时候漏了字符,或者用截图OCR识别导致乱码
  • 私钥路径配置错误,SSH客户端根本找不到对应的私钥
  • 本地.ssh目录下有多个私钥,但第一个加载的私钥不是GitLab对应的那把
  • GitLab上的公钥被管理员删除了或者过期了

排查思路是先用ssh -T git@gitlab.com查看详细错误信息,再用ls -al ~/.ssh确认密钥文件是否存在。如果用多个私钥,优先推荐配置~/.ssh/config文件指定IdentityFile

6.2 Host key verification failed

这个报错在网络环境变化或服务器重建后经常出现。原因是本地的~/.ssh/known_hosts文件里还保存着旧的主机指纹,而服务器端的指纹已经变了,SSH发现两者对不上,就拒绝继续连接。

解决方案很简单,用命令删除旧指纹:

ssh-keygen -R gitlab.com

然后重新连接,按提示接受新的指纹即可。如果你连接的自建GitLab端口不是22,记得额外指定端口:

ssh -T -p 2222 git@gitlab.yourcompany.com

在克隆代码时,非标准端口写法也不同:

git clone ssh://git@gitlab.yourcompany.com:2222/yourgroup/project.git

6.3 同一个仓库,为什么push还是提示输密码

这种情况往往是因为克隆的时候用了HTTPS链接,而不是SSH链接。你手上的SSH Key就算配置得再完美,HTTPS连接也完全不会使用它。

检查方式是命令:

git remote -v

如果输出里remote地址以https://开头,说明当前仓库用的是HTTPS方式。改成SSH方式:

git remote set-url origin git@gitlab.com:yourgroup/project.git

之后再push,就会走SSH认证,不会再输密码。

6.4 换新电脑后,原来的SSH Key怎么办

这是一个高频但很多人操作错误的场景。有人直接把旧电脑的私钥文件拷贝到新电脑,这个做法可行但有风险。更规范的做法是:

  • 旧电脑上如果可能,把旧Key从GitLab上删掉,防止私钥泄露后被人利用
  • 在新电脑上生成全新的Key,把新公钥再添加回GitLab

如果你的工作同时涉及GitHub和GitLab,记得每个平台都用独立的Key,不要图省事共用一把,这样即使某个平台被打穿,其他平台的代码仓库还是安全的。

6.5 常见问题速查表

我把高频问题和对应解法整理成一张表,方便收藏备查:

问题现象可能原因快速解法
Permission denied (publickey)公钥未配置或私钥路径不对重新添加公钥,检查IdentityFile配置
Host key verification failed服务器指纹变更ssh-keygen -R gitlab.com后重连
push仍提示输密码仓库用的是HTTPS地址git remote set-url origin改SSH地址
多个Key对不上号没有配置~/.ssh/config按Host指定各自的IdentityFile
连接超时或卡住网络不通或端口被防火墙拦截检查22端口连通性,或改用443端口
GitLab提示Key已过期Key设置了Expiration date在GitLab上更新Key并重新配置

6.6 几个独家避坑小技巧

第一,~/.ssh目录的权限一定要正确。私钥文件权限如果是664或777,SSH会直接拒绝使用,并提示Permissions 0664 for 'id_ed25519' are too open。新生成的文件默认权限是对的,但如果从别人那儿拷贝了密钥文件过来,这个坑特别容易踩。

第二,CI/CD环境里使用SSH Key时,不要把私钥直接硬编码到gitlab-ci.yml文件里,而应该使用GitLab的CI/CD变量(Settings -> CI/CD -> Variables)来存储私钥内容,流水线里用echo "$SSH_PRIVATE_KEY"注入到环境变量中,避免密钥泄露到代码仓库。

第三,GitLab管理员在后台能看到每个账号加载了哪些Key,建议定期梳理账号下的密钥列表,及时删掉已经不再使用的设备Key。我给公司的建议是每半年做一次密钥巡检,宁可让同事重新配置一遍,也不能留下无人认领的“僵尸Key”。

7. 从SSH Key往后走:GitLab的更多可能性

7.1 当SSH Key遇到CI/CD自动化

很多团队用GitLab不只是为了管代码,还会借助GitLab CI/CD实现自动构建和部署。流水线里Runner在拉取代码的时候,用的就是SSH认证。

简单说下流程:GitLab Runner是一个独立服务,它可以从GitLab服务器接收构建任务。Runner执行任务时,需要把代码仓库拉取到执行机,这时候Runner机器上就要配置能访问对应项目的SSH Key。

踩过的坑是:Runner的SSH Key不能和个人开发机的Key共用,应该单独生成一把独立的Key,并且把公钥添加到一个专门为CI创建的GitLab账号上,或者用Deploy Key的方式只授权某个特定的仓库。否则一旦Runner的执行机被入侵,你的个人GitLab账号也会跟着遭殃。

7.2 用Deploy Key实现仓库级别的访问控制

GitLab提供了一种叫Deploy Key的功能,它绑定的是仓库而不是个人账号。也就是说,你可以为某一个特定仓库单独生成一对Key,公钥配置到仓库的Settings -> Repository -> Deploy Keys中。这样CI Runner或者某台服务器只能访问这一个仓库,即使密钥泄露,攻击者也进不了你的个人账号和其他项目。

这是我在实践中最推荐的CI认证方案,安全边界非常清晰。

7.3 本地多账号场景的最终解法

如果你手里同时维护着GitHub、公司GitLab、个人GitLab等多个代码平台,前面提到的~/.ssh/config方案是目前最优雅的解法之一。我再给出一个常见配置片段:

Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519_github 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_personal

配置完成后,无论你连接哪个平台,SSH都会自动选择对应的私钥,完全无感切换。这个方案配合SSH Key使用,基本可以覆盖开发者日常工作中的绝大多数认证场景。

8. 关于SSH Key安全,最后想多说几句

SSH Key是本地机器和GitLab之间的唯一身份凭证,私钥一旦泄露,别人就能登录你的GitLab账号,拉取你所有的私有仓库,甚至以你的名义推送恶意代码。这个后果非常严重,因为代码仓库是公司最核心的资产之一。

几个安全习惯强烈建议养成:

私钥不要通过即时通讯工具、邮件或网盘传输。如果需要在新电脑上配置,请在新电脑上现场生成新Key,不要跨机器拷贝私钥文件。

定期检查GitLab账号里的Key列表,删除不再使用的设备Key。特别是离职员工的设备,管理员要及时清除。

可以给Key设置Expiration date。虽然到期续期稍微麻烦一点,但这个麻烦是值得的,它能保证即使密钥被泄露,也只是一个短期有效的泄漏。

执行重要操作之前,先确认一下自己当前用的是哪把Key。命令行可以快速查看:

ssh -T git@gitlab.com

如果输出里的用户名不是你以为的那个人,那就要立刻停下来排查,千万别继续操作。

我在实际维护公司GitLab的过程中,遇到过太多因为SSH Key配置不当引发的生产事故:有开发者的私钥泄露到公开仓库导致代码被爬走,有CI Runner因为Key过期导致整条流水线崩溃,还有同事把多个平台的Key混用导致权限混乱。这些问题一旦发生,排查起来往往比直接配置还要费时。所以,宁可在一开始多花十分钟把Key管理好,也别等出了问题再回头补救。SSH Key这个东西,配置一次,受益几年,但前提是你真的把它当回事儿来对待。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询