拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CentOS 7.9 OpenSSH 10.0p1 + OpenSSL 3.5.1 rpm升级加固全流程

CentOS 7.9 OpenSSH 10.0p1 + OpenSSL 3.5.1 rpm升级加固全流程

简介:CentOS 7.9 环境下,OpenSSH 与 SSL 库的安全升级一直是运维工作中的重点。面向需要修复 SSH 服务漏洞、提升远程管理安全水平的运维工程师,这份资源提供了一套基于 RPM 的升级加固方案,避免手动编译带来的依赖缺失、版本冲突与回滚困难。压缩包共 4 个文件,包含 3 个 x86_64 的 RPM 安装包(分别对应主程序、服务端与客户端)以及 1 个 Shell 升级脚本,整体大小约 20.42MB。脚本可在 CentOS 7.9 上自动完成 OpenSSH 10.0p1 与 SSL 3.5.1 的安装替换,并支持禁用空密码登录、关闭 root 远程登录、设置空闲超时等加固项,降低系统被非法访问的风险,目前已有 140 人学习、下载。使用这份资源,用户不仅能快速获得可直接安装的 RPM 包和升级脚本,还能从脚本内容中理解旧版本备份、依赖处理、关键配置调整等完整思路,便于在测试环境先行验证后按需二次定制,是一份实用的系统安全加固参考。

1. 为什么 CentOS 7.9 的 OpenSSH 升级加固不能再拖

CentOS 7.9 自带的是 OpenSSH 7.4 和 OpenSSL 1.0.2k,这两个版本在今天的漏扫报告里几乎是“必现高危”:协议算法偏老、密码套件有 Sweet32 风险、一堆公开 CVE 都卡在这两套组件上。标题里的 “centos7.9-ssh10.0p1-ssl3.5.1-rpm-x86-64升级加固脚本”,就是把 OpenSSH 升到 10.0p1、OpenSSL 升到 3.5.1,并用 rpm 包在 x86_64 机器上完成安装和安全加固的一套落地流程。适合被安全整改追着走的运维,也适合刚接手一堆 7.9 老机器、想一次性把 SSH 基线抬高的人。核心价值不只是“把版本号升上去”,而是升级过程中每一步都留验证、留回滚,不把自己锁在门外。

2. 升级前必做的三件事:版本兼容、rpm选择与系统备份

2.1 先确认基线:当前SSH/SSL版本与架构不能靠猜

同一条升级加固脚本,x86_64 和 aarch64 的 rpm 不通用;CentOS 7.9 的不同小版本也可能有不同的编译依赖。所以脚本第一段动作不是安装,而是把现状完整记录成一组基线文件。我一般会在操作前先跑一遍下面的命令:

# 记录系统版本、内核、架构 cat /etc/redhat-release uname -r uname -m # 当前 OpenSSH 与 OpenSSL 版本 ssh -V 2>&1 | tee /tmp/pre_ssh_version.txt openssl version # 当前 sshd 生效配置与主机密钥清单 sshd -T 2>/dev/null | head -n 20 ls -l /etc/ssh/ssh_host_*

这里的 ssh -V 会把版本信息打到 stderr,所以要 2>&1 收一下,tee 同时输出到终端和文件,后面核对升级结果时直接 diff 这个文件。openssl version 如果输出 1.0.2k-fips,说明是系统自带包;如果输出 3.x,说明这台机器已经被别人动过,再跑升级脚本前必须重新评估。还有一个小坑:某些云厂商镜像会预装自己编译的 sshd,rpm -qa openssh 查不到包,但 ssh 命令能用。这种情况必须先用rpm -qa | grep -E "openssh|openssl"确认安装来源,否则后面 rpm -Uvh 很可能会因为包冲突直接失败。

2.2 为什么必须用rpm而不是直接替换二进制

很多人拿到源码第一反应是 make && make install,但这在 SSH 升级上属于“把黑匣子带进运维”:编译安装没有 rpm 元数据,之后卸载、升级、追踪版本全靠猜;编译默认路径又在 /usr/local,和系统自带的 /usr/bin/ssh 共存时,PATH 一变就分不清当前用的是哪个版本。标题里明确给了 rpm 和 x86-64,说明这套方案的目的是用标准 rpm 生命周期管理新旧组件,脚本只负责安装顺序和配置加固,把安装动作交给 rpm 完成。

rpm 方式还有个直接好处:加固后可以跑rpm -V openssh openssl,校验哪些文件被改过、哪些文件权限异常。如果你之前是源码编译,这个验证手段基本是废的。关于升级命令,建议用 rpm -Uvh 而不是 rpm -ivh:-U 在安装新包时会替换旧版本,并把原来的配置保存成 .rpmsave;-ivh 遇到已安装的包会直接报「package already installed」。如果拿到的是 openssh-server、openssh-clients 等多个互相依赖的包,一次rpm -Uvh *.rpm让 rpm 自行处理依赖顺序,比一个个敲要省事。

提示:rpm 是 CentOS 7.9 的包管理基础,相当于 Debian/Ubuntu 里的 apt。如果哪台机器连rpm --version都跑不出来,说明它根本不是标准 yum 环境,这套脚本不能直接用。

2.3 备份与回滚计划:先给自己留后悔药

升级 SSH 最怕的不是失败,是失败后旧版本也不在了,只能跑机房。备份至少要覆盖三层:现有 rpm 包列表、sshd_config 与主机密钥、防火墙和 SELinux 里和 SSH 相关的规则。下面是脚本里建议的最小备份集:

mkdir -p /root/ssh_upgrade_backup/{rpm,etc} rpm -qa | grep -E "openssh|openssl" > /root/ssh_upgrade_backup/rpm/rpm_list.txt cp -a /etc/ssh/sshd_config /root/ssh_upgrade_backup/etc/ cp -a /etc/ssh/ssh_host_* /root/ssh_upgrade_backup/etc/ cp -a /etc/pki/tls/openssl.cnf /root/ssh_upgrade_backup/etc/ 2>/dev/null || true firewall-cmd --list-all > /root/ssh_upgrade_backup/etc/firewall.txt 2>/dev/null ss -tlnp | grep -E ":22 " >> /root/ssh_upgrade_backup/etc/firewall.txt

主机密钥必须备份,因为升级后如果重新生成 host key,所有客户端的 known_hosts 都会失效,ssh 批量登录、git 通过 ssh 认证都会变成“host key verification failed”。ssh_host_* 包括 rsa、ecdsa、ed25519 几套,备份时用 cp -a 保留原始属主和权限。还有一处容易漏:如果 sshd_config 里写了Include /etc/ssh/sshd_config.d/*.conf,这个目录下的片段也要一起备份。备份完后建议把文件列表打印出来确认一下,尤其是 ssh_host_rsa_key 的体积不是 0,否则后面恢复时会踩坑。

3. 把升级加固脚本拆开:从安装到配置的完整流程

3.1 安装顺序:先OpenSSL后OpenSSH,避免动态库错位

OpenSSH 10.0p1 编译时链接的是 OpenSSL 3.x 的 libcrypto.so.3,而 CentOS 7.9 系统自带 OpenSSL 1.0.2k 只有 libcrypto.so.10。如果先装 OpenSSH,sshd 启动时会因为找不到新库直接崩。所以标准动作是先装 OpenSSL 3.5.1,确认新库在位,再装 OpenSSH。但这里有一个关键决策:要不要让新 OpenSSL 直接替换系统自带的软链接?

我的建议是不要。CentOS 7.9 的 yum、curl、python、mysql client 都依赖 1.0.2k 的 libssl.so.10,你把它顶掉,整个基础工具链都会跟着翻车——常见现象是升级后yum list报libcrypto.so.10: cannot open shared object file,pip 也会报ssl support is missing。更稳的做法是让 OpenSSL 3.5.1 以独立目录安装,比如 /usr/local/ssl,OpenSSH 编译时用--with-ssl-dir指过去。这样新旧两套库各管各的,不会互相踩。安装命令的大致形态如下:

# 安装 OpenSSL 3.5.1,假设 rpm 包已经按 /usr/local/ssl 前缀打包 rpm -Uvh /path/to/openssl-3.5.1-1.el7.x86_64.rpm # 确认新动态库与二进制在位 ls -l /usr/local/ssl/lib64/libcrypto.so.3 /usr/local/ssl/bin/openssl version

说明:/usr/local/ssl 是源码编译时 --prefix 的常见值,如果你的 rpm 包不是这个路径,以rpm -ql openssl为准。之所以强调路径,是因为很多网上的“一键升级”rpm 包会把新库直接装进 /usr/lib64,然后软链接覆盖成 libcrypto.so.3,那种包安装后系统立刻出现“yum 坏了、curl 坏了”的现象。所以在安装前一定要检查文件清单,确认新 OpenSSL 没有覆盖系统库。检查命令是:

rpm -qpl openssl-3.5.1-1.el7.x86_64.rpm | grep -E "libcrypto|libssl"

安装 OpenSSH 的步骤类似,同样要注意 rpm 包里 sshd_config 的默认路径是否还是 /etc/ssh/sshd_config,以及是否带了 systemd unit 文件。命令如下:

# 安装 OpenSSH,不覆盖系统旧配置 rpm -Uvh /path/to/openssh-10.0p1-1.el7.x86_64.rpm \ /path/to/openssh-server-10.0p1-1.el7.x86_64.rpm \ /path/to/openssh-clients-10.0p1-1.el7.x86_64.rpm

说明:rpm -Uvh 在替换旧包时,会把旧配置文件改名成 .rpmsave。升级后第一件事就是检查 /etc/ssh/sshd_config.rpmsave,把里面自定义的端口、AllowUsers 等内容手动迁移到新配置里,不能指望 rpm 自动合并。OpenSSH 从 8.x 开始默认算法持续收窄,旧配置里的一些 AllowTcpForwarding、UseDNS 写法虽然还在,但语义可能有变化,直接硬覆盖进新配置可能让 sshd 拒绝启动。

3.2 加固sshd_config:协议、密钥、算法、登录策略一次配齐

升级后的默认 sshd_config 通常已经比旧版安全,但距离等保和漏扫要求还差几步。我习惯把加固项单独写到 /etc/ssh/sshd_config.d/hardening.conf,而不是直接改主配置,这样以后再来一轮安全整改时,只需要替换这一个文件。前提是主配置里要有Include /etc/ssh/sshd_config.d/*.conf一行,CentOS 7.9 的默认配置已经有这行了,但如果你手工改过主配置,需要确认一下。

cat > /etc/ssh/sshd_config.d/hardening.conf <<'EOF' # 主机密钥只保留 RSA/ECDSA/Ed25519,禁用 DSA HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_ecdsa_key HostKey /etc/ssh/ssh_host_ed25519_key # 登录策略:公钥认证优先,禁止空密码 PermitRootLogin prohibit-password PubkeyAuthentication yes PasswordAuthentication no PermitEmptyPasswords no # 密钥交换与加密算法:去掉 SHA1 和弱曲线 KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512 Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com # 连接超时与爆破防护 MaxAuthTries 3 LoginGraceTime 30 ClientAliveInterval 300 ClientAliveCountMax 2 # 转发控制:除非确有必要,全关 AllowTcpForwarding no AllowAgentForwarding no X11Forwarding no EOF

参数说明:PermitRootLogin 我这里写的是 prohibit-password,意思是 root 允许登录,但只能通过密钥,密码完全不能进。如果你是内部跳板机加上严格 ACL,可以再收紧成 no。MaxAuthTries 3 和 LoginGraceTime 30 是扫描器判定暴力破解防护是否到位的两个关键项。ClientAliveInterval 300 配合 ClientAliveCountMax 2,能在客户端“假死”时自动断开连接,避免系统里挂一堆空闲 sshd 进程。很多人在 vscode 里设置“连接 ssh 远程服务器后十分钟不用就断线”,其实就是服务端这两个值没配对到预期效果。

算法这一排很容易引发“配了强算法结果连不上”的争议。KexAlgorithms 只保留 curve25519 和 diffie-hellman-group16/18,老客户端如果只支持 group14,协商就会失败。Ciphers 去掉 aes128-cbc、3des-cbc,是为了规避 Sweet32 这类针对 64 位块大小密码套件的碰撞攻击。如果你环境里有老堡垒机或老网络设备,建议把 diffie-hellman-group14-sha256 也加回来,作为管理网段的降级兜底。这个稍后在避坑部分详细说。

3.3 端口与SELinux:改端口不是改一行配置的事

升级到 10.0p1 后,把 SSH 端口从 22 改为高位端口是常见的加固动作,能降低被批量扫描的概率。但只改 sshd_config 里的 Port 是不够的,至少要同步处理三件事:sshd_config 的监听端口、firewalld 防火墙放行、SELinux 的端口标签。前两者漏掉,端口不通;SELinux 漏掉,sshd 可能“看起来启动成功”,但连接直接被拒绝。下面是脚本里这一段的典型写法:

# 修改配置里的端口,这里以 22022 为例 sed -i 's/^#Port 22/Port 22022/' /etc/ssh/sshd_config.d/hardening.conf # firewalld 放行新端口,并移除默认 ssh 服务 firewall-cmd --permanent --add-port=22022/tcp firewall-cmd --permanent --remove-service=ssh firewall-cmd --reload # SELinux 放行 SSH 新端口 semanage port -a -t ssh_port_t -p tcp 22022

参数说明:semanage 来自 policycoreutils-python 包,CentOS 7.9 默认可能没装,缺的话先yum install -y policycoreutils-python。改完端口后,要同时检查云控制台的安全组、内网的 iptables 规则,否则本地放行了云上没放行,一样连不上。改端口还会影响已有的 ssh 批量登录任务和 git remote 配置,所有地方都要同步更新端口号。否则会出现“ssh 认证失败 git 突然开始报错”这种看起来像密钥坏了、实际是端口没改的乌龙。

4. 升级后验证清单:服务可起、算法生效、远程能连

4.1 服务与端口验证:systemctl 和 ssh -V 双确认

升级完不能只看 rpm -qa 里有新版本就认为成功,必须验证 sshd 能持续运行。我的顺序是:先跑配置语法检查,再在前台用 debug 模式启动一两次,最后才交给 systemd 重启。注意新版 sshd 的-t只能检查语法,检查不了 SELinux 上下文和密钥权限,这些要在服务真正启动时才暴露。

# 配置语法检查 /usr/sbin/sshd -t # 前台 debug 模式:看到监听端口和 host key 加载成功后 Ctrl+C /usr/sbin/sshd -ddd -p 22022 # 交回 systemd systemctl restart sshd systemctl status sshd --no-pager # 版本确认 ssh -V openssl version ls -l /usr/local/ssl/lib64/libcrypto.so.3

说明:sshd -ddd 会把每一次密钥交换、每一个 host key 加载都打印到终端,能直接判断是配置问题还是依赖库问题。ssh -V 的输出里会有 OpenSSH_10.0p1 和 OpenSSL 3.5.1 这样的字段。如果 ssh -V 显示 OpenSSL 还是 1.0.2,说明 sshd 并没有链接新的 libcrypto,需要再执行ldd /usr/sbin/sshd | grep ssl确认。这是升级后最容易被忽略的“版本显示已到位,实际没生效”问题。

4.2 算法协商验证:用 ssh -vvv 看Kex和Ciphers

配置了强算法后,最担心的不是配置本身,而是“配置了但没被读取”。验证算法是否生效,我喜欢用另一台机器发起一次 ssh -vvv,直接看协商过程里最终选中的密钥交换、哈希和加密算法。命令如下:

# 在另一台机器上执行,观察协商中实际使用的算法 ssh -vvv -p 22022 root@<目标机器> 2>&1 | grep -E "KEX|host key|kex_parse|Ciphers|MACs"

grep 输出里如果有你配置里没出现的算法,说明 sshd 没读到 hardening.conf,或者配置片段被主配置里的后面项覆盖了。常见的覆盖来源有两个:一是 sshd_config 主文件中存在另外的 KexAlgorithms/Ciphers/MACs 行;二是 Include 语句放在了主文件的末尾,但后面还有别的子文件被加载。检查方法:

grep -nE "Include|KexAlgorithms|Ciphers|MACs" /etc/ssh/sshd_config

另外,OpenSSH 10.0p1 自带了ssh -Q kexalgorithms、ssh -Q ciphers、ssh -Q macs这三个查询命令,可以用它直接列出当前二进制支持的算法全集。这个全集比配置里列出的要多,属于正常现象,不用担心。升级后如果机器上还跑着 nginx、nacos 这类需要配置 ssl 证书的中间件,也要顺手检查一遍它们的 SSL 库链接,特别是新版本 OpenSSL 的证书校验策略和旧版有差异,可能出现“openssl 升级后 ssl 连接错误”的情况。

4.3 重启不掉线的技巧:tmux + 安全会话

升级和重启 sshd 最怕的是当前连接断掉。实际上重启 sshd 通常不会切断已有连接,因为旧进程会继续服务已建立的会话;但如果你同时改了端口、禁用了密码登录、重建了 host key,当前连接也可能被波及。我的铁律是:所有修改 sshd 的步骤都放在 tmux 会话里执行,并且提前把备用密钥放到另一台机器上。

# 当前连接里开一个 tmux 会话 tmux new -s ssh_upgrade # 如果连接意外断开,重新登录后在任意终端恢复会话 tmux attach -t ssh_upgrade

提示:在使用 tmux 的基础上,还要确保手里至少有两把能登录的密钥:一把留在本地,一把放到内网跳板机或另一台管理机。血泪教训是:在 hardening.conf 里把 PasswordAuthentication 设为 no 后,突然发现自己唯一的私钥权限不对,密码登录又被禁用,整台机器只剩控制台一条路。

5. 避坑:升级OpenSSH时最常见的5个翻车现场

5.1 升级 OpenSSL 后 yum 报错:libcrypto.so.10 不见了

现象:执行 rpm -Uvh openssl-3.5.1 后,再跑 yum list 直接报python: error while loading shared libraries: libcrypto.so.10: cannot open shared object file,curl、wget 也一起失效。

原因:新 OpenSSL 的 rpm 包把 libcrypto.so.3 装进了 /usr/lib64,并在安装时替换或删除了系统原有的 libcrypto.so.10 软链接。CentOS 7.9 的 python、yum、curl 都链接旧库,所以整个基础工具链立刻崩掉。更麻烦的是,有些 rpm 包为了“兼容”,安装时直接覆盖了系统软链接,让你以为新旧共存,其实旧的已经没了。

解决:如果新 OpenSSL 已经污染了系统库,先用备份的旧 rpm 包强制恢复:

rpm -Uvh --replacepkgs --oldpackage /root/ssh_upgrade_backup/rpm/openssl-1.0.2k-*.rpm

这里的关键参数是 --oldpackage,允许用旧版本覆盖新版本,否则 rpm 会提示“已安装更新版本”。恢复后确认openssl version回到 1.0.2k,再重新把新 OpenSSL 以独立目录方式安装。正确的安装方式可以避免这个坑:装新包前用rpm -qpl检查文件路径,确认新库进入 /usr/local/ssl 而不是 /usr/lib64。如果机器上还跑着 mysql、dify 这类依赖 SSL 的服务,升级后也要重点看它们链接的是哪个 libssl,避免“mysql ssl 连接错误”这类连锁故障。

5.2 sshd 重启后连接被拒绝:主机密钥权限与上下文

现象:systemctl restart sshd 状态显示 active,但远程连接时报no hostkeys available,或者 ssh 客户端提示 host key verification failed。用 sshd -t 检查却没有输出错误。

原因:旧主机密钥从备份目录恢复后,权限可能变成了 0644,或者 SELinux 上下文因为文件被移动而丢失。新版 OpenSSH 对 host key 文件权限检查很严格,要求 0600 且属主是 root。SELinux 开启时,文件上下文必须是 sshd_key_t,否则 sshd 在读取阶段就会被拒绝。

解决:恢复密钥后统一刷权限和上下文:

chmod 600 /etc/ssh/ssh_host_* chown root:root /etc/ssh/ssh_host_* restorecon -Rv /etc/ssh systemctl restart sshd

如果主机密钥备份缺失,最简单是删掉旧密钥让 sshd 自动重新生成,但这样所有客户端的 known_hosts 都要重建。注意:新生成的密钥默认会包含 ed25519,老客户端如果只支持 RSA,需要确认 rsa host key 仍在 /etc/ssh 下,否则老客户端会连接失败。

5.3 密码登录被禁但密钥又没配对:血泪教训

现象:加固配置里写了 PasswordAuthentication no,重载后密码登录全部失败,密钥登录也失败,提示 Permission denied。用 ssh -vvv 能看到服务端接受了公钥,但客户端始终过不了认证。

原因:多数情况下是客户端私钥权限太宽松。OpenSSH 7.8 之后开始检查私钥文件权限,如果 ~/.ssh/id_rsa 是 0644,会直接拒绝使用。服务端配置没问题,但客户端私钥不合法导致认证中断。还有一种可能:known_hosts 里的旧 host key 和新 key 不匹配,客户端在确认新 host key 时中断,看起来像认证失败。

解决:在客户端上先修正私钥权限,再清理旧 host key:

chmod 600 ~/.ssh/id_rsa ssh-keygen -R "<目标机器IP>" -p 22022 2>/dev/null || true ssh -p 22022 root@<目标机器IP>

这里的 -R 是移除旧 host key,下一次连接时会弹出新 key 确认。如果你用的是 pssh、ansible 这类批量登录工具,也要同步检查它们使用的私钥路径和权限。这个坑在升级后“ssh 认证失败 git”的场景里尤其常见——git 操作看着是密钥失效,实际是私钥权限或 host key 不匹配。

5.4 配置了强算法却发现客户端连不上:兼容性边界

现象:KexAlgorithms 和 Ciphers 收紧后,老客户端直接报no matching key exchange method found,或no matching cipher found。

原因:Xshell、PuTTY 旧版本,以及老系统的 OpenSSH 7.3 等只支持 diffie-hellman-group14-sha1、aes128-cbc 这类已经被禁用的弱算法。安全加固把弱算法全禁掉,老工具自然协商失败。

解决:从安全角度,可以保留一组降级算法,但限制来源网段。用 Match Address 指令把弱算法只开放给管理网段,这样全局不暴露弱算法,内网老工具又能正常连:

cat >> /etc/ssh/sshd_config.d/hardening.conf <<'EOF' Match Address 192.168.0.0/16 KexAlgorithms +diffie-hellman-group14-sha256 Ciphers +aes128-ctr,aes192-ctr,aes256-ctr EOF

参数说明:行首的 + 号表示在全局配置基础上追加,而不是替换。如果你的合规要求是全段都不能出现弱算法,就只能强制客户端升级,或者用 ssh -o KexAlgorithms=... 在客户端手工指定算法。这个坑提醒我们:任何加固粒度都要先把“能连”作为第一优先级,再谈强弱。

5.5 SELinux 拦截新端口:sshd 起不来却看不到报错

现象:把端口改到 22022 后,systemctl status sshd 显示 active,但客户端始终连接不上。journalctl -u sshd 也没有明显错误。

原因:SELinux 强制模式下,sshd 只被允许监听带有 ssh_port_t 标签的端口。新端口没有打标签,SELinux 会静默拦截,systemd 层面却认为服务已启动。查看ausearch -m avc -ts recent能看到 AVC denial。

解决:用 semanage 把新端口加入 ssh_port_t:

semanage port -l | grep ssh_port_t semanage port -a -t ssh_port_t -p tcp 22022

注意:如果机器上没有 semanage,很多人会直接setenforce 0关闭 SELinux。这是为了修一条规则把整堵墙拆了,不推荐。正确做法是安装 policycoreutils-python,只补加一条端口规则。改完端口后还要记得在云安全组里同步放行,否则本地规则加好了,远端云平台没放行,依然连不上。

6. 收尾:做一个一键回滚脚本,把升级失败的成本降到最低

升级到这里基本完成,但真正让运维敢在生产环境执行的,是留一条退路。我习惯在脚本最后自动生成一个 rollback.sh,内容不复杂,但能救急:备份目录里留着一整套旧 rpm,回滚脚本只需要停掉新版本、恢复旧 rpm 和旧配置。

cat > /root/ssh_upgrade_backup/rollback.sh <<'EOF' #!/bin/bash # 回滚脚本:升级后无法连接或服务异常时应急恢复 set -e BACKUP=/root/ssh_upgrade_backup echo ">>> 停止新版 sshd,防止旧包恢复后被新进程占用" systemctl stop sshd systemctl disable sshd 2>/dev/null || true echo ">>> 用旧 rpm 包降级回恢复" rpm -Uvh --replacepkgs --oldpackage \ $BACKUP/rpm/openssl-*.rpm \ $BACKUP/rpm/openssh-*.rpm 2>/dev/null || { echo "rpm 恢复失败,请从原始介质补齐旧包" exit 1 } echo ">>> 恢复 sshd_config 与主机密钥" cp -a $BACKUP/etc/sshd_config /etc/ssh/sshd_config cp -a $BACKUP/etc/ssh_host_* /etc/ssh/ restorecon -Rv /etc/ssh 2>/dev/null echo ">>> 清理新端口防火墙与 SELinux 规则" firewall-cmd --permanent --remove-port=22022/tcp 2>/dev/null || true systemctl restart firewalld 2>/dev/null || true echo ">>> 启动旧版 sshd" systemctl enable sshd systemctl start sshd ss -tlnp | grep -E ":22 " || echo "22 端口未监听,请手动检查" EOF chmod +x /root/ssh_upgrade_backup/rollback.sh

这个脚本里最关键的是 --oldpackage,它允许旧版本 rpm 覆盖新版本,否则 rpm 会拒绝降级。备份目录里如果没有完整保留旧 rpm 包,回滚就是空话。我自己的习惯是:每次升级完,先检查回滚脚本里的端口号是否匹配,再把整个备份目录压缩成 tar 包扔到内网独立存储上。真出事时,我宁可多花五分钟回滚,也绝不现场去看“为什么 sshd 起不来”。这套流程走过几次之后,回滚脚本在我心里的优先级早就超过了升级脚本本身。希望帮到你。

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

返回列表