一、先说说我遇到的情况

有天下午我正要推送代码到 Gitee 仓库,结果命令行直接给我甩了一个大大的错误:Permission denied (publickey)。我一看就懵了,昨天还好好的,怎么今天就失效了?相信不少朋友也碰到过类似的情况,明明密钥没动过,配置也没改,可 SSH 就是死活连不上。更让人头疼的是,换了台电脑或者同时用公司电脑和个人电脑时,问题变得更加奇怪:一台能推,另一台推不了,删了重新添加又怕影响其他设备。今天咱们就坐下来,用大白话把这事儿捋清楚,看看问题到底出在哪儿,怎么一步步排查。

二、SSH密钥到底是怎么工作的

2.1 公钥和私钥是一对

SSH 密钥不像我们平时设的密码是个单词,它是一对文件:一个私钥,一个公钥。私钥放在你本地电脑里,比如 ~/.ssh/id_ed25519,它就像一把只有你有的钥匙,绝对不能给别人。公钥放在 Gitee 服务器上,它像一把锁,服务器拿它来验证你手里的私钥是不是配对的。当你执行 git push 时,本地帮你拿着私钥去敲门,服务器用公钥来检验,对上了就放行。

2.2 为什么密钥会失效

很多人说"密钥失效",其实并不准确。大多数情况下,不是密钥文件真的过期了,而是连接过程中某个环节出了问题。比如:

  • 私钥文件权限不对,系统不认。
  • 你用了 ssh-agent,但是 agent 里加载的私钥和 Gitee 上存的公钥不是同一对。
  • 本地 ~/.ssh/config 配置文件里指定了错误的私钥。
  • 多设备之间拷贝了密钥文件,但权限被改了。
  • Gitee 账户里误删或覆盖了公钥。

这些情况都会表现成"密钥无效",让你误以为是密钥过期了。其实大部分都能手动修好。

三、Gitee上的密钥管理

3.1 怎么添加密钥

在 Gitee 上管理密钥很简单。登录网页后,进到个人设置里找到"SSH 公钥"的入口。你只需要把本地电脑生成的那个 .pub 文件里的内容复制粘贴进去,保存就行了。注意,公钥是一整行以 ssh-ed25519ssh-rsa 开头的长字符串,别漏了末尾的邮箱注释。

3.2 多设备下密钥的添加与删除

现在的开发日常,往往白天用台式机,晚上用笔记本,或者办公室一台、家里一台。每个设备都要生成自己的密钥对,然后把各自的公钥添加到 Gitee 账户里。Gitee 允许你同时添加多个公钥,每个公钥都可以设置一个备注,比如"公司电脑"、"家用本"等,方便区分。

删除公钥就要小心了,如果你正在那台设备上使用,删掉之后它就会立刻失去推送权限。多设备场景下,最常见的坑就是重复生成密钥时,把旧的公钥从 Gitee 上删掉,但本地私钥没变,或者反过来。

3.3 密钥权限与过期问题

Gitee 的公钥本身没有强制过期时间,只要你不删,它就一直有效。真正导致"失效"的往往是权限问题。私钥文件的权限必须设置为 600,也就是只有你本人能读写。如果权限太开放,OpenSSH 出于安全考虑会直接拒绝使用。这就像是你的钥匙掉在了马路上,系统觉得不安全,不让你用。

四、多设备兼容性排查

4.1 检查本地SSH配置

排查的第一步,是弄清楚当前用的是哪个私钥。在终端里运行 ls -al ~/.ssh/ 看看有哪些文件。正常情况下会有一对 id_ed25519id_ed25519.pub,也可能有 id_rsa。如果有多个,可能是历史遗留。再看 ~/.ssh/config 这个文件是否存在并写入了正确配置。比如:

# 显示本机所有SSH相关的文件
ls -al ~/.ssh/

如果没有 config 文件,那 SSH 会默认使用 id_rsa 或者 id_ed25519。如果存在,检查 HostIdentityFile 字段是否指向正确的私钥路径。

4.2 检查ssh-agent状态

ssh-agent 是一个缓存私钥的小助手,你只需要把私钥加入一次,它就能在会话里帮你自动提供身份验证。但这里也容易出幺蛾子。比如你明明在 Gitee 上添加了新电脑的公钥,但 agent 里还缓存着旧电脑的私钥,导致连接时拿错了钥匙。

# 查看ssh-agent当前加载了哪些密钥
ssh-add -l

如果列表里没有你的密钥,就手动添加:

# 将默认的ed25519私钥添加到agent缓存
ssh-add ~/.ssh/id_ed25519

4.3 检查Gitee服务端

还要确认 Gitee 账户里的公钥确实和本地的公钥匹配。你可以把本地 .pub 文件的内容全部复制出来,和 Gitee 上显示的比对一下。经常出现的情况是:你从旧电脑复制了公钥内容,但粘贴的时候多了一个空格,或者少了一串字符,服务端就认为这是不认识的钥匙。

五、分享我的排查示例

下面我以一个典型的"公司电脑推不了代码,家庭电脑没问题"的场景来演示。咱们把整个排查过程走一遍,注意所有命令都是在 Bash 里执行的。

5.1 示例一:查看本地密钥

# 先看看用户目录下的.ssh文件夹里有什么
ls -al ~/.ssh/

# 结果里如果看到id_ed25519和id_ed25519.pub,说明用的是Ed25519加密
# 如果只有id_rsa和id_rsa.pub,则是RSA加密

# 查看默认公钥的内容,后面要跟Gitee上对比
cat ~/.ssh/id_ed25519.pub

看到输出结果后,把内容复制到 Gitee 的 SSH 公钥列表里对比,确认这两个公钥是否长得一模一样。

5.2 示例二:生成新密钥并添加

如果发现本地根本没有密钥,或者想换一个新的,那就重新生成。生成密钥的时候建议加上注释,方便知道是哪台设备:

# 生成新的ed25519密钥,-C后面是备注信息,可以写设备名
ssh-keygen -t ed25519 -C "company-pc"

# 按照提示设置保存路径,比如 ~/.ssh/id_ed25519_company
# 然后设置一个密码短语(可以不设置,直接回车跳过)

生成后,再查看公钥内容:

# 查看生成的新公钥
cat ~/.ssh/id_ed25519_company.pub

接着登录 Gitee,添加这个公钥,备注写"公司台式机"。

5.3 示例三:测试连接

添加完成后,测试是否连通:

# 使用SSH连接Gitee,会有一个提示,输入yes继续
ssh -T git@gitee.com

# 如果看到输出"Hi 用户名! You've successfully authenticated, but GITEE.COM does not provide shell access."
# 说明连接成功

如果连接失败,就逐步加参数调试:

# 开启SSH调试模式,了解详细交互过程
ssh -vT git@gitee.com

# 注意查看输出中的debug1行,关注使用的是哪个私钥文件

调试信息里会明确告诉你哪个密钥文件被尝试了,以及服务器是否接受它。

5.4 示例四:处理多个密钥

当电脑有很多密钥时,必须通过 ~/.ssh/config 告诉 SSH 工具什么场景用哪个密钥。先创建配置文件:

# 编辑SSH配置文件(如果不存在会自动创建)
nano ~/.ssh/config

在文件里写入如下内容:

# 针对gitee.com的连接配置,写明使用的私钥路径
Host gitee.com
  HostName gitee.com
  User git
  IdentityFile ~/.ssh/id_ed25519_company

保存后重新测试连接,这次 SSH 就会固定使用你指定的私钥去连接 Gitee,而不是到处乱找。如果你用了其他代码托管平台,比如 GitHub,可以再写一个独立的分段,互不干扰。

六、应用场景分析

SSH 密钥的应用场景主要分三类。

第一类是个人项目推送,你只有一台电脑,那么只需生成一个密钥,配好一次,基本可以长期使用。第二类是多设备开发,公司电脑、家里电脑、甚至平板都要跑代码,需要在 Gitee 上维护多个公钥,同时本地每台设备都配好正确的 config。第三类是团队协作,多人操作同一个仓库,每个成员都有自己独立的密钥,一但有人离职,管理员只需在 Gitee 后台删掉那个人的公钥,就能快速取消他的访问权限,不需要改仓库密码,非常灵活。

SSH 密钥比密码更安全,因为它不存在网络传输,不会像密码那样被拦截。但它也有它的麻烦,就是密钥文件的管理成本变高了。你想想,如果三台设备都要配,每台都要生成、添加、调权限,出问题还得逐一排查,没有点耐心可不行。

七、技术优缺点

优点很明显:

  • 安全性高,用的是非对称加密,私钥永远不出本机。
  • 使用方便,配置好后推送代码不用每次输密码。
  • 粒度细,可以给不同设备、不同用户分配不同公钥,随时单独撤销。

缺点也不容忽视:

  • 私钥一旦丢失或损坏,找回很麻烦。
  • 多设备配置复杂,容易因为权限、路径、配置错误导致连不上。
  • 如果私钥没设密码短语,别人拿到文件就能冒充你的身份访问仓库。

八、注意事项

结合我自己的踩坑经验,给你几点提醒。

第一,定期整理 ~/.ssh 目录,多余的密钥文件删掉,避免 SSH 在尝试时用错。

第二,每次修改 Gitee 密钥后,务必用 ssh -T git@gitee.com 测试一遍,别等到推送时才后悔。

第三,注意私钥文件权限,在 Linux/macOS 上用 chmod 600 ~/.ssh/id_ed25519 来修正。

第四,如果不行,试试清空 ~/.ssh/known_hosts 里关于 gitee.com 的记录,有时候旧的 host key 缓存也会导致连接异常。清空后再次连接会重新提示信任。

第五,换设备时不要直接复制私钥文件,最好在新设备上重新生成,然后把新公钥添加进去,这样既能保证每台设备的私钥独立性,也方便后续按设备管理。

九、总结

SSH 密钥频繁失效的根源往往不是密钥真的"过期",而是本地和服务端之间出现了信息不一致。你只需要按照"看本地密钥列表 -> 看 ssh-agent 缓存 -> 看 Gitee 公钥 -> 看 SSH 配置"这样的顺序逐步排查,大多数问题就能解决。Gitee 的密钥管理界面并不复杂,多设备兼容性出问题也主要集中在权限和配置上。希望这篇文章能帮你少走弯路,几十分钟的排查工作,在未来能节约你无数个焦头烂额的下班时间。