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 修复升级至 10.0p1同时把 SSL 库升级至 3.5.1可有效修补旧版组件中的已知漏洞。资源共 4 个文件其中 3 个为 RPM 安装包分别用于安装 OpenSSH 服务端、客户端以及核心命令工具另一个是一键执行的 Shell 加固脚本压缩包大小约 20.42MB方便在离线环境快速部署。该方案尤其适用于内网资产批量升级、需满足等保合规要求或对远程管理安全性要求较高的服务器环境通过脚本化执行可降低手动升级导致的版本冲突和配置遗漏问题。脚本兼顾升级与加固除了自动替换新版软件外还会引导用户检查远程登录配置比如是否禁止空密码、是否关闭 root 直接登录、是否设置空闲超时这类安全基线调整能显著减少被入侵的风险同时提示在操作前备份原有配置文件避免自定义参数丢失。已有 140 人学习下载适合希望掌握 CentOS 7.9 安全升级完整流程并想从脚本中学习排错思路的系统管理员与学习者。1. 为什么 CentOS 7.9 的 SSH 必须升级到 10.0p1等保审计和漏扫都盯着这里CentOS 7.9 自带的是 OpenSSH 7.4p1 和 OpenSSL 1.0.2k这个组合在现在的等保测评和漏洞扫描里几乎就是送分题用户名枚举、CVE 列表一串一串aws 和阿里云基线检查也会直接标红。我拿到的这套 centos7.9-ssh10.0p1-ssl3.5.1-rpm-x86-64 升级加固脚本核心就是干一件事在不重装系统、不折腾 yum 源的前提下把 OpenSSH 升到 10.0p1、OpenSSL 升到 3.5.1并打包成 x86_64 的 RPM再顺手把 sshd_config 加固到能过常见安全基线。适合被漏扫逼着升级的中年服务器也适合刚接手一堆 CentOS 7.9 存量机器、又不想一台台手动编译的运维。这套脚本比较实在的地方是它把 OpenSSL 3.5.1 装到独立目录不去动系统自带的 1.0.2k这样 yum 和 curl 这些依赖旧库的组件不会跟着翻车。下面我按“构建 RPM → 部署升级 → 加固配置 → 踩坑复盘 → 验证落地”的顺序把整个流程拆开讲包括每一步的命令、参数和容易出问题的地方。2. 本地构建 RPM从源码到 OpenSSH 10.0p1 安装包的关键路径2.1 构建环境与依赖准备为什么不用 make install很多人拿到源码第一反应是./configure make make install在一台服务器上这么干确实快但后续想统一分发、卸载、回滚就麻烦了。用 RPM 的好处是依赖关系明确、升级记录可控、卸载时不会漏文件而且可以在构建机打一次包之后直接往生产机rpm -Uvh。这套升级加固脚本的做法就是先构建 RPM所以第一步是准备构建环境。构建机最好和生产机同版本CentOS 7.9 x86_64内存 2G 以上磁盘剩余 10G 左右。需要安装基础工具链和编译依赖执行下面的命令yum install -y gcc make rpm-build rpmdevtools \ zlib-devel pam-devel libselinux-devel \ perl-core krb5-devel这里每个包都有具体用途zlib-devel是--with-zlib需要pam-devel用来支持 PAM 认证libselinux-devel让 sshd 能带 SELinux 上下文工作perl-core是 OpenSSH 源码里跑测试脚本用的。不装这些后面rpmbuild会直接在%build阶段报缺头文件不要等到失败才回头补。构建 CentOS 7.9 能用的 OpenSSH 10.0p1最大的依赖问题是系统自带的openssl-devel是 1.0.2k而 OpenSSH 10.0p1 需要 OpenSSL 1.1.1 以上。解决方案不是去升级系统库而是把 OpenSSL 3.5.1 独立编译安装到/opt/ssl351再让 OpenSSH 编译时通过--with-ssl-dir指过去。2.2 先编译 OpenSSL 3.5.1独立前缀避免搞崩 yum这一步是整个升级里最核心的“后悔药”设计。如果你直接把 OpenSSL 3.5.1 编译安装到/usr/local/lib64或者覆盖/usr/lib64/libssl.so.10大概率会出现系统里 yum、curl、wget 全部报SSL routines错误的情况。套件资源给的思路是OpenSSL 和 OpenSSH 都做成 RPM但 OpenSSL 固定装在/opt/ssl351不影响系统原有 OpenSSL。cd /usr/local/src tar xzf openssl-3.5.1.tar.gz cd openssl-3.5.1 ./config \ --prefix/opt/ssl351 \ --openssldir/opt/ssl351 \ shared \ -fPIC \ zlib make -j$(nproc) make install参数说明--prefix/opt/ssl351指定独立安装目录等于给 OpenSSL 3.5.1 建了一个“沙箱”shared生成动态库libssl.so.3和libcrypto.so.3OpenSSH 的 sshd 会动态链接它们-fPIC是编译共享库的必须参数zlib开启压缩支持。我这里建议在make install之前先跑一遍make test。OpenSSL 源码的测试比较耗时但能提前发现编译器版本、平台兼容问题。如果构建机性能差可以只跑make test TESTStest_version这种轻量测试或者直接信任官方 tarball。资源脚本里一般默认跳过完整测试但你自己的构建机上别省这一步。2.3 编写 openssh.spec版本号、依赖与 %files 清单构建 RPM 必须有 spec 文件。OpenSSH 10.0p1 的源码包解压后目录名是openssh-10.0p1所以 spec 里的Version直接写10.0p1。RPM 规范允许字母在版本号里只要没有连字符就行。mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} cp openssh-10.0p1.tar.gz ~/rpmbuild/SOURCES/ vi ~/rpmbuild/SPECS/openssh.specspec 文件核心片段如下注意%prep、%build、%install三段的分工Name: openssh Version: 10.0p1 Release: 1%{?dist} Summary: OpenSSH 10.0p1 upgrade package for CentOS 7.9 License: BSD BuildRequires: gcc, make, zlib-devel, pam-devel, libselinux-devel Requires: pam, zlib, openssl %description OpenSSH 10.0p1 built with OpenSSL 3.5.1. %prep %setup -q -n openssh-%{version} %build ./configure \ --prefix/usr \ --sysconfdir/etc/ssh \ --with-ssl-dir/opt/ssl351 \ --with-pam \ --with-zlib \ --with-selinux make -j%{_smp_mflags} %install make install DESTDIR%{buildroot} %files /usr/bin/ssh /usr/bin/scp /usr/bin/sftp /usr/sbin/sshd /etc/ssh/ssh_config /etc/ssh/sshd_config /usr/lib/systemd/system/sshd.service %attr(0755,root,root) /usr/libexec/openssh/sftp-server ...说明几个容易踩的点--prefix/usr是为了让二进制落到标准路径否则你升级完会发现ssh在/usr/local/bin而系统里原来的/usr/bin/ssh还是旧的--sysconfdir/etc/ssh保证配置目录不变避免别人找不到sshd_config--with-ssl-dir/opt/ssl351是让编译器和链接器优先用新 OpenSSL。%files清单必须写全make install安装的文件如果没被声明rpmbuild会报Unpackaged files错误。资源脚本里这份清单是已经写好的你不需要自己一个个补但理解它存在很重要。2.4 执行 rpmbuild常见宏与产物验证spec 写好后执行构建。CentOS 7 的%{dist}宏默认是.el7但有时构建环境里没定义所以建议显式传一下避免意外报错。cd ~/rpmbuild rpmbuild -bb --define dist .el7 SPECS/openssh.spec构建完成后产物在~/rpmbuild/RPMS/x86_64/下名字类似openssh-10.0p1-1.el7.x86_64.rpm。不要急着拿去生产机先用rpm -qpi和rpm -qpR检查包信息和依赖确认它确实链接的是新版本 OpenSSL。rpm -qpi ~/rpmbuild/RPMS/x86_64/openssh-10.0p1-1.el7.x86_64.rpm rpm -qpR ~/rpmbuild/RPMS/x86_64/openssh-10.0p1-1.el7.x86_64.rpmqpR输出里如果看到libcrypto.so.3()和libssl.so.3()说明这个包构建时确实依赖 OpenSSL 3.5.1。安装前你要么在目标机上也装一个 OpenSSL 3.5.1 的 RPM要么把/opt/ssl351/lib完整拷过去否则ldd /usr/sbin/sshd会缺库。这套升级脚本内部已经把这些依赖顺序处理好了如果你是自己手动打包记住“先装 SSL 包再装 SSH 包”这个顺序别倒过来。3. 一键升级部署升级加固脚本的执行流程与回滚机制3.1 安装前检查存量版本、备份目录、作业现场保护拿到这套资源后建议先在生产机上的业务低谷窗口操作不要在白天业务高峰直接跑。脚本第一段会做环境自检逻辑相当于下面的命令if ! grep -q CentOS Linux release 7.9 /etc/redhat-release; then echo Only CentOS 7.9 is supported exit 1 fi SSH_OLD$(rpm -q openssh --qf %{VERSION} 2/dev/null) if [ $SSH_OLD 10.0p1 ]; then echo OpenSSH is already at 10.0p1, skip upgrade exit 0 fi mkdir -p /opt/ssh_upgrade_backup_$(date %Y%m%d%H%M)这段检查的意义防止重复升级也防止你手滑把脚本跑到 CentOS 8 Stream 或者别的系统上。CentOS 7.9 的/etc/redhat-release内容比较固定直接 grep 就行。如果你有自定义的/etc/redhat-release记得先确认正则匹配。接下来是关键备份。升级前必须把/etc/ssh完整复制一份同时备份现存的 OpenSSH 包信息以便回滚BACKUP_DIR/opt/ssh_upgrade_backup_$(date %Y%m%d%H%M) cp -a /etc/ssh $BACKUP_DIR/etc_ssh rpm -qa | grep -E ^openssh $BACKUP_DIR/rpm_list.txt # 保留旧二进制紧急时直接拷回 /usr/bin 和 /usr/sbin mkdir -p $BACKUP_DIR/old_bin cp -a /usr/bin/ssh $BACKUP_DIR/old_bin/ 2/dev/null cp -a /usr/sbin/sshd $BACKUP_DIR/old_bin/ 2/dev/null这里cp -a保留权限和 SELinux 上下文比普通cp更适合备份二进制和配置。很多人在回滚时发现sshd起不来原因就是备份时权限丢了。另外rpm -qa列表里记录的openssh-7.4p1-*版本号是之后找旧 RPM 包的线索。3.2 安装 RPM先 SSL 后 SSH再让 systemd 接管这套资源里通常会包含两个 RPMopenssl-3.5.1-1.el7.x86_64.rpm和openssh-10.0p1-1.el7.x86_64.rpm。手动执行时也必须遵守这个顺序rpm -Uvh /opt/upgrade/openssl-3.5.1-1.el7.x86_64.rpm rpm -Uvh /opt/upgrade/openssh-10.0p1-1.el7.x86_64.rpmrpm -Uvh是升级安装-i是全新安装。这里必须用-U因为系统里已经存在旧版 openssh用-i会报 “already installed”。装完后立即执行 systemd 重载。OpenSSH 的 RPM 会在/usr/lib/systemd/system/sshd.service写入 unit 文件但这个文件只有在daemon-reload之后才会被 systemd 真正识别否则你systemctl restart sshd用的还是旧的 unit 缓存systemctl daemon-reload systemctl enable sshd systemctl restart sshd这里有个细节restart和reload不一样。reload是让 sshd 重新加载配置不中断现有连接restart会先停掉 sshd再启动。升级过程中第一次启动建议用restart因为二进制的版本切换必须重启进程。但之前先执行sshd -t确认新配置没有语法错误/usr/sbin/sshd -t如果这一行没有输出说明配置语法 OK有输出就先把报错解决不要贸然 restart否则很容易把自己锁在门外。3.3 网络会话保护tmux 和备用连接是最后的保命手段升级 SSH 这种事最怕的就是“当前连接断掉新连接又进不来”。我的习惯是强制所有远程升级动作放在 tmux 里跑这个习惯至少救过我两次。操作很简单tmux new -s ssh_upgrade进入 tmux 后再执行升级命令。即使你本地到服务器的网络闪断tmux 里的进程依然继续跑重新tmux attach -t ssh_upgrade就能回到现场。如果 tmux 没装先yum install -y tmux。不用 tmux 的话也可以开两个 SSH 窗口一个执行升级另一个放在那观察但 tmux 更稳。另外升级完成后当前连接还会保持但为了验证新配置最好另开一个 SSH 会话连进来测一下确认没问题再退出老会话。如果新会话连不上不要慌只要老会话还在你就有机会用sshd -t和回滚脚本拯救现场。3.4 回滚机制旧包降级与配置还原脚本里预置了rollback.sh核心逻辑是rpm -Uvh --oldpackage /opt/upgrade/openssh-7.4p1-1.el7.x86_64.rpm cp -a $BACKUP_DIR/etc_ssh/sshd_config /etc/ssh/sshd_config restorecon -Rv /etc/ssh /usr/sbin/sshd /usr/bin/ssh systemctl daemon-reload systemctl restart sshd--oldpackage是 rpm 做降级安装的标准参数允许把高版本替换回低版本。如果你在系统安装光盘或 ISO 里能找到原始的 openssh RPM也可以直接用它。备份目录里的old_bin是最后的应急手段——当 RPM 降级一时找不到包时直接把sshd和ssh二进制拷回/usr/sbin、/usr/bin再chmod 755和restorecon重置 SELinux 标签也能把系统拉起。回滚后同样要跑sshd -t再重启。注意回滚会使你之前做的加固配置失效所以回滚后要重新评估安全策略不要觉得“回到老版本就安全了”。4. 加固配置sshd_config 与 OpenSSL 3.5.1 的安全基线对齐4.1 安全基线对照表等保要求是怎么落地的升级到 OpenSSH 10.0p1 只是第一步漏扫能不能过最终看配置。这套资源里的加固脚本会在安装后自动修改/etc/ssh/sshd_config手动操作时可以对照下面的表格检查每一项配置项推荐值说明Protocol2SSHv1 早就该禁了OpenSSH 10 也默认只走协议 2PermitRootLoginno等保要求禁 root 远程登录用普通用户加 sudoPermitEmptyPasswordsno空密码账户不允许登录PasswordAuthenticationno只保留密钥登录需要先确保公钥已部署PubkeyAuthenticationyes对应上面开启公钥认证MaxAuthTries3限制认证失败次数防爆破ClientAliveInterval300每 300 秒发一次保活探针ClientAliveCountMax2超过 2 次无响应则断开X11Forwardingno业务不需要图形转发时关闭AllowUsersop admin明确允许登录的用户列表白名单思路按照这个表做完典型漏扫的“弱加密算法”“允许 root 登录”“空密码”三大类问题基本都能消掉。注意AllowUsers后写真实用户名不要写root否则和PermitRootLogin no自相矛盾。4.2 sshd_config 加固片段先备份、再改、最后校验直接改配置容易把自己锁在外面所以必须三步走。脚本里一般已经写好逻辑手动操作时如下cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date %Y%m%d) cat /etc/ssh/sshd_config EOF PermitRootLogin no PubkeyAuthentication yes PasswordAuthentication no PermitEmptyPasswords no MaxAuthTries 3 ClientAliveInterval 300 ClientAliveCountMax 2 X11Forwarding no AllowUsers op EOF /usr/sbin/sshd -t如果最后一步sshd -t没有输出再执行systemctl reload sshd。注意这里用reload而不是restart因为配置变更无需重启进程reload可以让现有连接不断开。AllowUsers op这里写的人是op如果你的运维账号不是这个名字务必替换成真实存在的用户名否则所有客户端都会被拒之门外。我见过不少人直接把PasswordAuthentication no一写结果发现生产机没部署任何公钥最终只能让机房同事从带外控制台登录进去救场。所以这里的顺序很重要先部署公钥再关密码认证最后测试密钥登录是否正常。4.3 算法策略Ciphers、MACs、KexAlgorithms 怎么设OpenSSH 10.0p1 本身的默认值已经不差但为了消除 sweet32 这类针对 64 位块大小密码套件的漏扫风险建议显式声明算法列表别用默认值赌扫描器心情。在/etc/ssh/sshd_config加上以下几行Ciphers chacha20-poly1305openssh.com,aes128-ctr,aes192-ctr,aes256-ctr MACs hmac-sha2-256,hmac-sha2-512 KexAlgorithms curve25519-sha256,curve25519-sha256libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521解释一下Ciphers里我只保留 CHACHA20 和 AES-CTR 系列不保留任何 CBC因为 CBC 系列在 SSH 里就是 sweet32 的温床MACs用 SHA-2 系列hmac-sha1也建议去掉KexAlgorithms保留 curve25519 和 NIST P-256/384/521这些都是当前主流客户端能支持的。配置后验证/usr/sbin/sshd -T | grep -Ei ciphers|macs|kexalgorithmssshd -T会把最终生效的配置打印出来而不是只看文件里写了什么。那些没有写在文件里、走默认值的项这里也能看到。这一步是确认“配置真的生效”而不是“配置真的存在”。4.4 OpenSSL 3.5.1 生效验证与 TLS 安全边界OpenSSH 10.0p1 用 OpenSSL 3.5.1但这个“用”不是让 SSH 走 TLS 协议而是让 sshd 调用 OpenSSL 底层的加密算法和随机数生成。所以不要拿openssl s_client去测 sshd 端口那是给 HTTPS 用的测 SSH 没意义。正确验证方式/opt/ssl351/bin/openssl version ldd /usr/sbin/sshd | grep sslldd输出里如果看到类似libssl.so.3 /opt/ssl351/lib/libssl.so.3和libcrypto.so.3 /opt/ssl351/lib/libcrypto.so.3说明 sshd 链接的是新库。如果显示libssl.so.10说明--with-ssl-dir没生效或者安装时缺了/opt/ssl351/lib的查找路径需要设置LD_LIBRARY_PATH/opt/ssl351/lib或安装配套的 openssl RPM。另外提一句 OpenSSL 3.5.1 自带 FIPS 能力但默认不启用。如果你们有国密或等保四级要求需要单独配置 FIPS provider而不是靠这个 RPM 自动搞定。SSH 场景通常不直接依赖 FIPS但你的加密算法列表必须符合国网或金融行业规范时就要在算法选择上额外注意。5. 避坑排查升级 OpenSSH 时最容易翻车的 5 个细节5.1 现象重启后 root 无法登录提示 Permission denied (publickey,password)原因PermitRootLogin no或PasswordAuthentication no已经生效但root的authorized_keys里没有公钥或者你根本没把公钥放进 root 目录。解决如果当前连接还在马上用su -切换到普通用户检查/root/.ssh/authorized_keys权限是否 600、属主是否 root。确认公钥正确后用普通用户测试sudo sshd -t。如果当前连接也断了只能通过带外管理IPMI、云控制台 VNC登录临时把/etc/ssh/sshd_config里这两项改回去重启 sshd重新从普通用户登入后再调整。5.2 现象systemctl restart sshd 后原有连接全部掉线新连接也连不上原因restart会先停掉 sshd 再启动一旦新配置里有绑定失败或监听异常服务就起不来。常见原因包括端口被别的进程占用、ListenAddress写错、或者你改动了Port但没有放行防火墙。解决升级后第一次启动用restart是必要的但在这之前必须用sshd -t做校验。如果已经翻车走控制台把/etc/ssh/sshd_config改回正确的端口和监听地址再执行systemctl stop sshd /usr/sbin/sshd -D -d-D -d会以前台调试模式启动 sshd把日志直接打到屏幕上比看 journalctl 更直接。看到监听成功后CtrlC 停掉再用systemctl start sshd。注意-d会输出验证细节但不代表配置正确最终还是要sshd -T确认。5.3 现象升级后 yum、curl 报错 SSL routines 版本不匹配原因OpenSSL 3.5.1 的库文件覆盖了系统/usr/lib64/libssl.so.10或者新库被放到了系统默认搜索路径里导致 yum 这些依赖旧 OpenSSL 的程序加载到了不兼容的版本。解决这套脚本把 OpenSSL 装在/opt/ssl351就是为了避开这个问题。如果你已经手动覆盖最直接的补救是把系统自带openssl-libs-1.0.2k重新装回去yum reinstall openssl-libs -y如果 yum 本身坏了用rpm -Uvh --force --nodeps从安装盘强制恢复openssl-libs的 RPM。恢复后确认/usr/lib64/libssl.so.10链路正常再检查/opt/ssl351是否还在。记住升级策略OpenSSL 3.5.1 只服务 OpenSSH绝不成为系统默认库。5.4 现象rpmbuild 报错 Missing BuildRequires 或 Unpackaged files原因spec 文件里BuildRequires只声明了 gcc 和 make但 OpenSSH 10.0p1 要链接 pam、zlib、selinux缺了对应的-devel包。另一个高频问题是make install装了一堆文件但%files清单没写全rpmbuild 会把多余文件当成“孤儿文件”并报错。解决先按 2.1 的命令补装pam-devel zlib-devel libselinux-devel perl-core。如果还报缺特定头文件用yum provides */xxx.h查是哪个包提供的装上再看。Unpackaged files的处理方式是把make install安装产生的路径逐一加入%files。你可以临时在 spec 的%install段加一行find %{buildroot} -type f查看全部文件再写清单。资源里已经预置了完整的%files自己写的 spec 可以借鉴它的结构。5.5 现象SELinux 开启时sshd 无法绑定非标准端口或无法启动原因CentOS 7.9 默认 SELinux 为 enforcing而ssh_t域只允许sshd监听ssh_port_t允许的端口22 端口没问题改到 2222 或 22022 就被策略拦截。日志里会看到 AVC denial。解决用semanage把新端口加入ssh_port_tyum install -y policycoreutils-python semanage port -a -t ssh_port_t -p tcp 2222如果要恢复用semanage port -d -t ssh_port_t -p tcp 2222。如果不想动 SELinux也可以把SELINUX临时调成 permissive但这样会让整套加固脚本的“加固”缩水不建议。正确做法是放行端口并保持 enforcing这样漏扫检查 SELinux 状态时你也能交差。6. 升级后的验证清单会用 sshd -T 和 openssl 才算真正落地6.1 版本、监听、配置三件事先确认升级完不要急着退出按下面的命令逐条核对。第一件事是确认二进制版本和动态库来源/usr/sbin/sshd -V 21 /opt/ssl351/bin/openssl version ldd /usr/sbin/sshd | grep ssl ss -tlnp | grep sshdsshd -V会输出 OpenSSH 版本和编译时链接的 OpenSSL 版本如果显示OpenSSL 3.5.1说明新库已经接上。ss -tlnp能看到 sshd 实际监听的地址和端口别只看配置文件。很多翻车现场就是配置里写了端口但进程没监听这时候ss -tlnp一眼就能发现进程退出了。6.2 用 sshd -T 和 ssh -Q 校验算法基线配置是否真正生效靠sshd -T说话/usr/sbin/sshd -T | grep -Ei permitrootlogin|passwordauthentication|ciphers|macs|kexalgorithms再看客户端支持哪些算法用ssh -Q查询ssh -Q cipher ssh -Q mac ssh -Q kex这两组命令结合起来你能知道“服务端允许什么、客户端支持什么”。如果漏扫报某个弱算法去sshd -T输出里找确认它不在Ciphers行里即可。这些输出建议重定向存到/root/ssh_upgrade_report.txt作为审计留痕。6.3 一个习惯把升级动作变成固定四步从那以后我每次升级 OpenSSH都强制自己走一遍“备份旧包 → tmux 保底 → sshd -T 验证 → -T 输出留档”这四步再顺手检查/var/log/secure里有没有新的认证异常。这套升级加固脚本帮我省了不少事也希望这四步能帮你在下次漏扫前少踩几个坑。最后再啰嗦一句升级完成后务必在一周内观察系统日志确认没有依赖老 OpenSSL 的服务悄悄报错有异常就从备份目录回滚别硬扛。希望帮到你。本文还有配套的精品资源点击获取
返回列表