
简介统信UOS操作系统aarch64架构下的OpenSSH 9.6p1升级安装包专为统信UEL20-aarch64版本的运维场景打造。面向系统运维与安全管理人员这份资源用于解决统信UOS系统中OpenSSH版本过低所引入的安全风险支持将低于9.6p1的版本一键升级至9.6p1尤其适合内网离线环境或需要批量维护的服务器集群也可作为安全合规整改时的标准升级方案。资源包体积仅1.5MB总共包含4个文件三个RPM安装包分别对应OpenSSH主程序、客户端和服务端可直接使用rpm命令安装另附一个自动升级脚本用于统一执行升级流程并降低操作门槛。整个包体结构清晰便于运维人员快速理解与使用。目前已有1277人学习/下载使用该资源能够避开源码编译的复杂依赖在离线环境中快速完成OpenSSH安全加固减少运维时间成本同时规避因手工编译可能产生的兼容性问题。 先说个背景最近在运维一批统信UOS的aarch64机器时安全扫描报告把OpenSSH版本问题标成了高危要求限期整改。我一看系统里OpenSSH还停留在非常老的版本而统信UOS软件源里的openssh更新滞后网上能找到的现成rpm包又基本都是x86_64架构aarch64根本装不上。当场编译虽然能跑通但几十台机器挨个编译、维护、回滚想想都头疼。最后我决定直接在统信UOS的aarch64环境上自制OpenSSH 9.6p1的rpm安装包走rpm统一升级路线。这篇文章不绕弯子就把整个流程写透从为什么非要自己做rpm包到环境准备、spec编写、rpmbuild打包、升级安装再到升级后踩过的几个坑一一列出来。如果你也在折腾统信UOS、麒麟这类国产系统或者手里是鲲鹏、飞腾等aarch64设备这篇应该能帮你省下不少时间。1. 为什么绕一大圈做rpm而不是现场源码编译1.1 扫描报告和官方源之间的尴尬安全扫描器报的CVE不会管你的操作系统源里有没有新版它们只认版本号和漏洞库。统信UOS作为国产操作系统软件仓库里的OpenSSH版本更新节奏通常落后于上游尤其是涉及安全版本时往往等不到官方源同步。你这边被监管或内部安全团队催着整改那边源里还是老版本最直接的办法就是自己动手。OpenSSH 9.6p1这个版本修复了不少已知问题而且对旧算法和密钥类型的限制更严格属于值得升级的维护版本。但问题在于aarch64架构下想找一个编译好的现成rpm包并不容易能找到的很多还是针对x86_64的放到aarch64机器上直接就是“软件包架构不匹配”。1.2 源码编译在现场批量执行时的失控感源码编译的流程本身不复杂configure make make install就完事。可放到生产环境批量交付时问题就来了每台机器都要装一套完整的编译工具链包括gcc、make、openssl-devel等这些包本身就要占用磁盘和时间。编译过程依赖系统当前环境同一份源码在不同机器上可能因为依赖库版本差异编出不同的行为。最关键的是编译安装的文件不在rpm数据库里。以后想卸载、想回滚、想查“这个文件是哪个包提供的”全都查不到rpm -q openssh看到的还是旧版本但实际上二进制已经变了这种“版本漂移”状态在运维上是很大的隐患。自制rpm包则能把所有文件纳入rpm管理统一走yum/dnf或rpm命令交付卸载和回滚都非常干净。对需要批量运维的场景来说这个优势是源码编译完全比不了的。1.3 aarch64环境下“现成包”很难捡有人可能会说CentOS、Ubuntu源里不是有编译好的OpenSSH吗问题在于统信UOS走的是自己的底座源里不一定有你想要的版本而RHEL系的aarch64 rpm包也不能直接拿到UOS上装依赖库的路径和版本未必对得上。更重要的是OpenSSH的编译需要和系统的PAM、SELinux、LDAP等模块深度集成别人编好的包不一定带上了你要用的特性。自己构建虽然麻烦但可以精确控制configure参数最终得到的rpm包是符合本机环境的。所以我最终选择直接在aarch64的统信UOS机器上打包而不是在x86_64上做交叉编译——交叉编译rpm需要额外配置一堆工具链在国产系统上坑非常多不如目标机器上直接编译来得稳。2. 打包前的环境准备工具链和依赖一个都不能少2.1 先确认架构和现有OpenSSH版本动手之前先摸清目标机器的底细。aarch64架构和x86_64的最大区别会在后面所有环节里体现出来所以第一步先确认自己被分到的是哪个架构、当前OpenSSH版本是多少。uname -m cat /etc/os-release rpm -qa | grep -i openssh正常输出里uname -m应该是aarch64然后能看到系统自带的openssh、openssh-server、openssh-clients版本。如果这里发现系统里连rpm命令都没有那就得先确认你用的是不是纯dpkg环境是的话需要先用alien或者直接换一种打包方式本文后面仍然以rpm为主线。2.2 安装rpmbuild和编译依赖接下来把打包工具链装齐。统信UOS如果带yum/dnf直接一条命令装完yum install -y rpm-build rpmdevtools gcc make openssl-devel zlib-devel pam-devel krb5-devel这里面rpm-build提供rpmbuild命令rpmdevtools提供rpmdev-setuptree等辅助脚本gcc和make是编译必须的。openssl-devel尤其重要OpenSSH编译时要通过它链接libcrypto和libssl没有这个包configure阶段就会直接报错说找不到OpenSSL头文件。pam-devel则是为了支持PAM认证你不装它也能编但编出来的sshd不支持系统账号密码登录等于废了一半。装完后用rpmdev-setuptree初始化一下打包目录它会生成~/rpmbuild下的BUILD、RPMS、SOURCES、SPECS、SRPMS这五个标准目录后面都会用到。2.3 OpenSSL和PAM版本是编译能否成功的关键OpenSSH 9.6p1对OpenSSL的版本有硬性要求至少要1.1.1以上。统信UOS aarch64环境自带的OpenSSL一般能满足但还是建议先确认一下openssl version如果系统OpenSSL版本比较老那就要先考虑升级OpenSSL本身否则OpenSSH 9.6p1的configure会卡在版本检查上。这一点在老的CentOS 7机器上特别常见但统信UOS一般还好。PAM方面要注意的是编译机上的pam-devel版本应该和目标运行时环境保持一致否则编出来的sshd在运行时可能会因为PAM模块库版本错位导致认证失败。这个坑我后面会专门说这里先埋个伏笔。3. 用官方spec改bump版本避免自己从头写spec3.1 从src.rpm里取现成spec骨架很多人一听“自制rpm包”就觉得要从零写spec文件其实完全没必要。OpenSSH这种历史悠久的软件各发行版都有非常成熟的spec模板最好的做法是找一份现成spec在此基础上改。具体操作是尝试从系统源里拉一份openssh的源码包如果统信UOS的repo里有直接用rpmdev-setuptree搭好目录后把src.rpm装到rpmbuild目录里让rpm自动解开spec和源码yum install -y yum-utils yumdownloader --source openssh rpm -ivh openssh-*.src.rpm执行完后~/rpmbuild/SPECS下会出现openssh.spec~/rpmbuild/SOURCES下会有对应版本的源码包和补丁。如果统信UOS源里没有src.rpm也可以从其他发行版源里找一个版本接近的openssh src.rpm下载重点是把它的spec文件拿过来当模板。3.2 修改Version并清掉过时patch拿到spec后第一件事是打开它把Version字段改成9.6p1Name: openssh Version: 9.6p1 Release: 1 Summary: An open source implementation of SSH protocol versions 2 and 3 ... Source0: https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.6p1.tar.gz然后把你下载好的openssh-9.6p1.tar.gz放到~/rpmbuild/SOURCES目录下注意文件名要和Source0指定的一致。接下来是最容易翻车的地方spec里的Patch列表。老版本spec里会有很多补丁有些是针对老版本bug的修改在新版本上游已经合入再打上去就会失败或者产生无法预料的冲突。我的做法是先把所有Patch行注释掉然后用rpmbuild试编遇到源码编译错误再逐个判断是缺补丁还是环境问题。如果你用的spec本身就是从9.x版本改过来的补丁冲突会少很多。另外要检查一下configure参数。OpenSSH的spec里一般会有类似这样的配置%configure \ --with-pam \ --with-selinux \ --with-privsep-path/var/empty/sshd \ --sysconfdir/etc/ssh \ --with-md5-passwords这些参数不要动尤其--with-privsep-path和--with-pam前者指定了sshd权限分离目录后者保证PAM支持。sysconfdir指定配置文件目录为/etc/ssh要和系统原有路径保持一致。3.3 rpmbuild打包与常见报错处理一切都准备好后执行打包命令cd ~/rpmbuild rpmbuild -ba SPECS/openssh.spec这个命令会依次做解压源码、应用补丁、编译、安装到临时root、打包rpm这套完整流程。第一次跑多半会报错最常见的就是缺少BuildRequires声明的依赖包。看到类似“checking for openssl/ssl.h... no”的报错说明openssl-devel没装好看到“required libcrypto not found”说明Header和库文件没对上。这时候回到第2节把缺的devel包装齐重新跑。还有一个高频报错是源码目录名和spec里的%setup期望不一致。OpenSSH 9.6p1解压后目录名是openssh-9.6p1如果spec里用了%setup -q而源码包文件名匹配问题一般不大。要是出现“cd: openssh-9.6p1: No such file or directory”去看看SOURCES里的源码包名字和spec的Source0是否完全一致包括大小写和点号。3.4 检查产出物确认依赖和文件清单打包成功之后rpm文件会出现在~/rpmbuild/RPMS/aarch64/目录下。用ls看一眼正常情况下应该有这几个包ls -lh ~/rpmbuild/RPMS/aarch64/输出里会看到openssh-9.6p1-1.aarch64.rpm、openssh-server-9.6p1-1.aarch64.rpm、openssh-clients-9.6p1-1.aarch64.rpm。这是一个很有用的细节OpenSSH的rpm包会按客户端、服务端、公共组件拆开升级时三个包要一并处理。接下来用rpm -qpR看一下包的依赖关系确认没有意外依赖rpm -qpR ~/rpmbuild/RPMS/aarch64/openssh-server-9.6p1-1.aarch64.rpm依赖里一般会有libcrypto、libpam、libselinux这些如果出现某个包名带版本号特别高的情况要留意目标机器上能不能满足否则装的时候会报依赖缺失。4. 升级安装的关键动作保住当前会话比什么都重要4.1 升级前备份和配置检查升级OpenSSH最怕的是什么是升级过程中当前ssh会话断开然后sshd又没起来人直接进不去机器。所以正式执行rpm -Uvh之前我会把下面几件事先做掉备份/etc/ssh目录这里面的sshd_config和主机密钥是重点。确认自己当前登录的账号有sudo或root权限并且系统里有其他可用登录方式比如带外管理口以防万一。检查sshd_config里有没有自定义端口。如果改过端口升级后要确认配置文件里的Port指令还在。提前把新包拷到机器上避免升级过程中网络波动导致包传一半。一条命令备份配置cp -a /etc/ssh /etc/ssh.bak.$(date %Y%m%d)4.2 rpm -Uvh升级的正确姿势升级命令本身不复杂但要确保把三个包一起传上去并且用-Uvh而不是-ivh。-U是升级如果老包存在就会替换-v和-h用于显示详细信息。rpm -Uvh ~/rpmbuild/RPMS/aarch64/openssh-9.6p1-1.aarch64.rpm \ ~/rpmbuild/RPMS/aarch64/openssh-server-9.6p1-1.aarch64.rpm \ ~/rpmbuild/RPMS/aarch64/openssh-clients-9.6p1-1.aarch64.rpm这里有个关键机制要提rpm升级时如果新包里的配置文件相对旧包有变化而且你本地改过这个配置rpm会保留旧文件并把新版本生成一个.rpmnew后缀文件而不是直接覆盖。这既是保护也是隐患保护在于不会丢配置隐患在于sshd可能还是按旧逻辑启动。所以升级后要检查/etc/ssh/sshd_config是否有.rpmnew文件有的话把需要的配置项手动合进去。4.3 sshd重启前的自检与延迟重启保险升级完二进制之后先不要急着重启服务。第一步是把当前配置验证一遍/usr/sbin/sshd -t这个命令会在不实际启动服务的情况下检查配置语法有问题会明确报错。显示配置正常后再考虑重启。我强烈建议在重启前加一道“延迟重启保险”。因为如果你用普通命令重启sshd当前ssh连接一旦断开而新sshd又因为某个运行时问题没起来你就被关在门外了。用延迟重启可以把风险窗口缩小nohup bash -c sleep 5; systemctl restart sshd 这样即使当前终端因为重启瞬间断连几秒后sshd也会自动拉起来。更稳妥一点还可以配合at工具设定1分钟后重启给自己留出检查配置的时间。重启后马上验证systemctl status sshd ssh -V如果能正常看到sshd服务是active状态本次升级基本就成功了。5. 升级后实测遇到的五个典型坑5.1 sshd直接起不来Missing privilege separation directory这是从旧版本跨版本升级时最容易碰到的问题。新版本sshd默认要求权限分离目录/var/empty/sshd存在并且权限正确。如果你之前的安装方式没有创建这个目录重启sshd时会报错/usr/sbin/sshd: fatal: Missing privilege separation directory: /var/empty/sshd解决办法很简单mkdir -p /var/empty/sshd chmod 755 /var/empty/sshd chown root:root /var/empty/sshd创建完再跑一遍sshd -t确认没有报错后再重启服务。5.2 sshd_config里残留过时指令导致启动失败跨大版本升级还有个常见问题旧配置里的一些指令在新版本已经被移除或者改名为新指令sshd -t会直接报错。我遇到的典型例子是旧配置里还有Protocol 2这样的显式声明以及指定主机密钥位置时用了老路径。解决方式是把这些过时指令注释掉或者改成新版本兼容的形式。注释完之后再执行sshd -t直到没有报错。这里没有统一脚本只能根据报错逐条处理。我的建议是升级前先用sshd -t跑一遍旧配置看看有哪些warning做到心里有数。5.3 RSA主机密钥位数过小被9.6拒绝OpenSSH 9.x对主机密钥的最小位数检查更严格了。有些老设备在最初部署时生成的是1024位RSA主机密钥升级后sshd启动会报类似“ssh_host_rsa_key too small”的错误。检查一下现有密钥位数ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub如果低于2048位重新生成RSA主机密钥ssh-keygen -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N 重新生成后所有老客户端的known_hosts里对应指纹都会变化这个要有心理准备属于安全升级的正常代价。5.4 PAM配置错位导致密码登录全部失败这个坑比较隐蔽。症状是sshd服务起来了状态也是active但所有用户用密码登录都直接失败认证日志里报PAM相关错误。原因一般是编译时用的PAM模块路径或版本和运行时系统不一致或者升级时rpm把/etc/pam.d/sshd做了变更。这个时候不要慌先看日志journalctl -u sshd -n 50 tail -n 50 /var/log/secure确认是PAM问题后重点检查/etc/pam.d/sshd文件是否还是系统原有的内容如果被替换成了新版的模板往往需要和系统里其他服务的PAM配置对比把关键行恢复回来。实在搞不定可以先临时把PAM关掉测试在sshd_config里把UsePAM改成no重启服务看能否登录。能登录说明就是PAM配置问题不能登录说明认证链路还有别的坑。5.5 SELinux/AppArmor上下文导致的“假死”问题国产系统上很多默认开了SELinux升级后sshd二进制被替换但安全上下文没有正确恢复就会出现“服务active、端口也监听、就是连不上”的假死现象。在SELinux环境下新文件可能继承了错误的文件标签需要手动恢复restorecon -Rv /etc/ssh /usr/sbin/sshd /var/empty/sshd如果系统用的是AppArmor则要检查对应的profile是否覆盖了新二进制路径。这类问题最迷惑人因为从系统层面看一切正常网络、端口、进程都在但连接就是进不来。升级后如果遇到这种情况一定先想到SELinux上下文。最后再分享一点个人体会自制rpm包这件事第一次跑通最花时间后面就会越来越顺手。我这次把openssh.spec和所有需要的devel依赖整理成了固定清单放在内网公共目录里以后再有同架构机器要升级直接拿包、rpm -Uvh半小时以内搞定。如果哪天OpenSSH出到10.x改一下Version和Source0重新rpmbuild一遍就行。长期这么操作下来最大的心得是给这类高危软件升级永远先在一台不承载业务的机器上完整走一遍流程再上生产千万别拿生产机器当第一个试验品。本文还有配套的精品资源点击获取