SSH 突然 Connection reset?不是密钥坏了,是 OpenSSL 把 sshd 干趴了

OpenSSH 起不来:OpenSSL 3.5 和旧版 sshd 对不上

现象:阿里云 ECS 的 22 端口直接 Connection reset,工作台里 systemctl restart sshd 失败。根因不是 sshd_config,而是 OpenSSL 已经升到 3.5,sshd 还停在按 3.0 编译的包。

现象

从外面连服务器:

text 复制代码
kex_exchange_identification: read: Connection reset
Connection reset by x.x.x.x port 22

SSH 握手还没开始就被掐掉,多半是 sshd 根本没在听 ,而不是密钥、安全组或 PermitRootLogin。

进不了 SSH,只能走阿里云控制台的 工作台 / VNC。在机器里执行:

bash 复制代码
systemctl restart sshd

得到:

text 复制代码
Job for sshd.service failed because the control process exited with error code.
See "systemctl status sshd.service" and "journalctl -xeu sshd.service" for details.

定位

不要先改配置。先看服务日志和配置自检:

bash 复制代码
systemctl status sshd.service --no-pager -l
journalctl -u sshd.service -n 80 --no-pager
sshd -t

日志里反复出现同一句:

text 复制代码
OpenSSL version mismatch. Built against 30000070, you have 30500080
sshd.service: Main process exited, code=exited, status=255/EXCEPTION
Failed to start OpenSSH server daemon.

版本号可以拆开看:

十六进制 含义
30000070 sshd 编译时 用的 OpenSSL 3.0.7
30500080 机器上 正在加载 的 OpenSSL 3.5.8

OpenSSH 会在启动时核对 OPENSSL_VERSION_NUMBER。库比编译时的新太多,进程直接退出,systemd 再自动拉起,于是日志里会出现一串 restart counter is at 2/3/4...。

再确认包和动态库:

bash 复制代码
openssl version
rpm -q openssl openssl-libs openssh-server
which sshd
ldd $(command -v sshd) | grep -E 'ssl|crypto'

当时机器上是:

text 复制代码
OpenSSL 3.5.9 29 Sep 2026
package openssl is not installed
openssl-libs-3.5.9-1.el9.x86_64
openssh-server-8.7p1-32.el9.x86_64
/usr/sbin/sshd
libcrypto.so.3 => /lib64/libcrypto.so.3

结论很清楚:

  • 系统 libcrypto.so.3 已经是 3.5.x
  • openssh-server 还是 8.7p1 ,按 3.0.7 编的
  • 独立的 openssl RPM 甚至已经不在了,只剩 openssl-libs

这不是配置写错,也不是端口被占。先不要改 /etc/ssh/sshd_config,更不要重启无关服务。

踩坑:把 OpenSSL 再降一格没用

第一反应是把 OpenSSL 降回 3.0.7:

bash 复制代码
dnf -y downgrade openssl-libs

dnf 只从 3.5.9 降到 3.5.8 ,因为仓库里的相邻版本就是 3.5.8。sshd -t 依旧报:

text 复制代码
OpenSSL version mismatch. Built against 30000070, you have 30500080

再看仓库里到底有什么:

bash 复制代码
dnf list --showduplicates openssl-libs

baseos 里只有:

text 复制代码
openssl-libs  3.5.7 / 3.5.8 / 3.5.9

没有 3.0.7。 发行版已经把 OpenSSL 切到 3.5 线,不能再靠降库去迁就旧 sshd。方向反了:应该让 OpenSSH 跟上 OpenSSL,而不是把 OpenSSL 拧回 3.0。

正确修复:升级 OpenSSH

bash 复制代码
dnf list --showduplicates openssh-server
dnf -y update openssh openssh-server openssh-clients
sshd -t
systemctl start sshd
systemctl is-active sshd

这次会把整组升到匹配 3.5 的构建,例如:

text 复制代码
openssh-9.9p1-16.el9
openssh-clients-9.9p1-16.el9
openssh-server-9.9p1-16.el9

升级过程中可能看到:

text 复制代码
warning: /etc/ssh/sshd_config created as /etc/ssh/sshd_config.rpmnew

这表示 正在生效的仍是原来的 sshd_config ,新包默认配置另存为 .rpmnew。密钥登录、监听端口一般不用动。

自检通过的标志:

  • sshd -t 没有输出(静默即成功)
  • systemctl is-active sshd 为 active

然后从外面再连一次 22 端口,应能正常完成密钥交换。

为什么会这样

OpenSSH 和 OpenSSL 必须 同一套 ABI 一起走。常见触发方式:

  1. dnf update 只更新了 openssl-libs,openssh-server 还停在旧构建
  2. 第三方源 / 预发布源把 OpenSSL 推到 3.5,但 OpenSSH 仍是 8.7
  3. 有人只升级加密库,没把 openssh、openssh-server、openssh-clients 一起升

EL9 上官方 openssh 8.7 是按 OpenSSL 3.0 编的。发行版若已经提供 openssh 9.9 + openssl-libs 3.5,就要整组对齐,不能一半新一半旧。

以后可以怎么防

  1. SSH 挂了优先看 journalctl -u sshd 和 sshd -t,不要先改配置。
  2. 看到 OpenSSL version mismatch,先对一下:
    • sshd 编译目标(Built against)
    • 当前 openssl-libs
    • 仓库里 openssh-server 有没有对应新构建
  3. 仓库已经没有旧 OpenSSL 时,升 OpenSSH ,不要死磕 dnf downgrade。
  4. 修 SSH 时不要顺手启动业务进程,避免排障过程中再引入一台抢端口、抢连接的服务。
  5. 升级后如果出现 sshd_config.rpmnew,先确认旧配置仍在用;不要无脑用新文件覆盖。

一句话

sshd 起不来不一定是配置问题。Built against 3.0.7, you have 3.5.8 时,如果仓库里已经没有 3.0,就把 OpenSSH 升到和当前 OpenSSL 同一代,而不是把 OpenSSL 再降一小步。


标签建议:运维、Linux、SSH、OpenSSL、阿里云

相关推荐
程序员大阳12 分钟前
副队长ES6+教程(3)--解构赋值
前端·javascript·es6·赋值·解构
神膘护体小月半30 分钟前
css - 元素背景图由 hover 触发,初次加载时闪动的解决办法
前端·javascript·css
程序员大阳1 小时前
副队长ES6+教程(2)--let 与 const
前端·javascript·es6·const·let·var
回眸&啤酒鸭1 小时前
【回眸】Node.js 新手从零到一实战指南
node.js
deli0071 小时前
写满 200GB 后 SSD 为什么掉到 95MB/s?SLC 缓存模型实测
前端
Thanks_ks2 小时前
【第 008 讲】在终端中运行 Python 程序:交互模式与脚本模式 | 绝对路径与相对路径 | 以模块方式运行 | 常见报错的识别与排查
python·异常处理·终端·脚本·命令行·cmd·python 解释器
曦樂~2 小时前
【Web Development】03JavaScript 基础和事件
开发语言·前端·javascript
deli0072 小时前
HTTPS 的锁是怎么挂上的?TLS 1.3 握手 6 步实测
前端
程序员大阳2 小时前
副队长ES6+教程(1)--ES6+初识
前端·ecmascript·es6