ARTICLE DETAIL

资讯详情

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

SSH拉取Git代码全攻略:密钥配置与常见问题排查

SSH拉取Git代码全攻略:密钥配置与常见问题排查 SSH方式拉取Git代码从密钥配置到日常避坑全记录前阵子接手一台新机器装完Git顺手就想从仓库里拉代码结果又双叒在认证这一步卡了半天。其实不管是GitHub、Gitee还是GitLab用SSH方式下载代码这件事本质上就是“生成密钥对→把公钥放到托管平台→本地用私钥认证”这三步。看起来简单但里面涉及的细节并不少——密钥算法选哪种、多平台密钥怎么管理、Permission denied到底是谁的问题搞不清楚的话够你折腾一下午。这篇文章就把我这些年用SSH方式拉取代码的经验从头梳理一遍。不光告诉你命令怎么敲还把每一步背后的原理和坑都讲清楚适合刚接触Git的初学者也适合一直被SSH认证折腾的老手查漏补缺。1. 为什么要用SSH而不是HTTPS来下载代码1.1 两种协议的认证方式差异用HTTPS方式拉代码最常见的就是这个画面输完用户名再输密码或者Token然后才能把仓库内容拖下来。如果需要频繁拉取每次都要重复输入哪怕Git有凭据管理器在服务器环境或者多账号环境下也经常失灵。更麻烦的是HTTPS的密码或Token一旦泄露别人就能直接访问你的仓库。SSH方式完全不同。它走的是“公钥加密、私钥解密”的非对称认证机制本地生成一对密钥——一个私钥自己保留一个公钥放到Git托管平台。连接时服务器用公钥验证持有私钥的人是你本人验证通过后直接放行全程不需要输密码也没有Token泄露的风险。这里有一个细节很多新手会忽略SSH认证的是“主机”不是“账号”。也就是说只要本机的私钥没被拷走任何情况下都不会有人能伪装成你拉取仓库代码。这一点在团队协作时特别有帮助——换电脑、换系统、重装环境只要把私钥带过去Git认证信息基本不用重新配置。1.2 实际使用场景中的体验对比我自己的使用习惯是本地开发机和远程服务器一律用SSH仅在企业内部某些受控环境里才用HTTPS。原因很直接服务器上拉代码通常希望免交互脚本里没法每次输入密码SSH天然满足管理多个托管平台账号时GitHub、GitLab、Gitee同时用SSH密钥可以按平台区分配置互不干扰仓库迁移、分支操作密集时SSH连接稳定性和速度通常更好SSL握手开销也小从安全角度看HTTPS传输过程中数据是加密的但认证凭据本身暴露了风险SSH认证凭据是私钥文件只要设好文件权限几乎不存在被网络截获的可能。两相对比SSH在代码拉取这个场景下是更可靠的选择。2. SSH密钥生成与配置的完整流程用SSH方式下载代码第一步绝不是打开终端敲git clone而是先把认证基础打好。整个过程可以拆成三步生成密钥对 → 把公钥配置到托管平台 → 测试连通性。下面一步一步来。2.1 生成密钥对时该如何选择算法和参数生成密钥的命令本身很简单ssh-keygen -t ed25519 -C your_emailexample.com -f ~/.ssh/id_ed25519注意这里我推荐的是ed25519算法而不是很多教程里默认写的rsa。原因在于RSA 4096位安全性足够但密钥文件大认证时握手速度稍慢Ed25519基于Curve25519椭圆曲线安全性更高密钥短、生成快、验证快GitHub、Gitee、GitLab等主流平台都支持如果因为某些旧系统兼容性原因必须用RSA建议至少用4096位ssh-keygen -t rsa -b 4096 -C your_emailexample.com -f ~/.ssh/id_rsa执行过程中会提示设置passphrase私钥口令。我的建议是本地个人电脑可以设置一个增加私钥泄露后的安全性服务器或CI环境不要设置否则脚本拉代码时会卡在口令输入上。这个根据场景灵活选择就好。2.2 Windows与Linux/macOS下的密钥存放位置密钥生成后存放在~/.ssh/目录下。不同操作系统路径略有不同系统SSH目录私钥文件公钥文件WindowsC:\Users\用户名.ssh\id_ed25519id_ed25519.pubLinux/macOS/home/用户名/.ssh/ 或 /Users/用户名/.ssh/id_ed25519id_ed25519.pub关键一步公钥文件内容要完整复制到托管平台。查看公钥内容cat ~/.ssh/id_ed25519.pub复制输出的一整行字符串以ssh-ed25519开头包含邮箱后缀。然后登录GitHubSettings → SSH and GPG keys → New SSH key、Gitee设置 → SSH公钥或GitLabPreferences → SSH Keys粘贴保存。这里提醒一个Windows用户容易踩的坑如果你用记事本打开.pub文件并复制可能会因为记事本自动换行把密钥截断导致配置后无法认证。建议用cat命令在终端里查看复制或者用VS Code等编辑器打开复制。2.3 多平台多账号的密钥管理技巧很多人同时注册了GitHub和Gitee甚至公司内部还有一套GitLab。如果所有平台都用同一个公钥是能工作但管理上不够清晰——万一某把私钥泄露所有平台都受影响。更合理的方式是按平台生成独立密钥ssh-keygen -t ed25519 -C github -f ~/.ssh/id_ed25519_github ssh-keygen -t ed25519 -C gitee -f ~/.ssh/id_ed25519_gitee ssh-keygen -t ed25519 -C gitlab -f ~/.ssh/id_ed25519_gitlab然后在~/.ssh/下创建config文件把不同host映射到私钥# GitHub Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519_github # Gitee Host gitee.com HostName gitee.com User git IdentityFile ~/.ssh/id_ed25519_gitee # GitLab Host gitlab.com HostName gitlab.com User git IdentityFile ~/.ssh/id_ed25519_gitlab这个配置文件的作用是让SSH客户端自动判断“我访问的是github.com就用这把私钥访问的是gitee.com就用那把私钥”。没有这个配置SSH默认只找id_ed25519或id_rsa一旦私钥文件名不是默认的就会报Permission denied (publickey)。3. SSH方式拉取代码的实操全过程密钥配置好之后真正下载代码的流程其实就顺畅多了。这里我把日常最常用的几个操作场景完整过一遍。3.1 从GitHub/Gitee/GitLab克隆仓库的标准步骤首先确保本机已安装Git。Windows用户建议直接从官网下载安装包一路默认安装即可安装完成后打开Git BashLinux用户直接使用系统自带终端。以GitHub为例进入目标仓库页面点击绿色的“Code”按钮选择“SSH”标签页复制形如gitgithub.com:用户名/仓库名.git的地址。然后执行git clone gitgithub.com:用户名/仓库名.git首次连接时终端会提示确认主机指纹The authenticity of host github.com (IP) cant be established. ED25519 key fingerprint is SHA256:DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU. Are you sure you want to continue connecting (yes/no/[fingerprint])?这里输入yes回车即可它会将主机指纹写入~/.ssh/known_hosts文件后续连接不再询问。如果你连这个都介意可以先去官网查一下各平台的指纹信息比对但日常使用中直接确认问题不大。克隆完成后进入仓库目录可以用git remote -v验证远程地址确实用的是SSH格式而不是HTTPS格式。如果之前误用了HTTPS也可以用git remote set-url origin gitgithub.com:用户名/仓库名.git一键切换。3.2 针对已有本地仓库切换为SSH远程地址实际操作中更多的人是从HTTPS仓库转过来的比如最初图省事直接用HTTPS克隆了仓库后来受不了反复输入认证信息决定切到SSH。步骤很简单在仓库根目录下执行把远程地址替换掉就行。git remote set-url origin gitgitee.com:用户名/仓库名.git改完之后再执行git remote -v确认输出里显示的是以git开头的地址然后再执行git pull就是走SSH通道了。这个操作不会影响你本地已经存在的提交记录和分支它只是改了“快递地址”不会动货。可以放心操作。3.3 服务器上免密拉取代码的配置方法还有一种高频场景是写了个部署脚本想在服务器上自动从代码仓库拉取最新代码比如每次发版前执行git pull。这时候不可能让人守在机器前输密码配置SSH就是最佳解。流程和本地一样在服务器上生成密钥把公钥配置到代码托管平台。这里注意服务器上的.ssh目录权限要正确否则SSH客户端会拒绝使用密钥chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519如果权限太开放比如私钥文件被其他用户可读SSH会直接报Permissions 0664 for id_ed25519 are too open然后放弃这个私钥。这是我帮别人排查服务器拉代码失败时遇到最多的原因之一。3.4 密钥变更后的处理方式说白了配置好的SSH密钥就像一把钥匙这把钥匙丢了或者泄露了你需要换一把同时让门锁托管平台认识新钥匙。在托管平台删除旧公钥、添加新公钥之后本地不需要做任何特殊操作直接重新拉取代码即可。但如果是在旧电脑上生成的密钥没拷贝过来新电脑需要重新生成一对然后把新公钥配置到平台上。配置完成后测试ssh -T gitgithub.com如果配置成功GitHub会回复Hi 用户名! Youve successfully authenticated, but GitHub does not provide shell access.。Gitee的回复是Hi 用户名! Youve successfully authenticated, but GITEE.COM does not provide shell access.。看到这句话就说明认证链路完全通了。4. 常见问题与排查技巧实录SSH拉取代码这套流程说简单是真简单说烦也是真烦。我在不同操作系统上、不同网络环境下踩过不少坑这里整理一份高频问题清单直接给结论和解决办法。4.1 Permission denied (publickey) 的排查路径这是出现频率最高的一条错误。终端提示gitgithub.com: Permission denied (publickey).原因集中在四个方向公钥没配置到平台或者配置错了对应的账号本地用的是非默认私钥文件名而SSH客户端没有通过config文件指定私钥文件权限过宽或者是Windows下经过某种工具转换后格式异常连接的不是目标平台——比如在GitHub上配了公钥但仓库地址写成Gitee的排查时按顺序执行# 查看当前用户下有哪些密钥 ls -la ~/.ssh/ # 测试连通性-v参数可以输出详细日志 ssh -vT gitgithub.com-v参数输出的日志信息量很大重点看最后阶段有没有出现Offering public key: ...以及服务器返回的Authentications that can continue: publickey。如果看到本地根本没提供公钥说明SSH没找到对应的私钥如果提供了但被拒绝说明公钥和账号不一致或者这个公钥在平台上被删除了。4.2 ssh: connect to host ... port 22: Connection timed out这个问题排查起来比密钥错误更直接因为跟密钥没关系完全是网络层面的问题。碰到连接超时先确认目标平台能不能通ping github.com能ping通则说明主机可达。接着考虑是不是22端口被干扰可以尝试改用443端口连接ssh -T -p 443 gitssh.github.comGitHub官方提供了ssh.github.com:443这个备用入口专门应对22端口被封闭的网络环境。测试成功后在~/.ssh/config里加一段Host github.com HostName ssh.github.com Port 443 User git然后继续用原来的克隆地址操作。日常网络下这个方案实测稳定适合办公网或某些受限网络环境。4.3 首次连接提示主机指纹确认该不该信任这个问题很多人会纠结尤其是安全敏感性强的同学。其实机制是这样的SSH协议为了防止中间人攻击会记录主机公钥指纹到known_hosts。首次连接时没有记录所以要求你确认。保险的做法不是无脑yes而是去官方渠道核对指纹ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub这条命令在服务器上查看本机指纹本地核对时对照GitHub官方文档公布的指纹列表。实操下来大厂的指纹基本不会变核对一次后known_hosts里就有了记录以后每次连接都会自动比对不一致会直接拒绝连接。4.4 VSCode远程开发中SSH认证不生效现在很多人习惯用VSCode的Remote-SSH插件连接服务器开发然后直接在服务器上操作代码仓库。这里有个容易犯迷糊的点本地生成的密钥和服务器上要用到的密钥是两回事。场景是这样的你想在VSCode里打开远程服务器上的一个Git仓库执行拉取操作。此时SSH认证发生在服务器与代码托管平台之间所以需要把服务器上生成的公钥配置到托管平台跟本地电脑的公钥无关。如果服务器拉取时报Permission denied就在服务器上重新执行一遍生成密钥、配置公钥、测试连通性的流程。VSCode只负责帮你连上服务器不负责服务器和远端仓库之间的认证。4.5 Windows下多账号用户名冲突的处理我在Windows Git Bash里遇到过一个很隐蔽的问题全局配置了GitHub的用户名和邮箱又在同一台机器上使用Gitee导致提交记录里的作者信息串了。解决办法是为不同仓库单独配置本地用户信息cd ~/work/gitee-project git config user.name gitee用户名 git config user.email gitee邮箱example.com注意这个和SSH认证是两套体系——SSH负责“这个人是被允许访问仓库的”Git用户配置负责“提交记录里显示这个人的名字”。两者要区分开排查问题时就清晰了。5. 日常使用中顺手又安全的几个小技巧5.1 用ssh-agent免输入私钥口令如果你给私钥设置了passphrase每次连接时都需要输入一遍。嫌麻烦可以用ssh-agent把私钥加进来让它替你记住口令eval $(ssh-agent -s) ssh-add ~/.ssh/id_ed25519输入一次passphrase后当前终端会话内再连接就不需要重复输入了。macOS还可以用ssh-add --apple-use-keychain把口令存入钥匙串重启后也免输入。Windows下的Git Bash也支持这套操作配合Windows凭据管理器可以做到重启后仍然有效。5.2 用include指令统一管理多套SSH配置如果你的~/.ssh/config文件配置很多会变得很乱。我个人习惯是按平台拆分成多个文件用Include指令引入Include ~/.ssh/config_github Include ~/.ssh/config_gitee Include ~/.ssh/config_gitlab每个文件里只写对应平台的Host配置清晰好维护。特别是团队内多人共用一个账号或角色账号时这种分文件方式能避免改配置时误改到别的平台。5.3 定期检查已知主机记录随着时间推移~/.ssh/known_hosts里会积累很多旧的主机记录。如果服务器重装过系统主机密钥变了SSH会拒绝连接并提示指纹冲突。这时候删除对应的旧行即可ssh-keygen -R github.com然后重新连接走一遍首次确认流程。知道这个命令能省很多排查时间因为报错信息往往不会直接告诉你是主机密钥冲突。5.4 配合Git凭据管理器HTTPS和SSH并存不冲突不是所有场景都能用SSH。比如某些内部工具只支持HTTPS或者你在公共电脑上不方便配置私钥。这时候可以两个方式并存SSH用于日常开发和自动部署HTTPS配合Git凭据管理器用于临时环境Git凭据管理器Git Credential Manager支持在Windows和macOS上安全存储HTTPS凭据拉取时自动带上Token不用每次输入。两种方式互不干扰每个仓库独立配置自己的远程地址就行。6. 最后的实操心得用SSH方式下载代码这件事一开始看起来有点门槛但说白了就是“密钥一对、配置一下、测试一次”的流程。我见过不少人在这一步卡住就放弃转回头用HTTPS然后每天被认证问题折磨。其实只要完整按流程走一遍SSH方案能省下大量重复劳动。我个人的体会是配置SSH时最容易出问题的环节就是“公钥内容复制不完整”和“多个平台共用一把私钥导致权限混乱”。前者可以用cat命令在终端里查看复制解决后者用config文件按平台区分就能根治。还有一点想特别提醒不要把所有鸡蛋放在一个篮子里。即使配置好了SSH也建议设置私钥口令、定期更换密钥并且不要让私钥文件在电脑之间随意拷贝。安全这件事多一道锁总比少一道锁强。如果在配置过程中遇到上面列到的问题对照排查路径一步步来解决问题的过程本身也是理解SSH原理的好机会。毕竟真正理解了这套认证机制以后无论在哪个平台上这套思路都能直接复用。
返回列表