■ space · 一场重放过的谈判 · fig 1

■ 先说答案

Permission denied (publickey) = 客户端开出的每一把密钥都被拒收 ——谈判的裁决,不是密码打错了。

诊断: ssh -vvv 显示开过哪些价; journalctl -u ssh 显示为什么被拒。

然后就是四个病因之一: 用户不对、密钥不在 authorized_keys 里、权限太宽,或者 OpenSSH 8.8+ 拒收 ssh-rsa。 ssh-copy-id 能防住大多数复发。

4 种病因,一个裁决
8.8第一个拒收 ssh-rsa 的 OpenSSH
02:10那次死掉的开价

01线缆

客户端报价 · 服务器拒收 · 三行日志决定你的问题住在哪一侧

FIG 1 · 钥匙串传送带钥匙 1–6 —— 或者按钮
开价 · 拒收authorized_keys谈判,就在线缆上deploy@stagingport 51422 · publickey客户端 · 你的笔记本服务器 · staging :22authorized_keysdeploy@stagingid_ed25519id_rsa开价1拒收已拒收publickey
在终端里重放一遍
$ ssh -vvv deploy@staging 2>&1 | grep -iE "offering|identity|denied|authentications"
debug1: Offering public key: /home/deploy/.ssh/id_rsa RSA SHA256:9T4xQmV…

02:10:03 — 拒收。部署死在 SSH-RSA 上02:14:41 — 同一个客户端,换 ed25519 通过

开价 id_rsa → 拒收 · 开价 id_ed25519 → 通过 · 台账 1R · 1A

传送带就是开价清单——钥匙串盖的每一个章, ssh -vvv 都会打印成一行

02见证

钥匙串自己记账——服务器早就记了它的第一笔:journalctl 已经把每个裁决都写进日志

staging · sshd 自家的日志
Oct 18 02:10:03 staging sshd[4421]: Failed publickey for deploy from 203.0.113.7 port 51422 ssh2: RSA SHA256:9T4xQmV…
Oct 18 02:14:41 staging sshd[4421]: Accepted publickey for deploy from 203.0.113.7 port 51422 ssh2: ED25519 SHA256:KP7wLn…

两行日志,一条弧线:02:10 RSA 开价被拒——部署之死——然后还是那个客户端,四分钟后拿着 ed25519 通行

为什么被拒——在 Ubuntu 上,sshd 把每一次开价的裁决都写日志
journalctl -u ssh -n 50 --no-pager | grep -iE "publickey|denied|accepted"

验证: journalctl -u ssh -n 50 | grep Accepted → 一行带着你的指纹和用户名

03病因表

日志只写裁决,从不写病因——六种形状产出同一个拒收

病因破绽修法
正确的钥匙在,来的却不对-vvv 开出一把你认不出的身份ssh-add -l 列清单, ssh-add -d 扔掉把过期的
-i mykey 被无视config 里的 IdentityFile 压过开价顺序去修或删掉 ~/.ssh/config
钥匙没装服务器日志每次都写 Failed publickey ——authorized_keys:空的,0 把钥匙ssh-copy-id user@host
用户不对钥匙对 root@host 好使,对 deploy@host钥匙必须放进那个用户的 ~/.ssh/authorized_keys
权限太宽WARNING: UNPROTECTED PRIVATE KEY FILE ——钥匙被直接跳过,根本不会开价chmod 700 ~/.ssh; chmod 600 ~/.ssh/*
传家宝 ssh-rsa 钥匙服务器跑 OpenSSH 8.8+;老 RSA 钥匙永远不被接受换 ed25519 重新生成,或者升级钥匙

每一行都能在传送带上重放——按下它对应的按钮,看谈判挑出那个病因

法则 01三行日志决定立场。开过价 · 还在接受 · 被拒——按顺序读,线缆会告诉你站在哪。
法则 02用 ssh-copy-id,绝不手工粘贴。半截行和松弛的权限,就是复发的出生地。
法则 03BatchMode 是铁证。 ssh -o BatchMode=yes … 'echo ok' ——没有提示符,没有指望,只有 ok。

04权限闸口

表里每个病因都到过服务器——这一种死在线缆的客户端一侧

~/.ssh——目录本身,ls -ld700 → drwx------ · 755 就太宽了
~/.ssh/id_ed25519——私钥本身,ls -l600 → -rw------- · 644 和 664 都太宽
■ 客户端替你婉拒你自己的钥匙 WARNING: UNPROTECTED PRIVATE KEY FILE. 组或所有人可读的钥匙会被悄悄从开价里丢掉——什么都到不了服务器;-vvv 日志里连一行 offering 都没有
修法——两条 chmod,按顺序
chmod 700 ~/.ssh
chmod 600 ~/.ssh/*

验证: ls -ld ~/.ssh → drwx------ · ls -l ~/.ssh/id_ed25519 → -rw-------

05退休的语言

某一个拒收带着日期——8.8,2021-10-01 发布,不再说 ssh-rsa 这门话

「ssh-rsa 签名方案 ... 默认已禁用」——OpenSSH 8.8 发行说明,2021-10-01。

2018 年生成的 RSA 钥匙没坏——只是它的签名格式没人再讲了

长久的答案—ssh-keygen -t ed25519 ——一把新钥匙,用所有服务器都还听得懂的话
同一把钥匙,就地升级—rsa-sha2-256 不必重新生成——签名原地升级
安装这一步—ssh-copy-id 追加钥匙并摆好健康的权限——它存在,就是因为手工粘贴会栽在半截行上
铸钥匙,装钥匙
ssh-keygen -t ed25519
ssh-copy-id deploy@staging
铁证——没有提示符,没有指望
$ ssh -o BatchMode=yes deploy@staging 'echo ok'
ok

验证: ssh -o BatchMode=yes deploy@staging 'echo ok' → ok,无提示符

反锁条款 怕修到一半把自己锁在门外?各云控制台都给你一条 不依赖 sshd 的串行控制台 ——VPS 服务商全都有。 如果密码登录已经关闭,而你的修法会动 authorized_keys,那么在重启任何东西之前,先把那条控制台开着
■ 诚实印记 测试环境:OpenSSH 8.8 → 9.x · Ubuntu · ed25519 + RSA 钥匙 · ssh-agent。首次发布 2026-09-18。 开价-拒收机制、UNPROTECTED PRIVATE KEY 拒收、以及 8.8 的 ssh-rsa 默认值,都是 OpenSSH 有据可查的行为;上面的 -vvv 与 journalctl 行就是这些工具真实打印的形状,从 02:10 死掉又复活的部署里抄录。

线缆到此为止 · 没有任何 fetch · 全程本地