OpenSSH 从 8.8 版本开始默认禁用 ssh-rsa 公钥算法,9.0 及更高版本延续了这一安全策略。若客户端或服务端版本较高且仍使用 RSA 密钥,会导致握手失败。最稳妥的处理方式是生成新的 ED25519 密钥对替换旧的 RSA 密钥,而不是强行开启已废弃的算法。
先说结论:这是 OpenSSH 的安全策略调整,建议更换密钥类型而非降级配置。
- 先确认:检查客户端与服务端 OpenSSH 版本是否大于 8.8
- 先处理:使用 ssh-keygen 生成 ed25519 新密钥并替换
- 再验证:通过 ssh -v 观察握手阶段使用的算法
核心原因:版本策略变更
OpenSSH 在 8.8 版本开始默认禁用了 ssh-rsa 公钥算法,因为该算法依赖的 SHA-1 哈希函数存在碰撞风险。9.0 版本延续了这一策略。客户端或服务端任意一方版本较高且未配置旧算法支持时,握手会失败。
解决方案一:更换客户端密钥(推荐)
1. 备份现有密钥:
cp ~/.ssh/id_rsa ~/.ssh/id_rsa.bak
2. 生成新密钥:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "your_email@example.com"
3. 部署公钥到服务器:
情况 A:密码登录仍可用
若服务器允许密码认证,可直接使用 ssh-copy-id:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
情况 B:完全无法连接(需控制台操作)
若 SSH 完全不可用,请通过云厂商控制台或 VNC 登录服务器,手动追加公钥:
# 在本地查看公钥内容
cat ~/.ssh/id_ed25519.pub
# 在服务器端执行
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "粘贴上面的公钥内容" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
解决方案二:更换服务端 Host Key
如果客户端报错提示 host key 类型不匹配,可能是服务端主机密钥也是 RSA 类型。需在服务端生成新 Host Key:
# 生成新的 ED25519 主机密钥
sudo ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
# 修改 sshd_config 确保优先使用新密钥
sudo vi /etc/ssh/sshd_config
# 确保包含或取消注释:HostKey /etc/ssh/ssh_host_ed25519_key
# 重启服务
sudo systemctl restart sshd
临时兼容方案(仅限排查)
警告:以下命令会启用不安全的算法,仅用于临时排查,生产环境不建议长期开启。
临时测试连接:
ssh -o PubkeyAcceptedAlgorithms=+ssh-rsa -o HostkeyAlgorithms=+ssh-rsa user@host
若需永久兼容(不推荐),修改客户端 config 文件 ~/.ssh/config:
Host *
PubkeyAcceptedAlgorithms +ssh-rsa
HostkeyAlgorithms +ssh-rsa
验证方法
使用详细模式连接,查看协商出的算法:
ssh -v user@host
在输出日志中寻找 Server host key: 和 Offering public key: 行,确认不再出现 ssh-rsa 字样,而是 ssh-ed25519 或 rsa-sha2-256。
常见坑
1. 仅修改客户端配置而服务器端 Hostkey 仍是旧 RSA 类型,连接仍会失败。
2. 某些老旧嵌入式设备无法升级 OpenSSH,只能被迫在客户端开启兼容模式。
3. 自动化脚本中硬编码了密钥路径,更换密钥后需更新脚本配置。
4. 手动复制公钥后,务必检查 ~/.ssh 和 authorized_keys 权限,否则 SSH 会拒绝读取。