TOC

Putty: Server refused our key

Ubuntu 升级到 22.04 之后,Putty 连接上去报:

Using username "catroll".
Server refused our key
catroll@172.16.0.49's password:

putty 的事件日志中也没有提供更多信息。

找原因 Find Out

开启 sshd 调试日志:

SyslogFacility AUTH
LogLevel DEBUG

/var/log/auth.log 中跟踪到以下信息:

debug1: userauth-request for user catroll service ssh-connection method publickey [preauth]
debug1: attempt 1 failures 0 [preauth]
userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms [preauth]

原来是 Ubuntu 22.04 中带的 OpenSSH 服务禁用了 ssh-rsa。

具体原因 Reason

sshd -v
unknown option -- v
OpenSSH_8.9p1 Ubuntu-3, OpenSSL 3.0.2 15 Mar 2022
usage: sshd [-46DdeiqTt] [-C connection_spec] [-c host_cert_file]
            [-E log_file] [-f config_file] [-g login_grace_time]
            [-h host_key_file] [-o option] [-p port] [-u len]

这个变化是从 OpenSSH 8.2 开始的。
openssh 8.2 remove ssh-rsa support for security reasons, suggest to use ssh-ed25519 instead.

man 5 sshd_config | grep -C10 PubkeyAcceptedAlgorithms 可以获得更多信息。

支持的方法列表:

ssh-ed25519-cert-v01@openssh.com,
ecdsa-sha2-nistp256-cert-v01@openssh.com,
ecdsa-sha2-nistp384-cert-v01@openssh.com,
ecdsa-sha2-nistp521-cert-v01@openssh.com,
sk-ssh-ed25519-cert-v01@openssh.com,
sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
rsa-sha2-512-cert-v01@openssh.com,
rsa-sha2-256-cert-v01@openssh.com,
ssh-ed25519,
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
sk-ssh-ed25519@openssh.com,
sk-ecdsa-sha2-nistp256@openssh.com,
rsa-sha2-512,rsa-sha2-256

puttygen 支持生成的四种密钥类型(rsa, dsa, ecdsa, ed25519, ssh-1 (rsa))应该只有 ed25519 可以用了。

删除 ssh-rsa 的原因:

另一方面关于 SHA-1 哈希算法,此前该算法被发现构造前缀碰撞攻击成本已降至低于 5 万美元(实际为 4.5 万美元),因此开发团队决定禁用 ssh-rsa 公钥签名算法。
有一些更好的算法可以替代,包括 RFC8332 RSA SHA-2 签名算法 rsa-sha2-256/512、ssh-ed25519 签名算法与 RFC5656 ECDSA 算法。目前这些算法在 OpenSSH 中都已经支持。

解决办法

要么开启对 ssh-rsa 的支持,要么重新创建一个 key,我选的后者。

  1. puttygen,密钥类型选择 ed25519,保存密钥对:~/.ssh/2204.ppk~/.ssh/2204.ppk.pub
  2. PUTTY配置 > 连接 > SSH > 认证,修改私钥文件路径:~/.ssh/2204.ppk

客户端方面的问题 Client Problem

上面解决了 Ubuntu 机器作为服务器的问题,现在发现客户端的 ssh 也默认移除了 ssh-rsa, ssh-dss (DSA) 的支持。

Unable to negotiate with 192.168.64.234 port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss

这个肯定得支持啊,不支持连接老的服务器可还行。

要么修改 ./ssh/config,要么修改 /etc/ssh/ssh_config。我选择后者。

Method 1

grep -Ev "^#" /etc/ssh/ssh_config | grep -Ev "^$"
Include /etc/ssh/ssh_config.d/*.conf
Host *
    SendEnv LANG LC_*
    HashKnownHosts yes
    GSSAPIAuthentication yes

直接到下面加上:

HostkeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa

Method 2: ~/.ssh/config

我发现修改 ~/.ssh/config 也有好处。我对 Home 目录下的配置文件有版本管理,可以带着走,/etc 目录我没有做这个 (之前做过,但用起来不够方便)。
而且如果改了 /etc 下的配置文件,下次更新的时候要 merge,相对来说麻烦一点。

修改 ~/.ssh/config 配置, 还是一样,在 Host * 下面加上:

HostkeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa

参考资料