VPS的SSH公钥登录失败,常见提示是 Permission denied (publickey)。问题可能出在客户端选错私钥,也可能是服务端没有读取正确用户的 authorized_keys,或因目录权限、SELinux上下文、sshd配置和账号状态被拒绝。排查前必须保留一个已登录的管理会话或云厂商控制台入口,避免修改SSH配置后失去访问。
先从客户端确认实际使用的密钥
ssh -vvv -i /path/to/private_key user@server.example
ssh-add -l
ssh-keygen -lf /path/to/private_key.pub
调试输出只在受控终端查看,不要把私钥内容或完整环境变量贴到工单。确认用户名、主机、端口和私钥路径一致;如果使用SSH代理或跳板机,还要确认最终连接的目标主机没有被别名覆盖。
核对服务端用户和authorized_keys路径
在现有控制台或备用会话中,确认登录用户的家目录和SSH目录:
getent passwd <user>
namei -l /home/<user>/.ssh/authorized_keys
stat -c '%U %G %a %n' /home/<user> /home/<user>/.ssh /home/<user>/.ssh/authorized_keys
文件必须放在sshd实际读取的路径。若配置使用了 AuthorizedKeysFile 自定义位置,不能只检查默认的 ~/.ssh/authorized_keys。同时确认公钥是一整行、没有被换行或复制时截断。
权限和所有权要与策略一致
常见安全基线是家目录不能被其他用户写入,.ssh目录通常为700,authorized_keys通常为600,所有者为目标用户。不同发行版的StrictModes和目录策略可能略有差异,应以本机sshd配置和发行版文档为准。不要为了“先登录再说”把目录改成777或关闭StrictModes。
检查sshd配置与生效值
sshd -t
sshd -T | egrep 'pubkeyauthentication|authorizedkeysfile|strictmodes|allowusers|denyusers'
systemctl status sshd --no-pager
部分系统服务名是 ssh 而不是 sshd。先用 sshd -t 做语法检查,再查看生效配置,确认公钥认证未被关闭,也没有AllowUsers、DenyUsers、Match块或端口限制影响目标账号。修改后按发行版流程重载服务,并保留现有会话做回滚。
用日志判断拒绝原因
journalctl -u sshd -b --no-pager | tail -n 100
# Debian/Ubuntu 也可检查
tail -n 100 /var/log/auth.log
日志中可能出现“bad ownership or modes”“Failed publickey”“User not allowed”等不同提示。若启用了SELinux,再检查上下文:
getenforce
ls -Zd /home/<user> /home/<user>/.ssh /home/<user>/.ssh/authorized_keys
只有确认上下文异常时,才按发行版工具恢复正确标签;不要在不了解策略的情况下关闭SELinux。
修复后的验证与回滚
- 保持旧SSH会话在线,先修正一个变量。
- 从新的终端用明确的
-i和目标用户名测试。 - 确认公钥登录成功后,再验证密码策略、跳板机和自动化任务。
- 记录变更前后权限、sshd生效配置和日志摘要,必要时准备云控制台回滚。
SSH公钥排查的核心不是反复生成密钥,而是证明“客户端拿了哪把私钥、服务端读取哪份公钥、系统为什么拒绝”。分层记录后,通常能在不扩大权限的情况下恢复登录。






