ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Windows下配置Git多平台SSH密钥:GitHub、GitLab、Gitee三套环境共存

Windows下配置Git多平台SSH密钥:GitHub、GitLab、Gitee三套环境共存 1. 为什么要在Windows上同时配置三套Git环境1.1 三个平台并存才是开发者的日常如果你只是偶尔往GitHub传点代码那今天这篇你大概率用不上。但只要你经历过公司项目、个人开源、国内托管三线作战你很快就会意识到一件事电脑上只有一个默认SSH Key根本没法在三家平台之间体面地共存。我自己的真实场景是这样公司在腾讯云上自建了GitLab所有业务代码、内部组件库、配置文件都放在上面自己的开源项目、博客源码放在GitHub还有一些偏国内业务、需要加速拉取的小项目放在Gitee上。以前每次切换到不同平台都要重新改~/.ssh/config或者干脆给每个仓库单独设置密钥麻烦不说还容易把密钥配错权限报错能卡你一下午。这套三平台并存的配置核心解决的就是一个问题让Git知道连接github.com时用哪把钥匙连接gitlab.company.com时用哪把钥匙连接gitee.com时又用哪把钥匙。配好之后你在三个平台之间切换提交、推送、拉取完全不需要手动干预就像同时拿着三把钥匙进了三扇门Git自动帮你把门对上。1.2 多仓库并存的底层逻辑SSH协议是怎么认人的要理解多平台共存你得先搞清楚Git通过SSH连接远程仓库时服务器是怎么验证你身份的。SSH认证走的是非对称加密你本地存私钥服务器存公钥。当你执行git push时客户端会拿着私钥去敲门服务器用你预先上传的公钥来验明正身。这里有个关键点Git本身并不过问你要连的是GitHub还是GitLab它只负责把SSH请求发给对应的域名至于用哪个密钥是SSH客户端根据配置决定的。如果你只有一个默认密钥id_rsa那把公钥上传到GitHub可以再上传到Gitee也可以这本身不冲突。但问题出在你想在同一个平台注册两个账号比如工作和个人或者你换了电脑、重新生成密钥之后旧公钥忘记在平台侧删除就会出现密钥到处飘的混乱局面。更麻烦的是如果你用的不是默认文件名Git会一脸懵地告诉你Permission denied (publickey)。所以三平台并存的本质不是同时用三个Git客户端而是一套Git环境下用SSH Config把不同的域名路由到不同的私钥文件。把这一点想通了后面所有配置步骤都顺理成章。1.3 整体配置思路先分钥匙再写路由我推荐的配置顺序也是很多老手实际采用的标准流程生成三把独立的SSH密钥分别命名为id_ed25519_github、id_ed25519_gitlab、id_ed25519_gitee互不干扰。把三把公钥分别上传到三个平台的SSH Keys管理页面。在~/.ssh/config里写清楚每个Host对应哪个私钥文件。用ssh -T逐个测试连接确认通了再推代码。最后在仓库目录里单独配置user.name和user.email保证提交人身份跟随仓库走。整个流程走下来大概十分钟。我用的是ed25519算法而不是传统的RSA一是因为生成快二是密钥长度短、安全性更高GitHub和Gitee现在都完整支持GitLab只要是较新的版本也没问题。如果你公司GitLab版本特别老再退回去用rsa -b 4096也不迟。2. 多SSH密钥生成与平台公钥配置实操2.1 环境准备确认Git版本和SSH客户端在Windows上配置第一步不是急着敲命令而是确认你的环境是干净的。我见过太多人卡在ssh命令都输不了或者密钥生成后根本找不到文件基本都是环境没准备好。打开PowerShell或者Windows Terminal先看Git版本git --version只要输出类似git version 2.40.0.windows.1就没问题。然后确认SSH客户端可用ssh -VWindows 10 1809以后的系统自带OpenSSH客户端如果你装了Git for Windows它也会自带一套SSH工具。这里有个坑值得注意系统自带的OpenSSH和Git自带的SSH两套工具读配置文件的位置其实是一样的都是C:\Users\你的用户名\.ssh\但在某些环境下版本差异会导致密钥算法兼容性问题。我一般建议直接用Git Bash来操作路径统一不容易出幺蛾子。打开Git Bash后检查.ssh目录是否存在ls -la ~/.ssh如果提示No such file or directory说明还没创建过后面生成密钥时会自动创建。如果目录里已经有id_rsa和id_rsa.pub那说明之前配过默认密钥不要慌我们新生成的密钥文件用独立名字和它井水不犯河水。2.2 生成三把独立密钥命名规范必须到位这是整套配置里最核心的步骤文件名直接决定了后面config文件好不好写。我强烈建议你在生成密钥的时候就按平台名来命名别偷懒用id_rsa_1、id_rsa_2这种否则两个月后你根本记不住哪把钥匙对着哪扇门。依次执行以下三条命令每条都会提示你输入存放路径和设置密码短语ssh-keygen -t ed25519 -C github-xxxexample.com -f ~/.ssh/id_ed25519_githubssh-keygen -t ed25519 -C gitlab-xxxcompany.com -f ~/.ssh/id_ed25519_gitlabssh-keygen -t ed25519 -C gitee-xxxexample.com -f ~/.ssh/id_ed25519_gitee解释一下每个参数的作用-t ed25519指定密钥算法为Ed25519目前安全性和性能都很优秀。-C注释信息一般填你的邮箱方便在平台后台识别这把钥匙是谁的。-f指定生成的私钥文件路径公钥会自动生成在同一个目录文件名多一个.pub后缀。命令执行过程中会问你是否设置passphrase密码短语。这里我建议设置一个简单的短语成本极低但能防止别人拿到你的私钥文件直接推代码。Git Bash下输入密码时不会显示任何字符你以为是卡住了其实是正常的。如果实在嫌麻烦直接回车留空也可以密钥文件就完全裸奔了。生成完后执行ls -l ~/.ssh你应该能看到六把文件三把私钥配三把公钥数量对得上才算正常。2.3 平台侧添加公钥三个后台的操作差异密钥生成完你得把公钥内容填到平台后台去。在Git Bash里用cat命令查看公钥cat ~/.ssh/id_ed25519_github.pub输出形如ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... github-xxxexample.com把这个内容完整复制包括开头的ssh-ed25519和结尾的邮箱注释然后分别去三个平台添加。GitHub登录后进入Settings-SSH and GPG keys-New SSH key标题随便填比如Windows Work PCKey Type选Authentication Key把公钥粘进去保存。GitLab进入Preferences-SSH KeysKey栏粘贴公钥Title会自动带出注释Expiration Date可以留空或设置一年后。注意GitLab保存公钥时格式校验很严格开头结尾的空格都会被判为非法粘贴时最好确认一下没有多余的换行。Gitee进入设置-安全设置-SSH公钥把公钥粘进大输入框标题自动生成点确定。Gitee还支持同一个账号绑定多台电脑的公钥每台设备生成一把独立的钥匙管理起来也方便。这一步有个细节公钥添加完之后不要马上关闭页面等后面测试连通性通过了再关。万一测试失败你还得回来检查是不是公钥粘贴出了问题。3. 用config文件实现多Git平台自动匹配3.1 config文件到底是什么为什么它能救你如果你只用默认的id_rsa点对点连接一个平台那确实不需要config文件。但现在我们有三把钥匙、三个平台Git当被告知gitgithub.com:xxx/repo.git时它默认会去找~/.ssh/id_rsa如果你没有这个文件或者id_rsa对应的公钥没上传到GitHub权限报错就来了。~/.ssh/config就是SSH客户端的路由表。它会告诉SSH当你试图连接某个Host时使用哪个用户、哪个私钥、哪些参数。相当于你在小区门口放了一块指示牌外卖小哥看到3栋走A门、5栋走B门就能准确送达不会敲错门。在Git Bash里创建这个文件touch ~/.ssh/config然后用你用着顺手的编辑器打开我一般在命令行直接写内容vim ~/.ssh/config不会vim也没关系用记事本打开也行但保存时记得编码选UTF-8文件不要带.txt后缀。3.2 完整配置示例逐行拆解关键参数下面是我用了很久的一份config配置适配GitHub、GitLab、Gitee三平台# GitHub Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519_github IdentitiesOnly yes # GitLab如果公司自建把HostName换成实际域名/IP Host gitlab.company.com HostName gitlab.company.com User git IdentityFile ~/.ssh/id_ed25519_gitlab IdentitiesOnly yes # Gitee Host gitee.com HostName gitee.com User git IdentityFile ~/.ssh/id_ed25519_gitee IdentitiesOnly yes这里面每个参数的用途我逐个说明Host你访问远程仓库时使用的别名。对GitHub和Gitee来说必须与真实域名保持一致不能乱改否则git命令里的URL会对不上。HostName实际连接的域名或IP。如果你公司GitLab部署在内网这里填内网地址如果绑定了域名填域名即可。UserSSH登录用户名。Git平台统一使用git不需要改也不需要填你的平台账号名。IdentityFile指定该Host使用的私钥路径这里的~会被自动解析成用户主目录。IdentitiesOnly yes这个参数容易被忽略但非常重要。它强制SSH只使用config里指定的私钥而不会一股脑把所有密钥都试一遍。很多多密钥串门的问题就是没加这个参数导致的。如果你还有第二个GitLab仓库组、第二个GitHub账号其实就是在config里再加一组相同结构的配置Host换一个别名即可。比如你有一个私有GitLab实例和公司GitLab可以用Host gitlab-private.company.com区分。3.3 测试连接用ssh -T把三扇门都敲一遍配置写完后先检查config文件格式是否正确ssh -T gitgithub.com第一次连接会提示确认主机指纹输入yes回车即可。如果配置正确你会看到类似输出Hi xxx! Youve successfully authenticated, but GitHub does not provide shell access.这就是门已打开的标志。接着测GitLabssh -T gitgitlab.company.comGitLab会返回你的用户名Welcome to GitLab, xxx!最后测Giteessh -T gitgitee.comGitee的返回比较个性Hi xxx! Youve successfully authenticated, but Gitee does not provide shell access.三个平台全部返回包含successfully authenticated或者对应欢迎语的提示说明路由已经全部打通。如果哪个平台报Permission denied (publickey)优先检查三件事config里的HostName写没写对、私钥路径写没写对、公钥有没有传到对应平台后台。我们后面单独开一节讲排错。测试通过之后还有一个增量操作值得做把~/.ssh目录下的私钥文件权限收紧Windows上一般默认就行但如果你用的是WSL或者共享目录注意别把私钥暴露给所有人。4. 提交身份隔离与多仓库推送完整流程4.1 为什么提交人的身份也要跟着平台走密钥搞定了很多人以为大功告成结果第一次往GitLab推代码提交记录里显示的作者居然是自己GitHub账号的邮箱。这就是提交身份没有隔离导致的。Git记录提交作者靠的是user.name和user.email这两个配置。如果你在安装Git时随手设置了--global的全局身份那么所有仓库提交都会用这个身份不管你是往公司GitLab推还是往个人GitHub推。这在多数场景下说得过去但如果你希望GitHub上的提交显示个人邮箱、GitLab上的提交显示公司邮箱或者干脆希望不同仓库用不同昵称那就要用局部配置覆盖全局配置。优先级的顺序是仓库级配置 全局配置 系统配置。仓库级配置写在每个项目目录的.git/config里只在当前仓库生效正好可以用来做身份隔离。4.2 用局部配置覆盖全局身份避免提交错人先看一眼你的全局配置是什么git config --global --list然后进入某个项目目录单独设置这套仓库的提交身份。以我的公司GitLab项目为例cd /d/projects/company-app git config user.name Zhang San git config user.email zhangsancompany.com再切到个人GitHub项目cd /d/projects/my-blog git config user.name zs-tech git config user.email zs.personalexample.com设置完后用git config --local --list确认无误。这样每个仓库的提交记录都会被打上对应的身份标签GitHub和GitLab后台统计的贡献图也不会串台。这里我建议全局配置只设一个兜底的通用身份具体仓库一定要单独设局部身份。别嫌麻烦这个习惯能避免很多尴尬。比如你某天在一个临时目录里初始化了仓库忘了设局部身份提交到GitHub后作者栏里出现了公司邮箱负责开源社区维护的朋友可能就会私信问你这是谁。4.3 从拉取到推送三平台完整操作流程演示配置全部就绪我们拿一个真实场景完整走一遍。场景一从GitHub克隆并推送新分支git clone gitgithub.com:zs-tech/my-blog.git cd my-blog git config user.name zs-tech git config user.email zs.personalexample.com git checkout -b dev/feature-xxx # 写代码、提交 git add . git commit -m feat: add new post git push origin dev/feature-xxx全程不需要指定密钥SSH自动匹配非常顺畅。场景二在已有GitLab仓库上改代码git clone gitgitlab.company.com:backend/api-service.git cd api-service git config user.name Zhang San git config user.email zhangsancompany.com git pull origin main git checkout -b fix/logic-error git push origin fix/logic-error注意这里gitgitlab.company.com中的域名必须和config里Host gitlab.company.com保持一致SSH才能认路。场景三Gitee仓库的初始化推送cd /d/projects/gitee-utils git init git remote add origin gitgitee.com:zs-tech/gitee-utils.git git add . git commit -m init project git push -u origin master推送之前别忘设置局部身份。Gitee的分支默认叫master还是main取决于你在平台创建仓库时怎么选的保持一致即可。整套流程跑下来你会发现一次公钥配置、永久无忧切换。以后新建项目只需要git clone或git init再设置一下局部身份就行完全不用再碰config文件。5. 三平台共存常见问题排查实录5.1 实战排错权限拒绝、密钥错位、身份串台我配置过不下十次多平台环境也帮同事排查过不少问题这里把最高频的几个问题整理成速查表你可以直接对照着找原因。现象可能原因解决办法Permission denied (publickey)对应平台的公钥未添加或config路径写错用cat ~/.ssh/id_ed25519_xxx.pub检查公钥内容重新上传确认config中IdentityFile路径与私钥实际位置一致GitHub能连GitLab权限拒绝config里Host和HostName写错或私钥匹配到旧文件检查GitLab对应的Host段是否正确确认IdentitiesOnly yes已加上gitgithub.com: Permission denied (publickey)且提示no such identity私钥文件不存在或名字与config不一致用ls -l ~/.ssh核对文件名修改config或重新生成密钥提交记录作者显示成别人仓库级user.name/email没设置用了全局配置在项目目录执行git config user.name 期望名字和git config user.email 期望邮箱ssh: Could not resolve hostname xxx域名写错或存在代理导致DNS解析异常检查config中HostName拼写确认仓库URL中的域名与config的Host一致Gitee连接时提示key already in use同一把公钥被绑到了其他账号去之前绑定的账号后台删除旧公钥或重新生成一个新密钥用于Gitee5.2 换电脑之后如何快速把配置迁移过来最常见的一个场景是换了新电脑。你在旧机器上配得好好的新机器一git clone就报权限错误。原因很简单新机器上没有私钥文件平台后台绑定的公钥也对应的是旧私钥。别急着重新生成密钥。有两种方案方案一是把旧机器的.ssh整个目录拷贝到新机器对应位置注意拷贝后私钥文件权限不能太宽松方案二是在新机器上重新生成密钥然后把新公钥分别添加到三个平台后台。我个人的建议是方案二理由很简单旧私钥在过去的使用中可能已经暴露过而且重新生成一次密钥的成本不到两分钟换来的是更干净的密钥链。如果你实在懒得换方案一也完全可用记得把config文件一起拷过去。新机器配置完成后逐平台跑一遍ssh -T测试通过之后再拉取代码。整个过程就是在重复本文第二节到第三节的步骤而已。5.3 关于ssh-agent的坑为什么有时候改了密钥不生效还有一个容易被忽略的点是ssh-agent缓存。Windows的OpenSSH服务会在后台缓存你输入过的私钥如果你在config里改了IdentityFile指向但ssh-agent里缓存了旧私钥连接时可能还是会拿出旧钥匙去试。遇到这种情况清空缓存再重新添加ssh-add -D然后重新添加需要的私钥ssh-add ~/.ssh/id_ed25519_github ssh-add ~/.ssh/id_ed25519_gitlab ssh-add ~/.ssh/id_ed25519_gitee执行完后再测连接就干净了。如果你发现ssh-add报错Could not open a connection to your authentication agent说明ssh-agent进程没启动先在PowerShell里启动服务Get-Service ssh-agent | Set-Service -StartupType Manual Start-Service ssh-agent然后再回到Git Bash执行ssh-add。5.4 一个不太常见但很实用的小技巧最后分享一个很多教程不会提的操作如果你同一个项目需要同时推送GitHub和Gitee可以不用手动push两次直接给一个仓库加两个remote地址。前提是你已经配好了两把密钥并且两个平台都绑定了对应公钥。git remote add github gitgithub.com:zs-tech/my-tool.git git remote add gitee gitgitee.com:zs-tech/my-tool.git git push github main git push gitee main或者用git remote set-url origin --push --add把多个地址绑定到同一个remote这样一条git push就能同时推送到两个平台。多平台协同发布时这个技巧能省不少时间。回到文章开头说的那个场景现在我的日常开发已经完全离不开这套配置了。公司代码推GitLab个人项目推GitHub国内分发改Gitee三套密钥井水不犯河水配置一次基本能用到换电脑为止。整个过程最核心的认知就一句话SSH不挑平台只看域名路由。把Host、HostName、IdentityFile这三个字段的事搞明白你甚至可以自由扩展到Bitbucket、自建Gitea、内部Gerrit套路一模一样。
返回列表