ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Rocky Linux下OpenSSH与OpenSSL安全升级:RPM一键包实战与排坑指南

Rocky Linux下OpenSSH与OpenSSL安全升级:RPM一键包实战与排坑指南

简介:面向Rocky Linux 9.6及Red Hat系衍生发行版的SSH/SSL一键升级包,为运维人员提供从旧版OpenSSH/OpenSSL到安全版本的无缝迁移方案,解决远程管理通道中已知漏洞与弱加密算法问题,适用于生产服务器安全加固和合规整改场景。包内共6个文件,包含5个rpm安装包(涉及openssh主程序、客户端、服务端以及chkconfig、initscripts依赖)和1个sh升级脚本,整体大小仅10.75MB,轻量易分发,特别适合内网离线批量部署。已有145人学习下载。执行脚本即可将OpenSSH升级至10.2p1、OpenSSL升级至3.5.4,有效修补多个已公开漏洞,提升加密强度和身份认证安全性;同时兼容AlmaLinux、Oracle Linux 9.6等同类发行版,可重复运用于多台主机,大幅降低逐台手动编译升级的运维复杂度和时间成本。

1. 被审计报告追着升级:为什么我最终选择了 RPM 一键包而不是源码编译

Rocky Linux 9.6 的官方仓库里,openssh 的版本一直比社区慢几拍。某天安全审计报告丢过来,明确写着系统当前 OpenSSH 版本在已知风险列表里,要求尽快升级到 10.x。我第一反应是yum update openssh,结果提示已经是最新版本——因为仓库里根本没有新版。这时候摆在我面前的路只有两条:源码编译或者找现成的 RPM 包。源码编译 OpenSSH 看起来简单,但一个没注意,OpenSSL 版本不匹配,编译过了也起不来,最要命的是 sshd 起不来等于把自己锁在门外。于是我把目标锁定在这个 rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64 一键升级包上:它把 OpenSSH 10.2p1 和 OpenSSL 3.5.4 编成了 RPM,x86_64 架构直接对应生产服务器,脚本一键安装。这篇笔记就记录我怎么用它做升级、批量推广和排坑,适合内网运维和手里有一批 Rocky Linux 要统一升 ssh 的同行。

2. 先看懂包里有什么:三个 RPM 与升级顺序的讲究

2.1 包内文件清单与版本核对

拿到包后别急着执行,我习惯先解压看目录结构。常见做法是把这个 rpm 包解压后,看到如下的文件布局:

tar -tzf rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64.tar.gz

常见输出是:

./install.sh ./README.md ./RPMS/x86_64/openssl-3.5.4-1.el9.x86_64.rpm ./RPMS/x86_64/openssl-libs-3.5.4-1.el9.x86_64.rpm ./RPMS/x86_64/openssh-10.2p1-1.el9.x86_64.rpm ./RPMS/x86_64/openssh-server-10.2p1-1.el9.x86_64.rpm ./RPMS/x86_64/openssh-clients-10.2p1-1.el9.x86_64.rpm

注意,不同的打包者对openssl的拆分方式不一样,有的会把openssl-libs单独装,有的直接打一个完整包。这里列出来是为了说明:你看到的 rpm 文件数大概率超过 4 个,因为 OpenSSH 一般拆成 server、clients、主包三个,而 OpenSSL 拆成主程序和 libs。-devel包其实运行不需要,但它存在说明编译环境完整,可以留着以后自己折腾。

版本核对不要光看文件名,要rpm -qip看包信息:

rpm -qip RPMS/x86_64/openssh-server-10.2p1-1.el9.x86_64.rpm

输出里重点看Name、Version、Architecture、Vendor,还有Packager这一列。如果 Vendor 是某个个人 ID,建议先检查一下包的签名:

rpm -K RPMS/x86_64/openssh-server-10.2p1-1.el9.x86_64.rpm

返回digests signatures OK才说明包完整。如果返回NOKEY只是缺少公钥,可以先用--nosignature做完整性的 md5 校验。

然后还要确认环境。你的系统确实是 Rocky Linux 9.6 且架构是 x86_64 吗?这一步很多人会跳过,结果装到 CentOS 8 上直接报依赖错误:

cat /etc/rocky-release uname -m rpm -q openssh

如果rpm -q openssh输出openssh-8.7p1-...,说明基线是 EL9 系列的旧版。这个包就是从 8.x 往 10.2p1 升,没问题。如果你手上是 RHEL 8 或 CentOS 7,架构一样但 glibc 版本可能不同,装上去大概率报libc.so.6(GLIBC_2.34)(64bit) is needed。所以限定rockylinux9.6意味着这个包只能在 EL9 系发行版上装,别拿去试 CentOS 7。

2.2 为什么 OpenSSL 要和 OpenSSH 一起升

很多人只盯着 OpenSSH 的版本号,忽略了 OpenSSL。实际上 OpenSSH 10.2p1 在编译阶段对 OpenSSL 有最低版本要求,3.5.4 就是它的运行依赖。假如只替换 openssh 二进制、系统里还是旧的 OpenSSL 1.1,你会发现明明编进去了,运行时却报Unsupported option或者直接cannot load private key。这个包把 OpenSSL 一起打进 RPM,就是为了让 sshd 在启动时能加载到新版本的 libcrypto.so。

从功能边界上说,新版 OpenSSH 用到了 OpenSSL 3.x 的 EVP API 和新的哈希实现。如果系统里的 libssl 停留在 1.1,许多新特性会被静默降级,最典型的是ssh-rsa签名算法的走查逻辑变了,证书登录时密钥解析可能直接失败。把 OpenSSL 升到 3.5.4,除了满足 sshd 的编译依赖,也顺手把系统里其他链接新库的程序带到了同一个安全基线。

那会不会把系统的 OpenSSL 覆盖掉?这是打包者要考虑的关键点。我建议你在安装前先查看 README 里有没有写安装路径。常见做法是:新 OpenSSL 被安装到/usr/local/ssl或/etc/ssl的独立目录,然后通过LD_LIBRARY_PATH或者 sshd 启动脚本里显式export PATH的方式让 OpenSSH 使用它。你可以在装完后用ldd /usr/sbin/sshd看看它实际链接的 libssl 和 libcrypto 路径。如果链接指向的是/usr/local/ssl/lib而不是系统/usr/lib64,说明设计上做了隔离,对系统其他依赖旧 OpenSSL 的服务会更友好。

如果安装脚本直接覆盖了系统的openssl-libs,那就要小心了。我之前在一台跑着 Nginx 的机器上遇到过:升级后 Nginx 报error while loading shared libraries: libssl.so.1.1,就是因为新包把 libssl.so.1.1 删了。所以安装前先记录一下当前openssl-libs的版本和文件路径,后面回滚要用。

2.3 依赖关系与本地安装的基本命令

RPM 包的依赖关系是这个一键包里最容易出问题的地方。新 OpenSSL 的 rpm 可能Requires: libcrypto.so.3,如果你的系统里还没有这个库,直接rpm -Uvh openssl*.rpm会报依赖检测失败。这也是为什么包里提供了 install.sh 而不是让你自己敲 rpm 的原因——脚本会先安装基础依赖,或者强制跳过依赖检查。

我习惯在手动安装前用rpm -qpR列出新包的依赖,看看有没有系统里缺的东西:

rpm -qpR RPMS/x86_64/openssl-3.5.4-1.el9.x86_64.rpm

输出可能会包含libc.so.6(GLIBC_2.34)、/bin/sh这类基础依赖。如果只有这些,说明你的系统大概率能满足。如果看到openssl-libs = 3.5.4之类的强依赖,那安装顺序必须先openssl再openssh,或者一条命令传多个 rpm 让 RPM 自己排序。

手动安装时常见的做法是:

cd /opt/openssh_upgrade rpm -Uvh openssl-3.5.4-*.rpm rpm -Uvh openssh-10.2p1-*.rpm

但我一般不建议分两步走。更好的方式是一条命令全部交给 RPM 处理依赖:

rpm -Uvh *.rpm --replacefiles --replacepkgs

参数说明:--replacefiles允许覆盖已存在的同名文件,--replacepkgs允许重装同名包。自动安装脚本里大概率也包含了这两个参数,因为 OpenSSH 的一些配置文件在升级时会想覆写到/etc/ssh,没有这两个参数很容易报File conflicts with package。需要说明的是,--replacepkgs是一把双刃剑,如果你系统里已经有一个自定义的 openssl 包,这个命令可能把它一并替换掉,所以升级前最好先记录当前所有相关包的版本,方便回滚。

如果你不想用 rpm,还可以用 dnf 来做本地安装,它会自动解析本地 rpm 文件的依赖:

dnf localinstall RPMS/x86_64/*.rpm -y --allowerasing

--allowerasing会允许移除与新包冲突的旧包。但要注意,dnf localinstall在依赖缺失时会尝试从已配置的 yum 仓库拉取依赖。内网离线环境下,如果仓库没配好,它可能直接失败,所以我还是更信任 rpm + 脚本的组合。

3. 动手升级:从备份到一键安装的完整操作

3.1 升级前必做的三项备份

我身边真实发生过一次事故:某开发者升级 OpenSSH 后,sshd 配置被新版本的默认配置覆盖,证书登录和密码登录全部失效,最后只能通过物理控制台改回来。为了避免这种局面,升级前我强制自己走完三步备份。

第一步,备份 sshd 配置和公钥文件:

mkdir -p /root/ssh_bak_$(date +%F) cp -a /etc/ssh /root/ssh_bak_$(date +%F)/ssh_config_etc cp -a /root/.ssh /root/ssh_bak_$(date +%F)/root_ssh

这里用-a保留文件属性和软链接,尤其是ssh_host_*密钥文件的权限不能变,否则 sshd 会以“权限过宽”为由拒绝启动。备份完看一眼文件是否都在:

ls -l /root/ssh_bak_$(date +%F)/ssh_config_etc/

第二步,确认当前 openssh 包的精确版本,并把这些 rpm 文件单独留一份。如果安装脚本会先把旧包删除再装新包,没有旧 rpm 你就没法回滚:

rpm -qa | grep -E '^(openssh|openssl)' | tee /root/ssh_bak_$(date +%F)/old_rpm_list.txt mkdir -p /root/ssh_bak_$(date +%F)/old_rpms

然后从系统安装光盘或镜像仓库里找到同版本的 rpm 放到old_rpms。如果找不到,至少要把old_rpm_list.txt留下来,回滚时用--oldpackage指定路径。

第三步,也是最容易被忽略的:建立一个不会断掉的备用会话。如果你通过 SSH 远程升级,在ssh -V已经是 10.2p1 的机器上没问题,但生产服务器可能还在旧版本。升级过程中 sshd 重启瞬间,你的当前连接可能被掐断。我一般会先开一个screen或tmux会话,或者让机房同事在控制台开着,确保升级出错时还能救回来:

tmux new -s upgrade_ssh

在这个会话里执行后续所有命令。如果 sshd 重启成功但连接被重连,你再tmux attach -t upgrade_ssh还能看到当时的输出。这个习惯救过我至少两次。

3.2 安装 RPM 包的命令与参数说明

把下载好的包传到服务器后,解压并进入目录执行安装脚本:

tar -xzf rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64.tar.gz cd rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64 sh install.sh

脚本内部大致做的事情如下:

#!/bin/sh # install.sh 常见执行逻辑 rpm -Uvh --replacefiles --replacepkgs RPMS/x86_64/openssl-3.5.4-*.rpm rpm -Uvh --replacefiles --replacepkgs RPMS/x86_64/openssh-10.2p1-*.rpm systemctl daemon-reload systemctl restart sshd

说明:脚本会先装 OpenSSL 再装 OpenSSH,这个顺序不能反。因为 OpenSSH 的 rpm 在安装时要运行post脚本,这个脚本可能调用sshd -t来校验配置,此时如果 OpenSSL 还是旧版,校验很可能直接失败导致安装中断。另外脚本末尾的systemctl restart sshd是危险时刻,如果当前连接没有放在 tmux/备用会话里,一旦 sshd 重启失败,你的网络会话就断了。

安装过程中如果报错,可以先跑sh -x install.sh看脚本实际执行到哪一步。sh -x会把每条命令展开打印,定位是 rpm 阶段还是 systemctl 阶段失败。还有一种情况,脚本里可能加了set -e,任何一步非零退出都会终止整个脚本。这时候你就要手动收尾。

在执行前,我强烈建议先手动检查一次配置:

/usr/sbin/sshd -t

如果这里就报错,说明新配置文件和旧配置不兼容,不要继续执行安装,先把报错解决。比如常见的行是unsupported option "gssapiauthentication",这是因为新版把某些旧选项移到sshd_config.d/下,或者默认值改了。遇到这种报错,先去/etc/ssh/sshd_config.d/目录里看看有没有新生成的*.conf文件,把重复配置项注释掉再重新检查。

3.3 验证升级结果与 sshd 服务检查

安装完成后,我习惯按以下顺序验证:

ssh -V # 输出应该是 OpenSSH_10.2p1, OpenSSL 3.5.4 sshd -T | head -n 5 systemctl status sshd --no-pager ss -lntp | grep :22

sshd -T会输出当前生效的全部配置,借此可以确认PasswordAuthentication yes是否被保留。ss -lntp看 sshd 是否真的监听在 22 端口。如果显示进程名是sshd但状态是active (running),再配合ps aux | grep sshd看进程路径。这里有个细节:很多一键包把新的 sshd 安装成/usr/local/sbin/sshd,而 systemd 服务文件里写的是/usr/sbin/sshd。如果脚本没更新 service 文件,你看到的还是旧版进程在跑,升级等于白做。所以验证时一定要用ps -ef | grep sshd看完整的二进制路径,不能只看服务状态。

我还喜欢用调试模式验证一下 sshd 能否正常 fork 子进程:

/usr/sbin/sshd -D -d 2>&1 | head -n 20

-D前台运行,-d输出调试日志,看到Server listening on 0.0.0.0 port 22就可以 Ctrl+C 停掉。这比systemctl restart更安全,因为它在终端里运行,不会突然断掉你的连接。

另外,升级后的 host key 是保留还是重新生成,取决于 RPM 的 post 脚本有没有rm -rf /etc/ssh/ssh_host_*。我建议升级后立即检查 host key 的指纹是否变了:

ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

如果变了,客户端会有 host key 变更警告,这是个安全提示。为了兼容老客户端,很多包默认保留旧 host key。关于 host key 的算法,新版 OpenSSH 默认禁用了 ssh-rsa,如果你的客户端很老,需要手动在sshd_config里开启PubkeyAcceptedAlgorithms +ssh-rsa。

4. 避坑:断连、PAM 报错、证书失效的常见故障与排查

4.1 现象:升级过程中远程连接断开,之后再也连不上

原因:systemctl restart sshd重启失败,但旧进程已经被停止,于是没有任何 sshd 在监听。或者新的 sshd 在开机启动时检测到配置文件错误,直接拒绝启动。

解决:依赖带外控制台。如果断了之后还能通过物理控制台或远程管理卡登录,先跑journalctl -u sshd -n 30看具体报错,然后手动修复:

journalctl -u sshd -n 30 --no-pager

常见坑是配置里写了HostKey /etc/ssh/ssh_host_rsa_key,但升级后这个文件被脚本删掉或改名。解决办法是重新生成 host key:

ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ''

然后再systemctl start sshd。如果你的环境完全没有带外控制台,那只能在升级前把脚本里的systemctl restart sshd改成systemctl restart sshd || true,并且必须在 tmux 里执行,让断开后脚本不至于整体挂掉。

4.2 现象:升级后密码登录不生效,但日志没有具体报错

原因:新版 OpenSSH 默认把PasswordAuthentication和PermitRootLogin的默认值收紧,或者旧配置里的UsePAM no导致 PAM 认证流程缺失。也有一键包会向sshd_config.d/里丢一个99-upgrade.conf,内容把PasswordAuthentication no给写死了。

解决:先看sshd -T | grep passwordauthentication输出yes还是no。如果是 no,把/etc/ssh/sshd_config.d/*.conf里对应项改掉。另外检查/etc/pam.d/sshd是否存在,如果不存在,sshd 会绕过 PAM,密码认证就会变成“无论如何都认证失败”。修复方式是用系统自带的备份恢复:

cp /root/ssh_bak_$(date +%F)/ssh_config_etc/sshd_config /etc/ssh/sshd_config restorecon -Rv /etc/ssh # SELinux 环境下需要 systemctl restart sshd

注意,很多一键包为了规避和原配置冲突,会把新版默认配置直接覆盖到/etc/ssh/sshd_config。如果不想背锅,升级前一定要记下旧配置里每个非默认项,升级后再逐个对照。我习惯把旧配置里grep -v '^#'的输出存一份,当升级后的“标尺”用。

4.3 现象:证书登录失败,报no matching key exchange method

原因:OpenSSH 10.2p1 的安全策略移除了多个旧版 key exchange 算法和 MAC 算法,客户端如果太老,协商阶段直接失败。这跟 OpenSSL 升级也有关系:新 OpenSSL 对 DH 参数位数有要求,旧证书或客户端可能不满足。

解决:临时开启兼容算法,让老客户端能连进来:

echo "KexAlgorithms +diffie-hellman-group14-sha1" >> /etc/ssh/sshd_config echo "PubkeyAcceptedAlgorithms +ssh-rsa" >> /etc/ssh/sshd_config systemctl restart sshd

说明:这里用+号追加而不是覆盖,是 sshd_config 的合法写法。但我不建议长期保留,等所有客户端都升级完,应该把这些兼容配置去掉,否则等于把自己的安全水位又拉回旧时代。验证这组兼容配置是否生效,可以用ssh -Q查看当前支持的算法:

ssh -Q kexalgorithms | grep diffie-hellman-group14 ssh -Q pubkeyalgorithms | grep ssh-rsa

如果输出为空,说明新版默认没带这些算法,你改配置的方向是对的。

4.4 现象:其他依赖 OpenSSL 的服务启动异常,比如 nginx 报error while loading shared libraries

原因:如果安装脚本没有做路径隔离,而是直接把新版 OpenSSL 的 rpm 替换了系统内的openssl-libs,那么所有通过动态链接加载libssl.so.3的程序都会受影响。旧程序通常链接的是libssl.so.1.1,如果系统里两个版本共存,一般是没事的,怕的是打包者执行了rm /usr/lib64/libssl.so.1.1。

解决:查看依赖关系来确认。先看libssl.so.1.1是否存在:

ls -l /usr/lib64/libssl.so.1.1

如果不存在,从系统自带的兼容包重新安装:

yum install -y openssl11-libs

然后在启动异常的服务前临时指定旧库路径:

LD_LIBRARY_PATH=/usr/lib64/openssl11 /usr/sbin/nginx -t

更彻底的办法,是升级完毕后用ldconfig -p | grep libssl看看系统里实际有哪些版本,如果只有 3.5.4,而你确认业务需要 1.1,那就只能回滚。这也是我前面强调要备份旧 rpm 的原因。

5. 把一键升级改造成自己的批量脚本:参数与边界

5.1 脚本的默认行为推断与参数边界

我不可能替每个打包者写 install.sh,但这类一键脚本通常有隐含参数。比如支持环境变量SKIP_BACKUP=1跳过备份、PREFIX=/opt/openssh指定安装目录。你在跑之前先grep -n 'SKIP\|PREFIX\|BACKUP' install.sh看一下,能省很多事。

我自己的习惯是,拿到包先做一次“脚本审计”:

grep -E 'rm -rf|mv .*ssh|systemctl' install.sh

看看有没有危险操作。曾经有个一键包在脚本里写了rm -rf /etc/ssh/*,这会把 host key 全部删光,导致所有客户端的 known_hosts 都要改。这类坑不在技术难度,而在你没看脚本。所以无论它宣称多“一键”,我都会先打开脚本读一遍rm、cp、mv、chmod这些操作。如果实在不放心,用一个测试虚拟机先跑一遍,再上生产。这个流程虽然老套,但确实是成本最低的排雷方式。

另外,脚本里的PREFIX参数值得你关注。如果打包者允许指定PREFIX=/opt/openssh,那么二进制会被安装到独立目录,和系统自带的 OpenSSH 并存。这时候要注意sshd服务的启动脚本里有没有写对路径,否则你重启服务后可能还是旧版在监听,新版本成了摆设。我见过有人把新 sshd 装到 /opt 后忘了改 service 文件,结果白忙活一场。

5.2 批量离线升级:给 20 台机器统一安装

当你有十几台同系统版本的服务器时,逐台执行 install.sh 不现实。我一般把包传到内网 HTTP 源或本地仓库,然后用 shell 循环批量执行:

for host in server01 server02 server03; do scp rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64.tar.gz root@${host}:/tmp/ ssh root@${host} "cd /tmp && tar -xzf rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64.tar.gz && cd rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64 && sh install.sh" done

这个循环有三个风险:其一,scp过程中如果网络抖动,脚本会断在中间,所以最好先传包再循环执行;其二,install.sh里的systemctl restart sshd会断开这条执行链,导致后面的done循环没法继续。解决办法是让 ssh 执行命令时脱离终端并记录日志:

ssh root@${host} "nohup sh -c 'cd /tmp/... && sh install.sh' > /tmp/upgrade_ssh.log 2>&1 &"

这样即使 sshd 重启断开了 ssh 通道,远端命令仍然会在 nohup 的守护下继续跑完。验证阶段再重新连上去检查/tmp/upgrade_ssh.log和ssh -V。

另一个更可控的方案是把 install.sh 拆成 install_rpm.sh 和 restart_sshd.sh 两步,先用 rpm 装完所有包,不重启 sshd,等全部节点都装完再统一重启。这样即使某台机器配置有问题,也不会影响批量执行。如果你会 Ansible,可以写成两个 play:第一个拷贝并安装 rpm,第二个用async和poll来跑systemctl restart sshd,避免连接中断导致任务卡死。

5.3 升级失败或出问题后的回滚路径

回滚必须依赖之前备份的 rpm 包。如果你按照 3.1 节保存了old_rpm_list.txt中的每个 rpm 文件,回滚命令是这样的:

rpm -Uvh --oldpackage /root/ssh_bak_$(date +%F)/old_rpms/openssh-*.rpm

--oldpackage允许把当前版本降级到旧版本。但要注意:如果新包安装时动了/etc/ssh/sshd_config,即使 rpm 回滚,文件也可能不会自动还原。所以在回滚前要把备份目录里的ssh_config_etc恢复覆盖:

cp -a /root/ssh_bak_$(date +%F)/ssh_config_etc/. /etc/ssh/ restorecon -Rv /etc/ssh systemctl restart sshd

回滚还有一个隐含坑:OpenSSL 版本如果是后装的,先回滚 OpenSSH 到旧版,再回滚 OpenSSL。如果顺序反了,旧版 OpenSSH 可能认不得新版 OpenSSL 的 API,继续报错。我的习惯是在回滚完成后第一时间ssh -V确认两个版本都回到了升级前的组合,然后跑一遍业务侧的 SSH 连接测试,而不是只看服务状态。

如果连 rpm 文件都没备份,回滚就只有一条路:从系统的安装光盘或你配置的 yum 源里重装系统自带的 openssh 和 openssl。方法是在yum install时指定版本:

yum install -y openssh-server-8.7p1-xxx.el9.x86_64

但这样会把配置重置,且版本号可能对不上。所以备份变量这步我从来不会省。

6. 升级后的验证清单:三天内我建议你盯住这几个指标

升级完成不等于事情结束,我一般会强制观察三个窗口:1 小时内、24 小时内、3 天内。下面的清单是我固定要过的:

时间窗口检查项命令/方法
1 小时sshd 进程是否持续存活watch -n 60 'systemctl is-active sshd'
1 小时新版本二进制是否真的在跑ps -ef | grep sshd看完整路径
24 小时是否出现 PAM 认证失败日志journalctl -u sshd -p err --since today
24 小时证书登录和密码登录都测一次从客户端用两种方式分别连
3 天依赖 OpenSSL 的服务日志有无异动grep -i "libssl|libcrypto" /var/log/messages

还有一个具体技巧:用ssh -Q列出新版本支持的算法,再对比客户端ssh -Q的输出,能提前定位算法不匹配问题。比如上面提到的ssh -Q kexalgorithms,如果服务端输出里没有diffie-hellman-group14-sha1,而客户端还在用旧选项,那就得在服务端追加兼容配置。这个检查我一般放在升级后第一个小时,因为很多用户会在上班后反馈。

最后说一说习惯问题。我自己的教训来自第一次用一键包升级。当时图快,没备份 host key,结果升级脚本把/etc/ssh/ssh_host_*重写了,第二天所有开发同学的 known_hosts 告警,找了我一上午。从那以后我每次升级前都会强制走一遍备份、开备用会话、sshd -t三件事,再把脚本里的rm命令逐条过目。这个习惯救过我至少两次——一次是配置文件被覆盖,一次是 OpenSSL 库冲突导致 Nginx 起不来。希望帮到你,少踩我踩过的坑。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进