Rocky 9.5 OpenSSH 10.0p1 RPM升级加固实战 简介面向 Rocky Linux 9.5 x86_64 环境的 OpenSSH 升级与安全加固需求这套离线交付包适合系统管理员、运维工程师及内网安全加固人员使用。它围绕将 OpenSSH 提升至 10.0p1 并配套 OpenSSL 3.5.0 的场景组织提供可直接安装的 RPM 组件和自动化升级脚本减少源码编译、依赖查找与外网源不可用带来的处理成本。压缩包共 6 个文件包含 5 个 rpm 与 1 个 sh 脚本整体约 10.96MB其中 rpm 覆盖 OpenSSH 服务端、客户端及相关系统依赖组件sh 脚本用于串联升级流程便于在受限网络中离线部署和升级后复核。资源已有 210 人学习下载可作为 Rocky Linux 9 系列 SSH 版本升级、服务可用性验证与基础加固的参考材料。读者可从中获得组件配套关系、脚本化升级思路以及升级后版本与服务状态核对方法适合需要快速落地补丁升级、减少外网依赖并完成加固检查的中高级运维场景。1. 上周接手一台 Rocky Linux 9.5 跳板机安全基线扫描把 OpenSSH 标成了红项运维同事的第一反应是dnf update openssh翻遍 BaseOS 和 AppStream版本最高只到 8.7p1离 OpenSSH 10.0p1 差着一大截。转头想源码编译又怕make install把系统自带的 sshd 冲掉回滚无门。这套 rockylinux9.5-ssh10.0p1-ssl3.5.0-rpm-x86-64 升级加固脚本走的是第三条路先把 OpenSSL 3.5.0 和 OpenSSH 10.0p1 编成标准 RPM再用 dnf 替换装翻了dnf downgrade就能退回去。手里有 Rocky 9.5、要过安全基线、又不敢在生产机上裸编源码的人这套流程值得照着走一遍。2. 环境盘点与版本选型OpenSSL 3.5.0 和 OpenSSH 10.0p1 的依赖账先算清动手之前先把盘面摸清。很多人卡在第一步不是因为不会编是因为不知道系统里到底有几个地方的 OpenSSH 在跑、sshd 到底链着哪个 libssl。这一章不讲原理只讲怎么在十分钟内把基线、依赖、回滚点三件事确定下来后面编包和装机才有底。2.1 系统基线核对五条命令摸清现状拿到机器先别急着上传源码包把下面几条命令跑一遍输出贴到变更单里后面出问题时要靠这份快照对照。# 1. 确认发行版与内核Rocky 9.5 对应 el9 系列 cat /etc/rocky-release uname -r # 2. 看当前 OpenSSH 相关包的完整清单别只看 openssh 一个 rpm -qa | grep -E ^(openssh|openssl) | sort # 3. 看 sshd 二进制实际链接了哪些库重点盯 libssl / libcrypto 的路径 ldd /usr/sbin/sshd | grep -E ssl|crypto # 4. 看当前 sshd 的编译参数判断系统包开了哪些特性 sshd -T 2/dev/null | head -5 strings /usr/sbin/sshd | grep -i openSSH_ | head -3 # 5. 看 sshd 监听端口与运行状态 ss -lntp | grep sshd systemctl status sshd --no-pager第 3 条是关键。Rocky 9.5 自带的 openssh-server 链接的是系统/usr/lib64/libssl.so.3版本 3.0.x。你要装的 OpenSSH 10.0p1 如果链接到 OpenSSL 3.5.0那么 libssl 的路径必须能被 sshd 在启动时找到——ldd的输出就是判断这件事有没有做对的唯一证据。第 5 条用来确认端口后面改配置时如果动了 PortSELinux 那边还要同步打标签这里先记下来。依赖清单我一般整理成一张表编包前对着装装完对着查依赖包作用缺失时的典型报错zlib-devel压缩传输configure: error: *** zlib missingopenssl-devel头文件与 pkg-configchecking for OpenSSL headers... nopam-develPAM 认证模块--with-pam编译中断libselinux-develSELinux 上下文--with-selinux静默跳过audit-libs-devel审计日志sshd 登录事件不进 audit.logkrb5-develGSSAPI 认证域环境下密码认证异常装依赖这一步别偷懒用--nodeps缺一个 dev 包configure 有时不报错只是把某个特性静默关掉等装到生产机上才发现 PAM 用不了那时候排查成本比装包高十倍。2.2 为什么这条链路必须走 RPM而不是 make install源码编译三分钟回滚三天——这是血泪经验。make install会把新二进制直接覆盖到/usr/sbin/sshd但 RPM 数据库里记录的还是 8.7p1rpm -V openssh-server从此永久报校验失败dnf后续任何一次系统更新都可能把文件再覆盖回去或者干脆因为文件冲突拒绝执行。更要命的是 SELinux 上下文手工 cp 进去的二进制标签常常是user_home_t或者default_tenforcing 模式下 sshd 直接起不来而journalctl里只会甩一句Permission denied玄学得很。下面这张表是我在几个项目里对比出来的结论变更评审时也拿它说服人维度make installRPM 打包替换回滚方式手工恢复备份文件dnf downgrade openssh包完整性校验rpm -V失效正常SELinux 上下文需手工 restorecon%post脚本自动处理多机一致性每台手工操作一套包推所有机器依赖解析无dnf 自动校验卸载找得到文件算命大rpm -e干净移除RPM 唯一多出来的成本是写 spec 和等编译。但这套脚本已经把 spec 模板和构建脚本备好了你要做的只是改%files里的路径、确认--with-ssl-dir指向正确剩下的rpmbuild -ba会自动跑完。熟手看到这里会问那 OpenSSL 3.5.0 要不要也打成 RPM 替换系统库答案是不替换理由在 3.2 节展开简单说就是动系统 libssl 会连带影响 dnf、curl、sudo牵一发动全身。2.3 升级前必留的三样东西备份、包、会话后悔药要在动手之前吃。下面三条命令在变更窗口开始前十分钟执行缺一不可。# 1. 备份整个 ssh 配置目录带上时间戳别覆盖旧的 tar -czf /root/ssh-config-backup-$(date %F-%H%M).tar.gz /etc/ssh /etc/pam.d/sshd # 2. 把当前的 ssh 相关 rpm 全部下载到本地留底断网也能回滚 mkdir -p /root/ssh-rollback cd /root/ssh-rollback dnf download --alldeps openssh openssh-server openssh-clients openssh-askpass # 3. 记录当前包版本与文件清单回滚后逐条比对 rpm -qa | grep -E ^(openssh|openssl) /root/ssh-rollback/pkg-list.txt rpm -ql openssh-server /root/ssh-rollback/openssh-server-files.txt第 2 条用的是dnf download --alldeps比yumdownloader --resolve更省事的地方在于它会把所有依赖包一并拉到当前目录尤其适合内网无外网源的机器。第 3 条的包清单在回滚后拿diff一比就知道哪些文件是新增的、哪些被改过比盲目rpm -e靠谱。最后一样东西不是文件是会话。操作前开两个 SSH 会话一个用来改配置一个全程不碰、只挂在后台当救生艇。改完配置先别关救生艇等新会话连上、systemctl status稳定三十秒后再退。后面第 6 章讲验证时会再提一次这里的习惯一旦养成sshd 相关的翻车概率能降低一大半。3. 编包实操OpenSSL 3.5.0 和 OpenSSH 10.0p1 的 RPM 怎么打出来构建机不需要和生产机同配置但必须是同一个大版本el9glibc 版本对不上编出来的包在目标机上一跑就报GLIBC_2.34 not found。我一般找一台同版本的 Rocky 9.5 虚拟机当构建机装完rpm-build和rpmdevtools就开工编完把~/rpmbuild/RPMS/x86_64/整个目录拷走。3.1 构建环境从空目录到能跑 rpmbuild# 装构建工具链与全部 dev 依赖 dnf install -y rpm-build rpmdevtools gcc make perl-IPC-Cmd \ zlib-devel pam-devel libselinux-devel audit-libs-devel \ krb5-devel openssl-devel perl-generators systemd-rpm-macros # 生成标准构建目录树BUILD / RPMS / SOURCES / SPECS / SRPMS rpmdev-setuptree # 确认目录落地 ls -1 ~/rpmbuildrpmdev-setuptree生成的五个目录各有分工SOURCES放源码 tarballSPECS放 spec 文件BUILD是解压后的编译现场RPMS是最终产物SRPMS是源码包。源码包放进 SOURCES 时注意名字要和 spec 里Source0:完全一致openssh-10.0p1.tar.gz少一个p都会让 rpmbuild 报Bad file。systemd-rpm-macros这个包容易被忽略。Rocky 9 的 spec 里用%systemd_post sshd.service这类宏来注册 systemd 单元缺了它%post段会报macro undefined包能编出来但装上去服务不生效。3.2 OpenSSL 3.5.0 的编包取舍装到 /opt不动系统库这是整套流程里最关键的一个决定。Rocky 9.5 的系统 libssl 是 3.0.xdnf、curl、sudo、systemd-resolved 全都链着它。你要是把 3.5.0 覆盖进/usr/lib64最快当天下午 dnf 就会报libssl.so.3: undefined symbol整台机器变砖。常见做法是单独编一份装到/opt/openssl-3.5.0只让 OpenSSH 这一个消费者去链接它。spec 的%build段核心参数如下# openssl.spec 的 %build 段装到独立前缀不碰系统 /usr ./Configure \ --prefix/opt/openssl-3.5.0 \ --openssldir/opt/openssl-3.5.0/ssl \ --libdirlib64 \ shared \ zlib-dynamic \ enable-ktls \ -Wl,-rpath,/opt/openssl-3.5.0/lib64 make -j$(nproc)--libdirlib64不能省。x86_64 上 OpenSSL 默认往lib/放共享库而 Rocky 的库搜索路径是lib64装完ldconfig也找不到后面 sshd 启动就报libcrypto.so.3 not found。-Wl,-rpath,...是把运行时库路径直接焊进二进制的头文件里这样即使 systemd 环境里没有LD_LIBRARY_PATHsshd 也能定位到 3.5.0 的库。enable-ktls是内核 TLS 卸载可选编不上也不影响 SSH 功能。%files段要把/opt/openssl-3.5.0整体收进去并在%post里加一句/sbin/ldconfig。另外提醒一句如果同一台机器上后面还要装别的需要 OpenSSL 3.5 的软件这份 /opt 前缀包可以直接复用不用重复编。3.3 OpenSSH 10.0p1 的 configure 开关--with-ssl-dir是命门OpenSSH 这边参数多但真正决定成败的就三个--with-ssl-dir、--with-privsep-path、--sysconfdir。其余都是功能取舍。# openssh.spec 的 %build 段核心 configure 参数 ./configure \ --prefix/usr \ --sysconfdir/etc/ssh \ --libdir/usr/lib64/openssh \ --with-ssl-dir/opt/openssl-3.5.0 \ --with-pam \ --with-selinux \ --with-auditlinux \ --with-zlib/usr \ --with-kerberos5/usr \ --with-privsep-path/var/empty/sshd \ --disable-strip make -j$(nproc)--with-ssl-dir/opt/openssl-3.5.0告诉 configure 去这个目录的include/找头文件、lib64/找库。写错成/opt/openssl-3.5.0/lib64会报找不到opensslv.h因为 configure 期望的是安装根目录。--with-privsep-path/var/empty/sshd指定权限分离用的空目录这个目录必须是 root 属主、755 权限、且不能有写权限%post段里要用install -d -m 0755 -o root -g root /var/empty/sshd建好否则 sshd 启动直接退出日志里只有一句Privilege separation user sshd does not exist或者bad ownership or modes for chroot directory。--libdir/usr/lib64/openssh是给 ssh 内部辅助程序sftp-server、sshd-session找位置用的和系统路径错开避免和旧包的文件冲突。--with-auditlinux编进 audit 支持后登录失败事件能进/var/log/audit/audit.log等保测评时这条是加分项。OpenSSH 10.0p1 相比 8.7 有几个算法层面的硬变化必须先知道否则配完连不上还以为是配置写错了DSA 算法被彻底移除ssh-dss主机密钥和ssh-keygen -t dsa都不再可用基于 SHA-1 的ssh-rsa签名默认不再协商RSA 密钥只能用rsa-sha2-256或rsa-sha2-512ChallengeResponseAuthentication这个配置项已经彻底删掉只认KbdInteractiveAuthentication。这三条在第 5 章会对应三个真实故障。3.4 产物自检包编出来了不等于能用rpmbuild 跑完不报错只代表语法对了不代表包能装。RPMS/x86_64/下面应该出现四个包openssh、openssh-server、openssh-clients、openssh-askpass以及 OpenSSL 的一个openssl35前缀包。装之前挨个过一遍下面三条命令。cd ~/rpmbuild/RPMS/x86_64/ # 1. 看包信息与依赖声明确认 Requires 里没有意外的系统库版本要求 rpm -qpi openssh-server-10.0p1-1.el9.x86_64.rpm rpm -qpR openssh-server-10.0p1-1.el9.x86_64.rpm # 2. 看包内文件清单确认没有和系统旧包重叠的路径 rpm -qpl openssh-server-10.0p1-1.el9.x86_64.rpm | head -30 # 3. 看 sshd 的链接情况把二进制从包里抽出来验 rpm2cpio openssh-server-10.0p1-1.el9.x86_64.rpm | cpio -idmv ./usr/sbin/sshd ldd ./usr/sbin/sshd | grep -E ssl|crypto第 2 条是防冲突的关键。如果清单里出现/usr/bin/ssh说明你的--libdir或者%files写岔了装的时候必然和系统的 openssh-clients 打架。第 3 条期望看到libssl.so.3 /opt/openssl-3.5.0/lib64/libssl.so.3如果指向/usr/lib64/libssl.so.3说明--with-ssl-dir没生效回去重编别抱侥幸心理往下装。4. 安装与加固把新包落进 Rocky 9.5 且不打断现有会话到这一步包已经在手上了真正的心跳时刻才开始。装包顺序错了会触发文件冲突配置改猛了会把自己关在门外SELinux 忘了打标签会让服务起不来。这一章按顺序做每一步都有回退点。4.1 安装顺序先 OpenSSL 前缀包再 OpenSSH 四件套# 1. 先装 OpenSSL 3.5.0 前缀包它不冲突可以放心装 dnf install -y ./openssl35-3.5.0-1.el9.x86_64.rpm # 2. 确认库路径已注册 ldconfig -p | grep openssl-3.5.0 # 3. 再装 OpenSSH 四件套--allowerasing 允许替换同名旧包 dnf install -y --allowerasing \ ./openssh-10.0p1-1.el9.x86_64.rpm \ ./openssh-clients-10.0p1-1.el9.x86_64.rpm \ ./openssh-server-10.0p1-1.el9.x86_64.rpm # 4. 立刻校验版本与链接 rpm -q openssh openssh-server openssh-clients ldd /usr/sbin/sshd | grep ssl--allowerasing的作用是允许 dnf 移除与新包文件冲突的旧包不加这个参数会直接报file /usr/bin/ssh from install of openssh-clients-10.0p1 conflicts with file from package openssh-clients-8.7p1。这个参数有风险——它可能在你不注意的时候顺带删掉别的包——所以装完立刻执行第 4 条把版本和链接都确认一遍。四个包要一次性装完分批装会在中间状态产生sshd和ssh版本不一致的情况sshd -t会报协议不匹配。如果dnf install因为依赖环卡住退一步用rpm -Uvh --replacefiles --replacepkgs手工装但装完要跑一次dnf check确认依赖树完整。4.2 sshd_config 加固openssh加固 最值得先动的十一个参数配置文件不建议整份覆盖用sshd_config.d/目录分片管理出问题好定位。Rocky 9.5 的/etc/ssh/sshd_config首行有Include /etc/ssh/sshd_config.d/*.conf把加固项单独写一个文件# /etc/ssh/sshd_config.d/99-hardening.conf # 认证策略禁密码、禁交互式、只留公钥 PermitRootLogin prohibit-password PubkeyAuthentication yes PasswordAuthentication no KbdInteractiveAuthentication no UsePAM yes MaxAuthTries 3 LoginGraceTime 30 # 会话控制断连回收与转发限制 ClientAliveInterval 300 ClientAliveCountMax 2 X11Forwarding no AllowTcpForwarding no AllowAgentForwarding no # 算法白名单只留 10.0p1 支持且安全的套件 KexAlgorithms sntrup761x25519-sha512openssh.com,curve25519-sha256,ecdh-sha2-nistp256 Ciphers chacha20-poly1305openssh.com,aes256-gcmopenssh.com,aes128-gcmopenssh.com MACs hmac-sha2-512-etmopenssh.com,hmac-sha2-256-etmopenssh.com HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256 PubkeyAcceptedAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256PermitRootLogin prohibit-password和PasswordAuthentication no这两条是必须成对出现的。只写前者root 还能用密码登录只写后者普通用户禁了密码但 root 没禁。KbdInteractiveAuthentication no在 10.0p1 里尤其要写因为旧的ChallengeResponseAuthentication已经不存在了配置文件里如果还留着这一行sshd 会直接报Bad configuration option拒绝启动。算法白名单这一组是最容易出事的地方。Ciphers只留 AEAD 套件、MACs只留 ETM 套件安全性上没问题但如果你的环境里有老旧的网络设备、堡垒机、自动化脚本客户端它们可能只支持aes128-cbc或hmac-sha1配完就连不上。稳妥做法是第一次先不加三行算法限制等新版本跑稳一周再按客户端能力逐个收紧。真要在生产上收紧提前用ssh -Q cipher、ssh -Q mac、ssh -Q kex在客户端侧确认支持列表。4.3 预检与重载sshd -t不通过就别 reload# 1. 语法检查这一步必须 0 退出码才继续 /usr/sbin/sshd -t -f /etc/ssh/sshd_config # 2. 打印最终生效配置确认分片文件被正确 Include /usr/sbin/sshd -T | grep -E passwordauth|permitrootlogin|ciphers|kexalgorithms # 3. 平滑重载不中断现有连接 systemctl reload sshd # 4. 看状态与最近日志 systemctl status sshd --no-pager journalctl -u sshd -n 30 --no-pager第 1 条是黑匣子。sshd -t会把所有配置项过一遍包括 Include 进来的分片、算法名是否合法、主机密钥文件是否存在、权限是否合规。它报错的行号有时不准尤其是 Include 场景但错误关键词很明确照着搜基本能定位。第 3 条用reload而不是restart。reload给 sshd 发 SIGHUP让它重新读配置已经在线的连接不受影响restart会把 sshd 主进程停掉再起如果新配置有隐藏问题你就彻底断了。真的需要restart时先确认救生艇会话还在并且那台机器有带外管理IPMI、云控制台 VNC可用。4.4 PAM、SELinux 与主机密钥三个装完必查的细节# 1. 主机密钥确认 ed25519 和 rsa 都在DSA 的旧文件删掉 ls -l /etc/ssh/ssh_host_* rm -f /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_dsa_key.pub # 2. 权限私钥必须 600目录 755属主 root chmod 600 /etc/ssh/ssh_host_*_key chmod 644 /etc/ssh/ssh_host_*_key.pub chown root:root /etc/ssh/ssh_host_* # 3. SELinux 上下文恢复 端口标签如果改了非 22 端口 restorecon -Rv /etc/ssh semanage port -l | grep ssh semanage port -a -t ssh_port_t -p tcp 2222 # 4. PAM 配置确认sshd 的 PAM 栈要能读到 grep -E ^(auth|account|session) /etc/pam.d/sshd | head -8第 3 条的restorecon是装完 RPM 之后必跑的一步。RPM 的%post脚本里一般会带但如果你手工覆盖过配置文件或者从别处拷过密钥上下文就乱了ls -Z一看是unconfined_u:object_r:user_home_tsshd 立刻拒绝使用该主机密钥。semanage port -a改端口标签这条命令只在真的改了 Port 时才需要执行重复执行会报ValueError: Port tcp/2222 already defined改用-m修改。第 4 条容易被跳过。UsePAM yes打开后sshd 会走/etc/pam.d/sshd这个栈如果升级过程中这个文件被旧包的%post覆盖或者被新包改坏认证会静默失败——密码输对了也进不去日志里只有Failed password看着像密码错了其实是 PAM 栈断链。装完比对一下备份里的版本diff /root/ssh-config-backup-*/etc/pam.d/sshd /etc/pam.d/sshd一眼就能看出来。5. 避坑与排查升级 OpenSSH 后连不上、起不来的五类现场下面五条是我在几个环境里真实碰到过的按现象、原因、解决三段写。碰到问题时先别乱改配置对着这五条找最像的那条能省掉大半排查时间。5.1 现象客户端报no matching host key type found服务端日志Unable to negotiate原因OpenSSH 10.0p1 默认不再协商基于 SHA-1 的ssh-rsa签名而老客户端旧版 PuTTY、某些网络设备的 SSH 客户端、写死算法的自动化脚本还在用这一套。同时 DSA 主机密钥已经被彻底移除如果客户端指定ssh-dss直接没有交集。解决不要试图在服务端把ssh-rsa加回HostKeyAlgorithms10.0p1 已经不接受这个值加了会报配置错误。正确做法是让客户端改用rsa-sha2-256或升级客户端。临时缓解可以在服务端保留 RSA 主机密钥它仍然能用 SHA-2 签名同时确保 ED25519 主机密钥存在客户端优先走 ED25519。实在没法升级的老设备单独开一个Match Address段降级算法别全局放开。5.2 现象systemctl start sshd失败journalctl报error while loading shared libraries: libcrypto.so.3: cannot open shared object file原因sshd 编译时链接了/opt/openssl-3.5.0/lib64下的库但 rpm 包里的二进制没有写死 rpath或者%post里忘了跑ldconfigsystemd 启动时环境里没有LD_LIBRARY_PATH找不到库。解决ldd /usr/sbin/sshd | grep crypto先确认路径如果是not found在/etc/ld.so.conf.d/openssl35.conf里写一行/opt/openssl-3.5.0/lib64然后ldconfig再systemctl daemon-reload systemctl restart sshd。根治办法是回 3.2 节给 configure 加-Wl,-rpath重编一次。不要用systemctl edit塞EnvironmentLD_LIBRARY_PATH...这对 sshd 这种特权进程不可靠子进程还会丢环境。5.3 现象dnf install报file /usr/bin/ssh from install of openssh-clients-10.0p1 conflicts with file from package openssh-clients-8.7p1原因新旧包的文件路径完全重叠dnf 的默认事务策略拒绝覆盖。这是 RPM 打包的正常现象不是包坏了。解决加--allowerasing让 dnf 移除旧包再装新的或者先dnf remove openssh-clients再单独装 —— 但后者有风险中间状态可能连 ssh 客户端都没有回滚都做不了。稳妥做法是四件套一次性dnf install --allowerasing ./openssh*.rpm事务里一起替换。执行前把/root/ssh-rollback里的旧包确认一遍出事直接dnf install /root/ssh-rollback/*.rpm退回去。5.4 现象密码输对了也登不进日志里只有Failed password/var/log/secure没有更详细的线索原因UsePAM yes打开了但/etc/pam.d/sshd这个 PAM 栈在升级过程中被改坏或缺失模块认证阶段直接失败。也可能是KbdInteractiveAuthentication被设为yes而PasswordAuthentication no两条路径打架。解决先diff备份里的 pam 配置和当前文件缺什么补什么再sshd -T | grep -E passwordauth|kbdinteractive|usepam看最终生效值确认三条互斥关系没写反。排查阶段可以临时sshd -ddd -p 2222在前台跑一个调试实例把客户端连到 2222 端口日志会打到终端上比翻 journalctl 清楚得多。调完记得 kill 掉别留在后台。5.5 现象装完扫描器仍然报 OpenSSH 版本低或者rpm -q openssh显示的版本没变原因只装了openssh-serveropenssh和openssh-clients还是旧版或者装完之后dnf做了一次自动更新旧包被重新拉了回来覆盖掉。解决rpm -qa | grep openssh一条条对四个包版本必须一致。再跑dnf versionlock add openssh openssh-server openssh-clients openssh-askpass把版本锁住防止后续更新回退。最后用strings /usr/sbin/sshd | grep -i openssh_10确认二进制里真的是 10.0p1别只看 rpm 数据库——数据库和文件不一致的情况在手工覆盖过的机器上并不罕见。6. 验证跑通三个终端交叉确认新版本真的生效版本号对了不等于服务能用。我的验证习惯是开三个终端终端 A 全程挂着旧连接不动终端 B 用来执行命令和新开连接终端 C 从另一台机器发起连接。三边交叉确认任何一边异常都能立刻定位是哪一层的问题。先做本地自证这几条命令的输出要逐条对# 1. 二进制版本与算法能力 /usr/sbin/sshd -V 21 | head -1 ssh -V ssh -Q kex | head -5 ssh -Q cipher | grep -c gcm # 2. 运行时链接确认最关键的一条 ldd /usr/sbin/sshd | grep -E ssl|crypto # 期望libssl.so.3 /opt/openssl-3.5.0/lib64/libssl.so.3 # 3. 配置最终生效值 /usr/sbin/sshd -T | grep -E permitrootlogin|passwordauthentication|ciphers # 4. 新建密钥对并走本机回环验证密钥认证链路 ssh-keygen -t ed25519 -f /tmp/verify_key -N ssh-copy-id -i /tmp/verify_key.pub localhost ssh -i /tmp/verify_key -o BatchModeyes localhost echo OK; ssh -V第 4 条是一次端到端自检用 ED25519 密钥、强制非交互模式登录本机如果返回OK加版本号说明密钥认证、PAM、会话建立、算法协商全部走通。BatchModeyes的作用是禁止任何交互提示密码提示、主机指纹确认都会被当成失败这样测出来的结果才是干净的。然后从终端 C 发起真实连接重点看协商细节# 客户端侧-vvv 看协商过程重点抓 kex / host key / cipher 三行 ssh -vvv -p 22 -i ~/.ssh/id_ed25519 usertarget 21 | \ grep -E kex:|host key algorithm|server-client cipher|Authenticated期望输出类似kex: algorithm: sntrup761x25519-sha512openssh.com、host key algorithm: ssh-ed25519、Authenticated to target。如果kex那行显示的是curve25519-sha256而不是 sntrup 那一条说明客户端版本稍老不影响使用只是没走最强的 KEM 套件。最后把验证项整理成一张表变更单里附上比写文字描述省事验证项命令期望结果版本一致rpm -qa | grep openssh四包均为 10.0p1库链接ldd /usr/sbin/sshd | grep ssl指向 /opt/openssl-3.5.0配置合法/usr/sbin/sshd -t退出码 0无输出服务状态systemctl is-active sshdactive密钥认证ssh -i /tmp/verify_key localhost免密登录成功算法协商ssh -vvv ... | grep kex非 ssh-rsa非 DSA旧会话保留终端 A 执行who am i仍在线未断开SELinuxls -Z /etc/ssh/ssh_host_*_keysshd_key_t这张表跑完才算真的装完了。别嫌麻烦我见过太多装完了其实是只在测试机装完了。从那以后我每次动 sshd都强制走一遍固定动作先开两个会话、sshd -t过一遍、reload而不是restart、新会话验证通过之后才关救生艇。这套动作花不了五分钟但救过我三次——一次是算法白名单写死了老设备连不上一次是 rpath 没生效库找不到一次是 PAM 文件在升级里被覆盖。希望帮到你。本文还有配套的精品资源点击获取