GitHub 配置 SSH key 这件事听起来简单网上一搜一大把教程无非就是ssh-keygen一路回车把公钥粘到网页上完事。但真到了实际开发里各种问题就会冒出来连接报Permission denied、换电脑后密钥失效、一台机器要同时用 GitHub 和公司 GitLab、甚至同一台电脑上要管理多个 GitHub 账号。我当初第一次配的时候也踩过不少坑所以干脆把整个流程——从原理、实操到排查——完整梳理一遍。这篇东西聚焦于 GitHub 配置 SSH key 的核心技术和完整流程既适合第一次接触 SSH 的新手照着一步步操作也适合已经配过但遇到问题、想弄明白背后原理的同学。1. 为什么要配 SSH key先搞懂认证这件事1.1 SSH 协议与密钥认证的基本原理很多人把 SSH key 当成一种登录凭证这个说法方向对但不够准确。SSH key 本质上是一对非对称加密密钥一把私钥id_ed25519和一把公钥id_ed25519.pub。私钥保存在你自己电脑上永远不要给别人公钥则可以公开你可以把它放到 GitHub、GitLab、服务器上随便放。整个认证过程可以打个比方你把一把锁公钥挂在门口用你自己的钥匙私钥开门。服务器端只存了你的公钥当你用私钥和服务器握手时服务器会验证这把钥匙能不能打开这把锁能打开就放行。因为私钥从不离开你的电脑所以整个过程不需要输入密码也不需要把敏感信息在网络上传送。具体的握手流程比这个类比略复杂客户端发起连接后服务器会生成一个随机挑战用你存的公钥加密客户端收到后用私钥解密并返回结果服务器验证通过就完成认证。期间还会涉及主机密钥验证known_hosts来确认服务器身份防止中间人攻击。这部分不用背下来但理解它有助于你后续排查问题尤其是后面要讲的Host key verification failed报错以及为什么要验证 host key这种疑问。1.2 为什么推荐用 SSH 而不是 HTTPSGitHub 提供了两种主要协议来拉取和推送代码HTTPS 和 SSH。早期大家习惯用 HTTPS因为简单clone 下来直接输账号密码就行。但 2021 年 8 月之后GitHub 完全停止了在 HTTPS 推送时对密码的支持改成了个人访问令牌Personal Access Token——说白了你 push 的时候还是要输一串很长的 token而且 token 有过期时间过期后又得重新生成。SSH 相比之下有明显的优势一次性配置永久免密。公钥加到 GitHub 之后你日常的 clone、push、pull 都不需要再输入任何密码体验非常顺滑。安全性上也更稳HTTPS 传输的是 token每次都要经过网络一旦终端被记录键盘输入或抓包token 就有泄露风险而 SSH 的私钥不出本地认证过程由加密协议保证安全性高出一截。从实际体验来说如果你经常用git clone拉项目、频繁 push 代码配好 SSH 之后那种不用再输 token的爽快感是非常直接的。这也是 GitHub 官方文档把 SSH 作为推荐方式的原因之一。2. 动手生成密钥一条命令背后的参数含义2.1 先选密钥类型Ed25519 还是 RSA现在生成 SSH key第一步不是直接敲命令而是想清楚用什么算法。很多旧教程还在教大家用ssh-keygen -t rsa -b 4096这确实是通用方案兼容性极好那些还在跑老版本 OpenSSH 的老服务器基本都能认。如果你是给公司内部很老旧的 GitLab 或服务器配用 RSA 4096 是稳妥的选择。但如果是面向 GitHub 这类主流平台我更推荐用ed25519。理由很直接密钥更短、生成速度更快、安全性更高而且 GitHub 早就完整支持了。你不用担心ed25519不兼容的问题现在所有主流系统自带的 OpenSSH7.0 以上都内置了支持除非你用的是一个九十年代的老系统。我自己目前所有新密钥都统一用 ed25519只有在连接某些老设备时才会单独生成 RSA 4096 作为备用。这里也顺带提一句-b参数代表密钥位数RSA 至少要用 40961024 已经被证明不安全了2048 算是底线但找谁可靠直接 4096。ed25519 的位数是固定的不用指定-b。2.2 完整生成步骤与指纹验证生成命令很简单ssh-keygen -t ed25519 -C 你的注释信息-C参数是注释Comment通常填邮箱地址方便你在 GitHub 上辨认这把密钥是给哪台电脑、哪个平台用的。不填也行默认会加上用户名主机名。执行后系统会问你保存路径默认是~/.ssh/id_ed25519。如果你本机之前没生成过密钥直接回车用默认路径最省事。后面如果有多密钥需求再考虑自定义文件名。接着它会问你是否设置 passphrase口令。这个点我多说两句passphrase 不等于密码它是私钥文件本身的加密口令。你设置之后每次使用私钥都要输入这个口令。现在 macOS 和 Windows 都支持把私钥保存到系统钥匙串里配合 ssh-agent 后设置为空或填入系统钥匙串都是不错的选择。如果你是安全敏感场景比如笔记本可能丢失建议设置一个否则私钥文件本身暴露出去就危险了。生成完后目录下会多出两个文件id_ed25519和id_ed25519.pub。前者是私钥后者是公钥。你可以用下面命令查看公钥内容cat ~/.ssh/id_ed25519.pub输出的内容以ssh-ed25519开头一长串 base64 编码字符最后是你刚才填的注释整体看起来像这样ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBo........省略 your_emailexample.com如果你想验证刚刚生成的密钥到底对不对可以查看指纹fingerprintssh-keygen -lf ~/.ssh/id_ed25519.pub它输出一串SHA256:...格式的指纹这串指纹在你后续把公钥添加到 GitHub第一次连接确认主机时会看到可以用来比对是否一致。3. 把公钥交给 GitHub添加与验证全流程3.1 复制公钥的三种方式公钥生成好了接下来要把它放到 GitHub 账号里。第一步是把公钥内容复制出来。这里有几种常见方式按你当前使用的系统选即可在终端直接cat ~/.ssh/id_ed25519.pub然后用鼠标选中复制。好处是所见即所得坏处是长字符串容易漏掉几个字符。用pbcopy ~/.ssh/id_ed25519.pubmacOS 专用直接复制到剪贴板省去手动选中的麻烦。Windows 下用clip ~/.ssh/id_ed25519.pub需要 PowerShell 或 CMD 环境效果一样。我个人的习惯是复制完公钥后不要马上粘贴到网页先在文本编辑器里看一眼确认它是以ssh-ed25519或ssh-rsa开头再结尾那串注释也别删没影响。因为公钥里有换行符的话粘贴后 GitHub 会当作格式错误提示 Key is invalid。3.2 在 GitHub 网页端配置与连接测试复制好公钥后登录 GitHub按以下路径操作点击右上角头像选择Settings。在左侧菜单中找到SSH and GPG keys。点击New SSH key新建 SSH 密钥按钮。Title 字段填一个你自己好记的名字比如MacBook Pro 2024或Home Desktop本质就是一个备注帮助你之后知道这把公钥放在哪些设备上。Key 字段粘贴刚才复制的整行公钥内容注意不要有多余空格或换行。点击Add SSH key提示可能需要输入一次 GitHub 密码确认操作。完成后就可以在终端里测试连接了。GitHub 官方提供了一个专门的测试命令ssh -T gitgithub.com第一次连接时SSH 会询问你是否信任这台主机问你Are you sure you want to continue connecting (yes/no)之类的问题。输入yes回车它会将 GitHub 的主机指纹写入~/.ssh/known_hosts以后不会再问。如果密钥配置正常你会收到类似这样的输出Hi your_username! Youve successfully authenticated, but GitHub does not provide shell access.看到这行字就说明认证成功了。这里有个小细节GitHub 不允许通过 SSH 获得 shell 登录权限所以即使认证成功也不会给你一个终端。这个提示是正常现象不是报错。如果你配置了多个密钥这里 SSH 会逐个尝试身份文件直到通过验证。如果测试连接时输出的用户名不是你预期的那个账号说明 SSH 可能用了另一把密钥这时就要用到后面讲的配置文件了。4. 多账号、多平台下的密钥管理实战4.1 什么时候需要多把密钥很多人觉得一把密钥走天下最方便实际场景中完全不是这样。最常见的需求有几种第一种同时使用 GitHub 和公司 GitLab。部分公司会要求统一使用公司发的密钥或者你不想把个人密钥带到公司电脑上这时候就需要给 GitHub 和 GitLab 分别生成独立的密钥。第二种同一台电脑上有多个 GitHub 账号。比如一个私人账号一个接外包或公司用的账号。如果把两把公钥加到同一个电脑的默认位置~/.ssh/id_ed25519后加的那把会覆盖之前的默认密钥导致其中一边失效。第三种不同安全等级的密钥分开管理。比如对内对外用不同密钥或为了实验方便把旧密钥单独建档。虽然这种情况不多但多密钥管理的技能是通用的。我的建议是不要长期依赖一把通用密钥至少学会用~/.ssh/config来区分不同主机。这个文件就是 SSH 客户端的路由表告诉它连接哪个地址时用哪把密钥。4.2 用 ~/.ssh/config 管理多密钥的完整写法~/.ssh/config文件默认不存在需要你自己创建。创建前先确保~/.ssh目录存在mkdir -p ~/.ssh chmod 700 ~/.ssh然后编辑~/.ssh/config常见配置如下# 默认 GitHub 个人账号 Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519_personal # 公司 GitLab Host gitlab.company.com HostName gitlab.company.com User git IdentityFile ~/.ssh/id_ed25519_company # 另一个 GitHub 账号通过别名访问 Host github-work HostName github.com User git IdentityFile ~/.ssh/id_ed25519_work关键点在于IdentityFile指向你为特定场景生成的私钥文件。Host这个名字很关键它会成为你在 clone 时使用的别名。举个例子当你想 clone 一个使用github-work别名的 GitHub 仓库时命令要写成git clone gitgithub-work:your_work_username/repo.git如果你直接用默认的gitgithub.comSSH 会按第一条规则匹配使用个人账号的密钥而不会自动切换到工作账号。还有一点值得注意同一把公钥可以同时添加到 GitHub 和 GitLab。也就是说你不一定需要每加一个平台就生成一把新密钥。我自己的做法是个人电脑的核心密钥就一把用于个人 GitHub 和部分自建服务器公司电脑另生成一把专门用于公司 GitLab 和对应 GitHub 工作账号。互不交叉丢了也不影响另一边。4.3 让 ssh-agent 帮你记住密钥如果你给私钥设置了 passphrase那每次 push 和 pull 都会要求输入口令这就有点烦人了。解决办法是使用ssh-agent它是 OpenSSH 自带的一个后台服务专门帮忙管理私钥把解密后的密钥存在内存里后续连接直接使用不用反复输入 passphrase。启动和添加密钥的操作eval $(ssh-agent -s) ssh-add ~/.ssh/id_ed25519macOS 还支持把 passphrase 存进钥匙串之后 app 或终端调用时就不再询问ssh-add --apple-use-keychain ~/.ssh/id_ed25519Windows 的话如果你用的是 Git Bash 或 PowerShell也可以使用ssh-add但需要先确认ssh-agent服务已开启。在管理员的 PowerShell 里执行Get-Service ssh-agent Set-Service ssh-agent -StartupType Automatic Start-Service ssh-agent设置好后终端里当前用户会话内 SSH 连接都不需要重复输入 passphrase体验和完全无口令差不多。安全上也有个提醒ssh-agent会一直在后台跑如果你在多用户共用的机器上使用记得用完ssh-add -D清空代理里的密钥。5. 常见问题与排查技巧5.1 高频报错速查表配 SSH key 的过程中最打击新人的通常是那几个看起来莫名其妙的报错。我整理一下我遇到过的和群里朋友遇到过的常见问题直接做成速查表格报错信息及场景可能原因解决方法Permission denied (publickey)服务器端没有对应公钥或本地用了错误的私钥检查公钥是否已正确粘贴到 GitHub用ssh -vT gitgithub.com看详细日志确认使用了哪把私钥Host key verification failed本地 known_hosts 里没有 GitHub 的主机指纹或指纹不匹配如果是首次连接输入yes接受即可如果提示不匹配可能是中间人风险或 known_hosts 被篡改删掉对应行后重新连接Bad owner or permissions on ~/.ssh/configOpenSSH 拒绝加载权限过宽的文件设置正确权限chmod 600 ~/.ssh/config目录保持 700gitgithub.com: Permission denied (publickey)且用户名是另一个账号当前本机默认密钥是另一把参照上文~/.ssh/config配多密钥使用正确的 Host 别名连接连接超时Connection timed out网络环境受限22 端口访问 GitHub 不稳定可以尝试使用 SSH over HTTPS 443 端口配置HostName ssh.github.com和Port 443Load key ...: invalid format私钥文件损坏或格式不对重新生成密钥如果是从老服务器拷贝来的确认没有复制多余内容上面列的连接超时问题我多说一句。GitHub 本身在大多数网络环境下 22 端口是正常的但确实存在某些宽带运营商或企业网络把 22 端口拦掉的情况。官方提供了替代方案使用 SSH over HTTPS 端口在~/.ssh/config里做如下配置Host github.com HostName ssh.github.com Port 443 User git IdentityFile ~/.ssh/id_ed25519这种方式不改变你日常的使用习惯git clone gitgithub.com:xxx/repo.git照常可用只是底层的传输端口从 22 变成了 443。这个配置在人人在用的国内网络环境里也经常能生效原理就是 443 端口一般不会被粗暴屏蔽这是官方文档明确支持的方案不是旁门左道。5.2 我踩过的坑与想分享的三个经验配置 SSH key 这么多年有些教训是网上教程很少提到的我在这里一并说出来希望能帮你少走弯路。第一个经验不要嫌麻烦每次都检查公钥和私钥文件权限。OpenSSH 对私钥文件权限有强制要求只要权限过宽它就会直接拒绝加载。我自己有次在 Windows 和 WSL 之间拷贝密钥文件权限变得混乱导致Permission denied排查了很久。正确设置是chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub公钥权限稍宽没问题但私钥一定要收紧。第二个经验用ssh -vT gitgithub.com代替默认测试命令。普通-T只告诉你认证成功还是失败但-v参数会输出详细日志包括当前尝试了哪些私钥、哪个文件加载失败、服务器拒绝了哪条认证请求。排查问题时看到 Offering public key: /home/user/.ssh/id_ed25519 这一行就明白到底用了哪把钥匙。如果日志里没出现预期密钥多半是~/.ssh/config配置没生效或者私钥路径拼错了。第三个经验配置好后记得把~/.ssh/config纳入你自己的环境管理工具比如 dotfiles 仓库或者同步脚本。换电脑时配置文件和密钥本身是可以整体迁移的私钥也可以通过安全通道转移但很多人忘了这个配置导致新电脑上多出了一堆难以管理的密钥路径问题。把配置文件纳入版本管理换机后直接复制回去加上 identity 文件几分钟就恢复开发环境。最后再分享一个小技巧GitHub 官方还提供了查看账号内所有已注册公钥的 API如果你忘了自己往 GitHub 上贴过哪些公钥可以用管理员权限在 GitHub 网页端随时查看和管理。另外不要在同一台机器上把同一把私钥复制给多个完全不相关的服务器。私钥一旦泄露所有配置了对应公钥的主机都会被影响这比 HTTPS token 泄露的波及面还要大。基于密钥的管理确实能带来极大便利但前提是你真的管好你的私钥。希望这篇 GitHub 配置 SSH key 的完整指南能帮你一次把所有流程理清不再被各种奇奇怪怪的报错困扰。