最近总有朋友跑来问我:“我的SSH密钥是不是过期了?怎么突然连不上服务器了?”这个问题我听得太多了,尤其是隔三差五就要登上跳板机操作一遍的人,十次里有八次不是密钥真的“过期”,而是权限、配置、指纹、代理这些地方出了岔子。今天就把这个话题彻底拆开,从密钥本身到底会不会过期,到每一步该怎么排查、怎么配置,再到Git、VS Code、网络设备等各种场景下的坑,一次性讲明白,保证你看完能从“连不上”变成“秒连接”。
1. “密钥过期”到底是什么问题
1.1 SSH密钥本身不会到期,但确实会遇到“失效”
先说结论:你自己用 ssh-keygen 生成的那对公钥和私钥,本身是没有“有效期”这个概念的。密钥文件里没有类似SSL证书那样的起止时间字段,只要文件不损坏、不被删掉、权限没被改乱,理论上它可以一直用下去。
那为什么这么多人觉得“密钥过期了”?因为大家把“连不上”的结果直接归因成了“密钥过期”,实际上背后是几种完全不同的故障。最常见的几种:
- 服务器上存放的公钥被清掉了,或者你换了一台新机器,公钥根本没部署过去。
- 本地私钥权限变成了其他用户可读,OpenSSH出于安全考虑直接拒绝使用。
known_hosts里记录的服务器指纹和实际指纹对不上,被当成中间人攻击给拦下了。- 系统重启过,SSH agent没有被重新加载,于是每次都要输一遍密钥密码。
- 服务器端启了更严格的认证策略,比如修改了
sshd_config,限制登录用户,导致即使你有有效密钥也无法认证。
所以如果你的第一反应是“重新生成一套密钥”,我劝你冷静三分钟。重新生成等于把问题归零,但问题的根源并没有找到。正确的姿势是先做一轮系统排查,把真正的故障点揪出来,再看该不该换钥。
1.2 最常见的问题场景:其实是权限和配置在捣乱
有一次我帮一个同事排查,他信誓旦旦地说密钥过期了,结果我远程一看,服务器上 ~/.ssh/authorized_keys 里的公钥内容就是他本机 id_rsa.pub 的内容,一分不差。那问题出在哪?出在他把私钥放在了一个NTFS格式的U盘里,拷到Linux机器后,权限变成了 -rw-r--r--,OpenSSH直接报 Permissions too open,拒绝认证。
还有一次更离谱,明明能连本机,但连生产服务器就报 Permission denied (publickey)。查了半天发现,客户端的 ~/.ssh/config 里写了一个 IdentityFile 路径,指向了一个不存在的文件,而默认的 id_rsa 没有被自动尝试。OpenSSH其实是有默认行为的:如果没有显式指定密钥文件,它会依次尝试 ~/.ssh/id_rsa、id_ecdsa、id_ed25519 等。但一旦你在config里给某个Host单独指定了 IdentityFile,那个默认密钥就不会被用于这个Host了。所以很多人误以为“密钥过期”,其实只是config文件里的路径写错了。
这类问题非常多,我把它们归类成一句运维心得:**SSH连不上,90%以上是密钥文件、权限、指纹、配置这四个维度的偏差,真正需要重新生成密钥的比例极低。**上午卡在这四个维度做了完整检查的人,下午基本都能恢复正常工作。
1.3 真正会“过期”的几种情况
虽然普通SSH密钥默认不会到期,但在企业级环境或特定场景下,是存在“到期”机制的。
第一种是证书认证。OpenSSH支持用CA签名的方式发放用户证书,签名的时候可以设置有效期。比如运维平台签发一个有效期为8小时的证书,超时之后证书就失效了,这时候你会频繁遇到“密钥过期”的问题。这其实是一种安全设计,保证临时授权不会被无限期滥用。
第二种是服务器端的强制策略。某些安全加固方案会定期轮换所有服务器的登录凭据,包括更新 authorized_keys。如果轮换流程跑得不完整,或者客户端没有及时把新公钥部署到服务器上,就会突然出现“前一天还能连,今天连不上”的情况。
第三种是代理转发带来的连带失效。你把本地agent转发到跳板机,再从跳板机登录目标机时,如果本地agent恰好超时、重启或者环境变量没继承过来,目标机就会一直提示密钥无法匹配。这看起来也像“密钥过期”,实际上是agent生命周期导致的。
第四种是密钥文件本身保管不当。比如你加密了私钥,设置过一个口令,时间久了忘了;或者云厂商的密钥对一旦丢失,私钥没法找回,只能重新生成并重新注入。这类问题虽然不是“到期”,但造成的体验和“到期”完全一样。
所以,别看到“过期”两个字就想重新生成密钥,先想清楚到底属于哪种情况。接下来进入正题,手把手带你把问题查个底朝天。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 六步排查:找回能用的SSH密钥
2.1 先确认密钥文件本身是否存在且能被找到
排查的第一步不是改配置,而是先回答三个短语问题:私钥在哪,公钥在哪,服务器上授权的公钥是什么。这三个问题一个都不能猜,必须用命令去验证。
先看本地有没有私钥:
bash复制ls -la ~/.ssh/
正常情况下你会看到 id_rsa、id_ed25519、id_ecdsa 或者 id_rsa.pub 这类文件。如果你连 ~/.ssh 目录都没有,说明你压根没有生成过密钥,那后续所有“密钥过期”的说法都不成立,直接跳到第3章去生成一套。
如果密钥文件存在,继续查看公钥内容:
bash复制cat ~/.ssh/id_rsa.pub
公钥通常长这样:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user@hostname,前面是算法标识,中间是Base64编码的主体,最后是注释。如果你看到公钥内容非常长,或者开头不是 ssh-rsa、ecdsa-sha2-nistp256、ssh-ed25519 这类正常的标识,那你这个文件可能被截断过或损坏了。
接着登录服务器(用密码方式或者控制台VNC),查看服务器上当前用户是否有对应的授权公钥:
bash复制cat ~/.ssh/authorized_keys
如果服务器上这个文件不存在,或者里面没有你本地那份公钥,那问题答案就出来了:不是密钥过期,是根根本没部署过。这种缺失通常发生在你重置过服务器、换过系统盘、或者运维平台统一管理过密钥对之后。
2.2 权限检查:700、600、644的区别
很多人老是忽略权限,但它却是SSH登录失败里出现频率极高的一类原因。OpenSSH对待权限相当严格,稍微宽松一点就直接拒绝。
正确的权限要求如下:
~/.ssh目录权限必须是700(只有自己可读可写可执行)。~/.ssh/authorized_keys权限必须是 `60
