简介:面向RockyLinux 9.6等EL9系发行版运维人员的一键升级包,用于将系统内置OpenSSH与OpenSSL批量升级至ssh 10.2p1和ssl 3.5.4版本。其核心价值在于通过统一脚本和RPM包解决手动编译升级易出错、依赖冲突等痛点,适用于需要修复已知安全漏洞的生产与测试环境。包体共6个文件,以5个RPM安装包和1个shell升级脚本为主,涵盖chkconfig、initscripts、openssh客户端与服务器端等组件,整体大小仅10.75MB,部署轻量,无需复杂前置配置,能降低因操作失误导致的系统故障风险。已有144人学习下载,经社区验证可兼容RockyLinux 9.6、RHEL 9.6、Oracle Linux 9.6、AlmaLinux 9.6及CentOS 9等主流发行版。下载后可获得完整的RPM包集合、一键升级脚本以及清晰的文件组织,帮助管理员在几分钟内完成SSH/SSL组件替换,显著提升远程管理通道和数据传输的加密强度,同时规避因版本过旧带来的已知漏洞风险,是维护Linux系统安全稳定运行的高效工具。
1. 一个 RPM 包解决 SSH/SSL 版本焦虑:rockylinux9.6 一键升级包到底省了什么
“rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64 一键升级包”,这串名字说白了就是给 Rocky Linux 9.6 x86-64 服务器准备的一组 RPM,把 OpenSSH 拉到 10.2p1、OpenSSL 拉到 3.5.4。安全扫描报出一堆 SSL/TLS 漏洞(CVE-2016-2183、Sweet32)却因为版本太老没法关单时,这种包最解渴。适合等保整改、内网离线升级、以及被漏扫报告追着跑的场景。这个方向要讲清楚的是三件事:为什么 SSH 和 SSL 必须绑在一起升、升级包怎么安全装上去、装完之后哪些配置最容易让远程连接翻车。
2. 为什么 OpenSSH 和 OpenSSL 必须绑在一起升:版本、链接与打包逻辑
2.1 漏扫报告催出来的升级:默认仓库版本为什么总慢半拍
Rocky Linux 9.x 默认仓库里的 OpenSSH 还停留在 8.7p1 左右,OpenSSL 是 3.0.x 系列。平时用没毛病,但漏扫报告一出来就难受:原理扫描会报 SSL/TLS 协议信息泄露漏洞 CVE-2016-2183,还会报支持 SSL 64 位块大小的密码套件 Sweet32。RHEL 系发行版的策略是用 backport 修复安全漏洞而不是升大版本,所以版本号看着老,但漏扫工具不认这个逻辑,它只看你协商出来的算法和版本字符串。
换句话说,你用ssh -V看到的 OpenSSH_8.7p1,即便内核修复了已知高危项,扫描器照样判定不满足整改要求。这时候就只能动真格升级。但升级 OpenSSH 有一个绕不开的前提:新版 OpenSSH 在编译和运行时都依赖新版 OpenSSL 提供的 libcrypto 能力,比如更强的密钥交换算法、证书验证逻辑、以及 FIPS 相关的密码学接口。只升 OpenSSH 不升 OpenSSL,编译新版本时可能直接报缺符号,就算强行挂上去,新算法也可能因为底层不支持而静默降级。
所以这类一键升级包把两个组件放在一起发布,是有工程依据的,不是顺手打包。你在红帽系服务器上做安全整改,最常见的做法就是找对应的 RPM 升级包,openssh 和 openssl 一起升,这样才能保证 sshd 二进制链接到的 libcrypto 版本和 OpenSSH 编译时期望的一致。单独升某一个,短时间能跑,漏扫复查大概率还是过不了。
2.2 ldd 说真话:sshd 与 libcrypto 的链接关系
在动手之前,先看一条命令。对着一台 Rocky Linux 9 服务器执行:
ldd /usr/sbin/sshd | grep -E 'ssl|crypto'输出一般是libcrypto.so.3 => /lib64/libcrypto.so.3,而 OpenSSL 3.0 到 3.5 系列的主版本号都是 3,soname 保持 libcrypto.so.3。这意味着 OpenSSL 从 3.0 升到 3.5,sshd 的二进制不需要重编也能加载到新库。但注意,这是 ABI 层面的兼容,不代表算法行为一致。OpenSSL 3.5 里默认安全级别更高,很多旧的密码套件被标记为不安全,sshd 拿到这些算法列表后会自动过滤。
反过来,如果你只有 OpenSSH 10.2p1 的新 rpm,却把系统里 OpenSSL 锁在旧版本,那么 sshd 可能起得来,但新版本里默认启用的某些密钥交换算法,比如基于 NIST 曲线的特定实现,如果底层 libcrypto 不支持,日志里会出现无法协商的报错,表现为客户端连不上、或者只能用老算法兜底。真实排障时我用strace -f -e trace=network,openat sshd -t跟踪过启动过程,看到它反复在找 libcrypto.so.3 里的符号,才明白版本配套有多重要。
这也是为什么升级包要把 ssh 和 ssl 版本一起写死:编译 OpenSSH 10.2p1 时链接的是 OpenSSL 3.5.4,运行时也给你装 3.5.4,两边版本对上,排除了最磨人的“二进制和运行库不匹配”问题。你不需要关心 rpmbuild 的 spec 文件里 BuildRequires 写了几行,只要知道这个包替你做完了版本匹配。
2.3 用 RPM 而不是 make install:可管理性、依赖与回滚
很多人拿到源码第一反应是./configure && make && make install,这在生产服务器上是给自己挖坑。源码安装的 OpenSSH 默认装进/usr/local/,而系统原有的/usr/bin/ssh、/usr/sbin/sshd还在,于是出现两套 SSH 共存:systemd 启动的可能是旧版,你在命令行敲ssh调用的可能是新版。漏扫扫的是 22 端口上监听的守护进程,你升级了个寂寞。
RPM 包的价值在于它替你把文件放回系统标准路径,覆盖掉旧版,并且写入 rpm 数据库。之后你可以用rpm -qf /usr/sbin/sshd查归属,用rpm -V openssh-server校验文件完整性,用yum versionlock锁版本。出了问题还能用rpm -Uvh --oldpackage回退到上一个 RPM。这些动作在 make install 的世界里全都不存在——你只能手工删文件,删不干净就等着下一次系统更新时冲突。
另外,编译 RPM 时依赖关系会被写进包头。比如 openssh-server 这个包会声明Requires: openssl-libs,强制保证 libcrypto.so.3 存在。如果你用一键升级包,rpm 在装 openssh 前会先检查 openssl-libs 是否满足依赖,不满足直接报错,这就是为什么升级包通常把 openssl 和 openssh 两个 rpm 一起给你,让你用一条 rpm 命令同时安装,让 rpm 自己排序。
3. 把一键升级包装上去:备份、安装顺序与重启
3.1 动手前先做两件事:确认基线版本与备份配置
升级前先确认系统确实是对的目标。标题里写明了 rockylinux9.6 和 x86-64,但生产服务器上跑什么系统你心里要有数,别拿到包就往上装。先跑一组命令:
cat /etc/rocky-release uname -m rpm -qa | grep -E '^(openssl|openssh)' ssh -V 2>&1 openssl version第一行看发行版版本,第二行看架构,第三行列出已装的 openssl 和 openssh 相关包,最后两行记录旧版本号。这里有个细节:ssh -V默认往标准错误输出打版本信息,所以写成ssh -V 2>&1,不然你在脚本里抓取不到。
确认完基线,备份配置目录。很多人只备份/etc/ssh,其实关键路径还有两个:/etc/pki和/etc/ssl。前者存放系统证书,后者是 OpenSSL 运行时的配置文件。如果服务器上跑着 HTTPS 服务,/etc/pki/tls/certs里的本地证书也要留意,不过升级 OpenSSL 不会动你的私钥,只是提醒你别在升级过程中顺手清掉。
mkdir -p /root/upgrade_backup cp -a /etc/ssh /root/upgrade_backup/ssh.$(date +%F) cp -a /etc/pki /root/upgrade_backup/pki.$(date +%F) rpm -qa | grep -E '^(openssl|openssh)' > /root/upgrade_backup/rpm-list.txt备份完之后,检查一下服务器上有没有用到旧 SSH 密钥文件的自动化任务,比如 cron 里写的 scp 同步。OpenSSH 10.x 对密钥格式和权限的检查更严格,如果密钥文件权限是 644,新版 ssh 客户端会直接拒绝加载,报bad owner or permissions。这种问题回滚也解决不了,因为 rsa 密钥的权限校验在旧版本也存在,只是警告,新版本变成了硬错误。
3.2 安装命令:为什么用 rpm -Uvh 一次装两个包
把升级包传到服务器后,进入包所在目录执行安装。我假设你已经把 openssl 和 openssh 相关的 rpm 文件放在/root/upgrade下,文件名以版本号开头,建议用通配符而不是手敲全名,减少打错文件名导致“没找到 rpm 包”的尴尬:
cd /root/upgrade rpm -Uvh \ openssl-3.5.4-*.rpm \ openssh-10.2p1-*.rpm不要分开执行两次rpm -Uvh。如果先装 openssh,而系统里 openssl-libs 还是旧版,rpm 会报依赖不满足直接退出。反过来先装 openssl 再装 openssh 理论上可行,但 RPM 在安装时会执行触发脚本,一条命令同时给两个包时,rpm 会自己计算依赖顺序:先升级 openssl-libs,再升级 openssh-server 和 openssh-clients,全程不出现在“中间态”。
这里补充一个参数说明:-U表示升级安装,老版本文件会被替换并备份为.rpmsave后缀;-v显示详细过程;-h打印进度条。升级过程中如果出现file /usr/bin/openssl from install of openssl-3.5.4 conflicts with existing file这种报错,说明系统里有非 rpm 包覆盖过/usr/bin/openssl,后面避坑章节我会展开讲。
3.3 重启 sshd 的顺序:先校验、再重启、最后检查自启
rpm 安装完成后不要急着重启。先跑sshd -t校验配置语法,再把当前 sshd 配置里的有效参数打出来看一眼:
sshd -t sshd -T | grep -E '^(ciphers|macs|kexalgorithms) 'sshd -t只做语法检查,不会启动进程,如果配置有问题它会明确报错在第几行。sshd -T是输出实际生效的配置,注意它输出的是 systemd 环境下最终合并的结果,包括/etc/sshd_config.d/目录下的所有片段。这一步能帮你提前发现配置冲突——比如你以前在 sshd_config 里手写过Ciphers,但系统策略文件里定义得更严格,最终生效的可能是你不认识的一组值。
确认无误后重启服务并确保开机自启:
systemctl restart sshd systemctl enable sshd systemctl status sshd --no-pager这里说一个许多人不知道的点:systemctl restart sshd不会断开你已经建立的 SSH 会话。因为 sshd 主进程负责监听 22 端口,你的已连接会话是独立的子进程,restart 只重置监听进程。但如果这台机器上只有 SSH 一种远程通道,重启动作本身有风险——万一 sshd 配置有误起不来,你的现有会话并不会立即断掉,可只要会话一断,就再也连不回来了。所以生产环境我强烈建议升级前开一个控制台会话(云厂商的 VNC 或 IPMI)保底,血泪经验不值得再付一次学费。
4. 升级后的验证与基线加固:版本、算法和策略三个层面
4.1 版本验证与算法清单:用三条命令确认升到位
装完先确认版本确实变成目标值。命令很简单,却经常有人只验证一半:
ssh -V 2>&1 openssl version openssl version -a | head -n 4第一条输出OpenSSH_10.2p1, OpenSSL 3.5.4之类的字符串,第二条输出OpenSSL 3.5.4。要警惕一种情况:如果 ssh 客户端二进制来自/usr/local/bin,而你升级的是/usr/bin/ssh,ssh -V可能还是旧版本。用which ssh和rpm -qf /usr/bin/ssh确认路径归属。
接着看算法支持情况。OpenSSH 提供了-Q参数直接查编译时支持的算法列表,不需要真去发起连接:
ssh -Q kex ssh -Q cipher ssh -Q mac这个列表是 sshd 能力上限,实际允许用的还要被配置文件约束。复查漏扫时,你会看到之前报的 Sweet32——也就是 64 位块大小的 CBC 类密码——在新版本里默认不再出现,因为 OpenSSH 10.x 的默认 Ciphers 只包含 AES-GCM 和 ChaCha20-Poly1305。如果你在内网用绿盟或 Nessus 复查,重点关注这两条是否消失,顺带看一眼 TLS 服务端口的扫描结果。
4.2 sshd_config 收紧密码套件:参数怎么设,哪些别乱禁
版本升上去了,但漏扫整改往往还要求你主动收紧算法。OpenSSH 默认启用的一组配置虽然安全,可如果你们安全团队有明确的基线清单,需要在 sshd_config 里显式声明。我通常会这样改:
# /etc/ssh/sshd_config Ciphers aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512 MACs hmac-sha2-256,hmac-sha2-512三个参数的逻辑分别是:Ciphers 只留 AEAD 类算法;KexAlgorithms 去掉所有 group14 及以下的 DH 组,因为 2048 位以下 DH 已经不被一部分扫描器信任;MACs 去掉 hmac-sha1 和所有-etm之外的弱算。改完执行sshd -t校验,再systemctl reload sshd平滑加载。
但有一个实际情况要提醒:如果你手上有 Windows 7 的旧机器或者老版本 PuTTY、Bitvise SSH Server 之类的客户端,上面这份配置会把它们全部拒之门外。Windows 7 自带的 OpenSSH 版本太老,不支持 curve25519,也不认识 chacha20-poly1305。VSCode 连接 SSH 远程服务器一般没问题,因为它用的是较新的 OpenSSH 客户端。
所以生产环境不要一上来就上最狠的配置。建议分两步:先保持默认,确认所有客户端能连,再收紧算法并观察一周日志。如果一定要兼容老客户端,KexAlgorithms 至少保留diffie-hellman-group14-sha256,Ciphers 保留aes128-cbc时要接受漏扫可能继续报 Sweet32。安全整改是个权衡题,别为了过扫描把业务机器变成孤岛。
4.3 crypto-policy 会覆盖 sshd 配置:改完不生效的真相
在 RHEL 系系统上改完 sshd_config 发现不生效,十有八九是 crypto-policy 在起作用。Rocky Linux 9 的 OpenSSH 编译时启用了系统加密策略支持,意味着 sshd 实际使用的一组算法是由/etc/crypto-policies/back-ends/openssh.config生成的,你在 sshd_config 里写的 Ciphers 会被这个文件覆盖。
验证方法很简单,你已经用过了:
sshd -T | grep -E '^(ciphers|macs|kexalgorithms) '把输出和你手写的配置对比,你会发现它跟你写的不一样,而是系统策略展开后的完整算法列表。如果你确实需要收紧策略,正确路径是调整系统策略等级,或者生成自定义策略子集:
update-crypto-policies --set LEGACY--set LEGACY会放宽到兼容老协议,但这也意味着 Sweet32 一类问题可能复现。更推荐的做法是写一个自定义策略文件,只针对 SSH 做调整。在/etc/crypto-policies/policies/modules/下创建一个模块,把要禁用的算法列进去,然后执行update-crypto-policies --set DEFAULT:模块名。
这块是最容易被漏扫整改人员忽略的:你在 sshd_config 里改了一堆参数,重载了服务,最后sshd -T一看什么变化都没有。我见过好几次这种情况,最后发现是策略模块生成了/etc/ssh/sshd_config.d/50-redhat.conf,而这个文件在你手动编辑的 sshd_config 之后加载,优先级更高。排查顺序应该是先看sshd -T实际值,再反查是哪个文件写入了这些值。
5. 避坑:远程升级 SSH/SSL 最容易踩的五个坑
5.1 远程会话中断:升到一半连不上了
现象:在远程终端执行 rpm 升级,跑到一半卡住,然后连接断开,再也连不上。控制台看系统还活着,就是 sshd 没起来。
原因:升级 openssl 时,rpm 触发脚本会重启依赖它的服务,如果这个过程中 sshd 尝试重启且加载了新配置失败,就会退出。另一个常见诱因是磁盘写满,rpm 事务写到一半空间不足,文件处于半更新状态,sshd 二进制损坏。
解决:升级前用df -h确认/usr和/var剩余空间大于 1GB。先把 openssl 单独升级并重启依赖服务验证,再升级 openssh,分两步走。如果已经断了,只能通过控制台登录,检查/var/log/messages里 sshd 的报错,然后手工执行sshd -t修复配置或回滚。
5.2 curl 报 unexpected eof while reading:新库把老对端拒了
现象:升级完 openssl,服务器上用 curl 访问某个 https 下载源,报curl: (35) error:0a000126:ssl routines::unexpected eof while reading。
原因:新版本 OpenSSL 默认安全策略不允许 TLS 1.0/1.1 和一批旧密码套件,对端是老旧服务器或老版本中间设备,握手时直接断开。类似的还有 MySQL 客户端报ssl 连接错误,SQL Server 驱动报证书链是由不受信任的机构颁发的,本质都是新版 OpenSSL 的证书校验和协议栈更严格。
解决:如果你这台服务器必须访问某些老系统,可以用 curl 临时降低协议版本和密码套件:curl --tlsv1.2 --ciphers DEFAULT@SECLEVEL=1验证连通性。长期方案是让对端升级 TLS 库,或者确认它是不是某个数据库、中间件的连接端口。临时兼容可以给应用设置环境变量OPENSSL_CONF指向一个自定义配置文档,调低安全级别,但生产环境不建议这么干,相当于为了老设备把自己的安全策略拉低。
5.3 sshd 起不来,客户端全部报 Connection closed
现象:升级完重启 sshd 后,任何客户端连接都报kex_exchange_identification: Connection closed by remote host,有些工具报更多细节。
原因:大概率是 sshd 配置里有旧版本不支持的算法名或语法。OpenSSH 10.x 把某些指令的写法改了,比如HostKeyAlgorithms之前可以用ssh-rsa,新版本里这个算法已从默认列表移除,如果配置里显式写了它且不带签名后缀,sshd 直接拒绝启动。
解决:先看日志journalctl -u sshd -n 50 --no-pager,然后跑sshd -t定位配置行。修复方式是删除或注释掉报错行,把配置恢复成默认,再逐项加回自己的参数。注意 sshd 配置文件里的Include /etc/ssh/sshd_config.d/*.conf指令,50-redhat.conf里如果写入了旧算法,你改主配置文件是没有用的。
5.4 一次 yum update 把版本打回原形
现象:升级完没几天,执行yum update,发现 openssh 和 openssl 被替换回仓库版本,之前的安全整改白做了。
原因:仓库里如果有比当前 RPM 版本号更高的包,更新时会被选中覆盖。编译时 Release 号写得太低,比如1.el9,仓库里某个补丁版本是0.5.el9,比较版本号时主版本更高就直接替换了。
解决:升级完成后立刻锁定版本:
yum install -y yum-plugin-versionlock yum versionlock add openssh openssh-server openssh-clients openssl openssl-libsyum versionlock list可以查看锁定项。另外建议把这次的一键升级包留档,同时生成一份rpm -qa | grep -E 'openssh|openssl'的清单,下次做镜像或克隆机器时可以直接复用它。
5.5 rpm 报文件冲突和“没找到 rpm 命令”
现象:执行 rpm 安装时,报file /usr/bin/openssl ... conflicts with existing file,或者干脆提示bash: rpm: command not found。
原因:文件冲突是之前有人用 make install 编译过 OpenSSL 放在系统路径里,或者另一个第三方 rpm 包抢先安装了该路径。rpm 命令找不到则多半是 PATH 被改过,或者 bash 环境文件被污染,/usr/bin 没有被包含在 PATH 里。
解决:先确认冲突文件归属:rpm -qf /usr/bin/openssl。如果显示not owned by any package,说明是手工放置的,建议移走而不是--replacefiles强行覆盖,因为手工文件的来源不可控。rpm 命令找不到时,用绝对路径执行/usr/bin/rpm,同时检查/etc/profile和~/.bashrc里有没有覆盖 PATH。这台机器如果是被入侵过导致 PATH 异常,先查安全事件,别急着装包。
6. 回滚与固化:给升级加一道后悔药
6.1 三种回滚路径,按优先级排序
回滚路径有三条。最轻量的是保留旧版 rpm 文件,用rpm -Uvh --oldpackage降级回去。升级包安装前把旧包用yumdownloader拉下来存好,就能随时回到升级前状态。这条路径适合只是配置或版本不兼容的情况。
第二优先级是备份还原。把/etc/ssh和/etc/pki备份目录恢复回去,重启 sshd。这条路径解决配置类问题,解决不了二进制层面的兼容性问题,因为旧配置配新二进制可能反而更糟。
第三优先级是系统快照,也是我最推荐在生产服务器上做的。云主机控制台打一个磁盘快照,或者本地 LVM 卷做lvcreate --snapshot,升级前拍一张,出问题直接回滚整个系统。RPM 回滚对依赖关系的处理不一定干净,快照是物理层面的后悔药。
6.2 防止版本被后续更新覆盖
版本锁定用 versionlock 是一个手段,但要注意它只管 dnf/yum 的自动更新,不影响你手动 rpm -Uvh。更稳妥的是把一键升级包的文件放到自己的 yum 仓库里,比如内网用createrepo生成元数据,然后把仓库优先级调高。这样每次系统更新时,dnf 会对比本地仓库和官方仓库,你这个 10.2p1 版本永远比官方源里 8.7p1 版本新,不会触发替换。
另外我习惯在每年做一次安全基线复查时,写一个小脚本自动巡检 SSH 和 SSL 版本,防止哪次更新把它悄悄改了没人发现。
6.3 端到端验证脚本
升级完成不等于整改结束,漏扫复查前先自己验一遍。我一般把验证写成一段可直接执行的脚本,避免手工漏项:
#!/bin/bash set -e ssh -V 2>&1 | grep -q 'OpenSSH_10.2p1' || exit 1 openssl version | grep -q '3.5.4' || exit 1 sshd -t sshd -T | grep -q 'chacha20-poly1305@openssh.com' || exit 1 ssh -o BatchMode=yes -o ConnectTimeout=5 root@127.0.0.1 true \ && echo "local ssh check pass" nmap --script ssl-enum-ciphers -p 22 127.0.0.1 | grep 'sweet32' && exit 1 echo "upgrade verification passed"脚本断言的逻辑是:版本字符串对上,sshd 配置语法没问题,实际生效的 Ciphers 包含 AEAD 算法,本地回环 SSH 能真实建连,最后用 nmap 检查 22 端口没有 Sweet32 类算法。最后一条在只有 nmap 权限受限时会失败,没有装 nmap 的机器可以先跳过。
这些检查项看起来简单,但每一条我都踩过对应的坑。远程升级这类操作,事后验证比事中小心翼翼更值钱——验证脚本把“感觉没问题”变成“确实没问题”。希望这篇能帮你顺利把 SSH 和 SSL 的整改单关上,少走我走过的弯路。
本文还有配套的精品资源,点击获取