OpenSSH 10 升级后 DSA 公钥被静默拒绝:巡检、host key 与日志来源排查
信源:OpenSSH 10.0 release notes · 发布历史
现象
升级到 OpenSSH 10.0 之后,一部分用户登录直接失败。客户端侧只有一行 Permission denied (publickey),看不到算法协商失败之类的提示;服务端按平时的过滤规则翻日志,也找不到能指向原因的行。
常见根因是 authorized_keys 里还留着 ssh-dss 公钥。10.0 把 DSA 从代码里删掉了,没有配置项可以把它打开。10.0 在该场景下具体输出哪条日志、日志为何看起来"没有原因",需自行验证;已确认的事实是认证相关消息的进程来源变了,见下文 sshd-auth 一节。
DSA 在 10.0 是被删除,不是被关闭
- DSA 上限 1024 位私钥 + SHA1 摘要,估算安全强度约 80 bit 对称强度。
- 弃用是一条长链路:7.0(2015)起运行期默认禁用 → 9.7 转为编译期可选 → 9.8 编译期默认禁用 → 10.0 彻底删除代码。到了 10.0 没有开关可以恢复。
- OpenSSH 10.0 发布于 2025-04-09,协议标识字符串是
SSH-2.0-OpenSSH_10.0。
所以升级后能做的只有两件事:把 DSA 公钥换掉,以及处理遗留的 DSA host key。
升级前先跑这三条
在动手升级之前,先在机器上确认有没有 DSA 残留:
# 用户侧:authorized_keys 里的 DSA 公钥
grep -r 'ssh-dss' /home/*/.ssh/authorized_keys /root/.ssh/authorized_keys
# 用户侧:本地 DSA 私钥
find ~/.ssh -name 'id_dsa' -o -name 'id_dsa*'
# 服务端:DSA host key
find /etc/ssh -name 'ssh_host_dsa_key'
第一条命中就说明升级后这些用户会登不上,要提前通知换密钥(ssh-keygen -t ed25519 或 RSA 都可以,只是别再生成 DSA)。第三条命中说明主机上有一份升级后完全用不上的 host key。
host key:ssh-keygen -A 会跳过 DSA
主机上存在 ssh_host_dsa_key 时,升级后 ssh-keygen -A 会重建缺失的 host key 类型,但会跳过 DSA——它不再生成 DSA host key。所以不要把"-A 跑过了"当成"DSA 的问题已经处理完了":它只是不再补新的,旧文件仍然躺在 /etc/ssh 里,清理要单独做。
版本号字符串的匹配坑
协议标识是 SSH-2.0-OpenSSH_10.0。用 OpenSSH_1* 这类简单模式匹配的扫描器或资产脚本会认不出 10.0,把它当成未知版本或干脆漏掉。升级后资产台账里突然空出一批主机,先查这条规则,不要先怀疑网络。
另外,发行版会把补丁 backport 回旧版本号而不改上游版本字符串。判断某台机器到底有没有打上补丁,只看版本号不够,需要结合发行版的包版本。需自行验证具体发行版的命名规则。
sshd-auth:日志来源和监控口径都变了
10.0 把用户认证代码从 sshd-session 拆到了新的 sshd-auth 二进制,目的是让暴露在前的认证代码拥有独立的地址空间。这对运维有两个直接影响:
- 发行版需要把这个新二进制一起打包,漏包会直接影响登录。
- 日志里部分消息的来源会从
sshd-session变成sshd-auth。
如果监控或告警规则只匹配 sshd 这个进程名,就会漏掉 sshd-session 和 sshd-auth 的日志。上面那个"日志里没有可用原因"的现象,第一步应该核对的就是采集规则覆盖了哪些进程名。
别把 ssh-rsa 和 ssh-dss 搞混
这两件事经常被混为一谈:
ssh-rsa(RSA + SHA1 签名)从 8.8 起默认禁用,但 RSA 密钥本身没变。同一把密钥改用rsa-sha2-256/rsa-sha2-512签名即可,不需要换密钥。- 8.2 起证书签名不再接受
ssh-rsa。 - 真正被删掉的密钥类型只有 DSA。
如果临时需要放行 ssh-rsa,例外范围要写死到单台主机(Host 块或 Match),并给出截止时间。不要写 PubkeyAcceptedAlgorithms +ssh-rsa 挂在 Host * 上——这种写法会在所有连接上生效,并且通常没人回来删。
10.0 其它会影响现有配置的变化
mlkem768x25519-sha256成为默认密钥交换(后量子混合,NIST 标准化,比之前的默认更快)。- sshd 默认关闭有限域 Diffie-Hellman(
diffie-hellman-group*、group-exchange-*),客户端仍会提供这些算法。 - 当
/etc/moduli存在但没有请求范围内的 group 时,sshd 不再回落到内置 group;moduli文件完全不存在时仍然回落。 - 客户端加密套件优先级变为 chacha20-poly1305 → AES-GCM → AES-CTR。
10.3 与 10.6 之后的行为变化
10.0 之后还有几次会影响排查结论的调整:
- 10.1(2025-10-06):客户端在非后量子密钥交换时给出警告(
WarnWeakCrypto);agent socket 从/tmp移到~/.ssh/agent;移除 XMSS。 - 10.3(2026-04-02):空的证书 principals 不再匹配任何用户;不再对无法 rekey 的对端做 bug 兼容;新增 invaliduser 惩罚。
- 10.4(2026-07-06):rekey 期间收到非 KEX 消息会断开连接;Linux 上 seccomp 设置失败从忽略改为致命;引入实验性 ML-DSA 44 + Ed25519 签名。
- 10.5(2026-08-11):portable 构建要求 libcrypto 带椭圆曲线支持(含 NIST P-521)。
- 10.6(2026-10-06):关闭 LZ77 字典压缩以阻断一条跨信道侧信道;
ssh-mldsa44-ed25519以 IANA 名称启用;sshd 也加上WarnWeakCrypto。
其中 10.3 的两条对日常影响最大:空 principals 的证书不再"匹配所有人",以及 invaliduser 惩罚会让大量失败登录的来源更早被挡——排查时如果看到某 IP 从认证失败变成完全没响应,先想到这条。10.6 关闭压缩后,带宽和吞吐的基线会变,之前按压缩后流量做的容量评估要重算。