DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

SSH 报 .pub 文件权限过宽

SSH 报 .pub 文件 Permissions 0644 are too open 时,先确认公钥是否被当作本地私钥读取。核对 IdentityFile、真实私钥权限和 agent 身份,避免只改公钥权限后继续遇到认证失败。

SSH 登录失败,日志里出现了私钥权限警告,但报错路径却以 .pub 结尾:

WARNING: UNPROTECTED PRIVATE KEY FILE!
Permissions 0644 for '/home/alice/.ssh/server_key.pub' are too open.
This private key will be ignored.
Permission denied (publickey,password).

如果同目录下的私钥已经是 600,继续收紧 .pub 文件权限往往没有解决关键问题。先确认 SSH 是否把公钥文件当作本地私钥读取。

下面针对 Linux、macOS 上的 OpenSSH 客户端,以及保存在本地普通文件系统中的密钥。Windows 原生 OpenSSH 的 ACL、WSL 挂载盘权限和硬件密钥另有条件,不应直接套用文件权限命令。示例别名 app-server、账号 deploy、地址 server.example.com 和文件名 server_key 都需要替换。

报错里的文件名比权限数字更关键

常见的一对文件是:

~/.ssh/server_key       私钥,留在客户端
~/.ssh/server_key.pub   公钥,可配置到服务器账号

普通文件密钥登录需要客户端用私钥完成签名。把公钥交给服务器是正常的,但如果本来打算从磁盘读取私钥,客户端的配置却写成:

IdentityFile ~/.ssh/server_key.pub

SSH 就可能在需要私钥时读取这个公钥文件,并先触发私钥权限检查。把它改成 600 只能改变文件权限,不能把公钥变成私钥,之后还可能出现格式错误。

.pub 只是常用命名习惯,文件名本身不能证明里面的内容。也不要通过重命名、删除扩展名,把一份公钥伪装成私钥。应找到原来生成的配套私钥,或者确认对应私钥确实由 agent 管理。

查看实际生效的身份文件

先展开平时使用的主机别名:

ssh -G app-server

关注 hostname、user、port、identityfile 和 identityagent。这个命令输出配置后退出,不建立远程 SSH 会话。若平时还传了 -F、-i 或其他连接选项,检查时也要带上,否则得到的并非同一套配置。

不要只看刚编辑的那个 Host 段。多个 IdentityFile 会累加,通配 Host、包含文件或命令行里可能仍有另一个 .pub 路径。找到实际提供错误路径的位置,只改对应条目,不要清空全部 SSH 配置。

若展开结果不够清楚,可在已有授权的目标上使用调试连接:

ssh -v app-server

对照日志中读取的配置文件、提供的公钥和权限警告中的完整路径。Offering public key 只是提供候选公钥;即使出现 Server accepts key,也不能单凭这一行判断签名和最终认证已经完成。继续查看后续日志,确认公钥认证最终成功。

调试日志可能暴露用户名、路径和服务器地址,分享前应脱敏。不要把私钥内容贴出来,也不要为了排查而关闭主机指纹验证。

本地有私钥时,修改指向而不是修改公钥内容

确认 ~/.ssh/server_key 是自己有权使用的现有私钥后,先查看两个文件的所有者和权限:

ls -l ~/.ssh/server_key ~/.ssh/server_key.pub

私钥应当由当前登录用户妥善保管,不能让其他用户访问。若所有者正确、文件系统支持普通 Unix 权限,可仅对这一个私钥收紧权限:

chmod 600 ~/.ssh/server_key

600 允许所有者读写;只读的 400 也可以用于读取私钥。公钥本身不需要按私钥保密,正常的 .pub 文件可以让其他人读取。不要递归修改整个 .ssh 或 /etc/ssh,也不要用 sudo ssh 绕过当前用户的配置和权限问题。

备份现有客户端配置后,将该主机的身份文件改为实际私钥。例如:

Host app-server
    HostName server.example.com
    User deploy
    Port 22
    IdentityFile ~/.ssh/server_key
    IdentitiesOnly yes

这是一个主机配置片段,不是整份配置文件的替代品。已有跳板机、非默认端口和其他网络设置应当保留。IdentitiesOnly yes 限制额外身份的尝试,但不会清除其他已经配置的 IdentityFile;修改后仍要再次检查展开结果。

如果需要确认这份文件能作为私钥读取,可在本机使用:

ssh-keygen -y -f ~/.ssh/server_key

它读取私钥并输出对应公钥,不会重新生成或覆盖密钥。加密私钥可能要求输入私钥口令。将输出的密钥类型和公钥主体,与现有 .pub 文件或服务器上已经授权的公钥比较;末尾注释不同不代表密钥不同。输出的是公钥,也没有必要随意传播其中的身份信息。

如果只有 .pub,没有私钥,也没有可用的 agent,就不能靠调整权限完成签名。应从自己有权访问的安全备份恢复私钥,或通过已有管理通道登记一对新密钥的公钥。不要删除旧授权,直到新身份经过验证;如果私钥曾泄露,恢复登录后还应撤销对应旧公钥,单纯改权限不能收回已经泄露的副本。

有意用公钥选择 agent 身份时,不必改成私钥路径

当前 OpenSSH 支持另一种用法:本地没有私钥文件,IdentityFile 指向公钥,由 agent 中对应的私钥完成签名。因此,不能只看到 .pub 就断言配置一定错误。

这种配置依赖当前 SSH 进程能够访问正确的 agent,并且该 agent 确实持有对应身份。先在运行 SSH 的同一个终端查看:

ssh-add -l
ssh-keygen -l -f ~/.ssh/server_key.pub

比较指纹时,要使用相同的指纹算法。没有 agent、agent 中没有身份,或指纹不同,都不能证明目标公钥对应的私钥可用。还需检查 IdentityAgent:它可以覆盖 SSH_AUTH_SOCK,所以这个终端中的 ssh-add 与实际 SSH 连接未必访问同一个 agent。

如果就是要使用这条路线,应恢复预期的 agent 连接和身份加载方式。密钥有确认、解锁或硬件触摸要求时,也需完成相应操作;列表中出现指纹不等于本次签名一定成功。不要为了消除报错,把原本由专门 agent 保管的私钥复制出来。

明确使用磁盘私钥还是 agent 中的身份,再按对应方式验证。旧版客户端的功能和报错措辞可能不同,不应把一份旧日志中的行为当成所有版本的规则。

修复后确认认证完成,再处理服务器授权

使用原来的主机别名和连接路线再连接一次。确认 SSH 已停止把错误文件当私钥读取,使用了预期身份,通过公钥认证并登录到正确账号。不要把消失了一条权限警告当成全部修复完成。

若权限警告已消失,仍然是 Permission denied,继续检查服务器上对应账号是否授权了这把公钥,以及客户端实际使用的身份。此时问题可能已转到服务器授权或其他认证条件,反复调整 .pub 权限没有帮助。

需要回退时,恢复本次修改的客户端配置条目,保留其他主机设置,再检查展开结果。对真实私钥已经收紧的权限,无需为了回退配置而重新放宽;本次排查也不要求删除公钥文件、重新生成现有密钥或重启远程 SSH 服务。