OpenSSH 8.x 下 Oracle 19c RAC OUI SSH 连接失败解决指南
2026/9/21 0:40:08 网站建设 项目流程

先说个结论:你手动 ssh/scp 都能通,不代表 Oracle 19c RAC 安装界面里的 OUI 能通。我在 RHEL 8 系列系统上装 19c Grid Infrastructure 时,就被这一幕卡了整整一个下午:两台节点的 ssh 互信、免密登录全都正常,可一走到 OUI 的 “SSH Connectivity” 步骤,就是红叉,报错信息翻来覆去就是那句“The ssh command failed. Ensure that ssh is installed and available in the PATH.”。后来扒日志、查算法、翻系统安全策略,才发现真正的矛盾点根本不在这台机器的命令上,而是 OpenSSH 8.x 默认关闭了老式 RSA 签名算法,而 Oracle 安装器内嵌的 Java SSH 库还停在“旧世界”里挪不动步。这篇文章就把这次的完整排查过程和最终解决办法写出来,给所有准备在 OpenSSH 8.x 环境下装 19c RAC 的人省点时间。

1. 这个问题的现场还原:手动 SSH 正常,OUI 却一直失败

1.1 我这次的部署环境

先说下我手里的这套环境,方便你对号入座:

项目配置
操作系统RHEL 8.6(内核 4.18.0-372),两台节点
主机名db01,db02
数据库版本Oracle Grid Infrastructure 19.3.0.0,Oracle Database 19.3.0.0
用户grid(GI 安装)、oracle(DB 安装)
OpenSSH 版本OpenSSH_8.0p1, OpenSSL 1.1.1k
共享存储ASM,两节点各挂同一组共享 LUN

整个安装流程走到 OUI 的 “SSH Connectivity” 界面前,cluvfy的检查都正常,网络、内核参数、用户组、存储属主权限也全都通过了。问题就出在这个步骤上——填上grid用户和口令,点 “Test”,界面不通过,日志里记录到远端执行命令失败。

1.2 手动命令全通,到底哪里断了

这是最让人抓狂的地方。我在 db01 上执行:

ssh db02 hostname scp /tmp/test.txt db02:/tmp/

都正常,用ssh-keygen生成 RSA 密钥、ssh-copy-id配好互信之后,免密登录也完全没问题。所以一开始我根本不信是 SSH 本身的问题,怀疑是权限、目录、防火墙,甚至 OUI 的 Java 环境有问题。

但问题恰恰就藏在“手动命令全通”的背后:我在命令行手工执行 ssh 时,系统用的是 OpenSSH 8.0p1 这个原生客户端,它会和远端的 sshd 协商一套双方都支持的算法。而 OUI 里的 “SSH Connectivity” 检测,是它自带的一个 Java SSH 库(jcraft.jsch,也就是常说的 JSch)去连接远端节点并执行远程命令。这个库的版本相对老,默认支持的算法和 OpenSSH 8.x 能提供的算法匹配不上,结果就是:命令行能过,JSch 过不去。

提示:如果安装过程中 OUI 的 SSH Connectivity 失败,第一反应不应该是重装 OpenSSH,而是先确认是不是 JSch 和 OpenSSH 8.x 的算法协商问题。这个问题在 Oracle Linux 8、RHEL 8、CentOS 8 上非常典型。

2. 追根溯源:OUI 检测 SSH 背后到底发生了什么

2.1 OUI 的 “SSH Connectivity” 并不是简单的 ping

很多第一次装 RAC 的人,可能以为点一下 “Test” 就是用ssh命令连一下远端服务器,类似于看看通不通。实际它做的工作比这多得多:OUI 会调用 JSch,用你填的用户名和口令(或者已有的密钥),连接到每个节点,然后到远程执行一些安装前需要的命令,比如创建诊断目录、把安装介质同步到其他节点、验证远程节点的目录权限等。

也就是说,这个步骤不是“验证连通性”,而是“真正在使用 SSH 通道做远程操作”。在这个场景下,JSch 自身支持的算法列表,决定了它能不能和远端的 sshd 成功握手。

2.2 OpenSSH 8.x 和 JSch 的算法碰撞

这里解释下冲突的根源。OpenSSH 8.0 开始,出于安全考虑,默认禁用了基于 SHA-1 的 SSH-RSA 签名算法。RSA 密钥本身没有问题,但用 RSA 私钥去签名时,旧版本默认走 ssh-rsa(SHA-1)这条算法;而 8.x 的 sshd 默认不再接受这种签名,除非在配置里显式加回ssh-rsa。JSch 的老版本在连接远端时,默认也只会用 ssh-rsa 这个算法去做密钥交换和用户认证,两边一碰,服务端直接拒绝。

打个比方:JSch 是个只会说“方言 A”的人,OpenSSH 8.x 的 sshd 是个已经不再说“方言 A”的当地人。命令行下的 OpenSSH 客户端因为本身也会说“方言 B”,就能和当地人聊得热火朝天;但 JSch 只会“方言 A”,自然吃闭门羹。

那怎么确认是这个原因?最直接的办法是看 OUI 的详细安装日志。日志路径一般在:

$ORACLE_BASE/oraInventory/logs/installActions2025-XX-XX_XX-XX-XXPM.log

或者你安装时指定的 inventory 目录下的 logs。用文本编辑器打开,搜索JSchAuth failno matching key exchangeConnection refused这类关键字,一般能看到这样的内容:

com.jcraft.jsch.JSchException: Auth fail

或者:

com.jcraft.jsch.JSchException: Algorithm negotiation fail

看到 “Algorithm negotiation fail”,基本就可以锁定了。

注意:网上搜这个问题,很多人会建议你把~/.ssh/known_hosts删掉、检查authorized_keys权限、改成 DSA 密钥后再试。这些我都试过,不能说完全没用,但都没有触及根本——即使你完美配置好 RSA 免密,JSch 和 sshd 之间算法协商不一致,一样会认证失败。

3. 排查过程记录:那些试了以后没用的方案

3.1 我一开始的排查侧重

我先把节点间时钟同步、DNS 解析、防火墙、SELinux 都过了一遍,都正常。然后手动在grid用户下重新生成密钥并配好互信,sshscp依然通畅。

再试ssh -v看连接过程,能看到两边的算法协商列表:

ssh -vvv db02 hostname

输出里能看到:

debug1: kex: algorithm: curve25519-sha256 debug1: kex: host key algorithm: ecdsa-sha2-nistp256 debug1: Server accepts key: /home/grid/.ssh/id_rsa debug1: Authentication succeeded (publickey).

这说明在命令行场景下,OpenSSH 客户端有足够多的算法选择,甚至可以用 ECDSA 密钥或 curve25519 密钥交换来绕过 ssh-rsa 的限制。

3.2 重装 OpenSSH、升级 OpenSSH,都不是正路

还有一个容易被带偏的方向,就是网上有人建议把 OpenSSH 升级到更高版本,说新版本和 Oracle 19c 更“兼容”。这里我强烈不建议在安装 Oracle RAC 期间去动系统的 OpenSSH,原因有三点:

  1. OpenSSH 升级后,系统原有的 sshd 配置、PAM 模块、SELinux 策略都可能要跟着调整,风险成倍增加。
  2. 网上能搜到的一些 OpenSSH RPM,来源不一定可靠,而且版本和系统自带的 OpenSSL、内核 Crypto 策略可能不匹配。
  3. 真正的问题不在 OpenSSH“不够新”,而是“太新”,新到把老算法默认关了。升级上去只会更难协商。

你要做的是让 sshd 把老算法重新打开,而不是把整个 SSH 协议栈换掉。

4. 一劳永逸的解法:让 OUI 和 OpenSSH 8.x 重新“通气”

4.1 修改 sshd,显式开启老算法

直接在集群的每个节点的 sshd 配置里加上兼容老算法的设置。编辑/etc/ssh/sshd_config,在文件末尾追加:

HostKeyAlgorithms +ssh-rsa,ssh-rsa-cert-v01@openssh.com PubkeyAcceptedAlgorithms +ssh-rsa KexAlgorithms +diffie-hellman-group14-sha1,diffie-hellman-group1-sha1

需要注意,OpenSSH 8.x 里PubkeyAcceptedAlgorithms这个参数的名称,在更早版本里叫PubkeyAcceptedKeyTypes。如果你用的系统版本提示参数名不对,可以改成PubkeyAcceptedKeyTypes +ssh-rsa。这里我以 8.0p1 为准。

改完后重启 sshd:

sudo systemctl restart sshd

然后确认配置已生效:

sshd -T | grep -E 'pubkeyacceptedalgorithms|hostkeyalgorithms|kexalgorithms'

输出里应该能看到ssh-rsa出现在列表里了。

4.2 把兼容配置固化,避免系统更新后被覆盖

如果你只是改/etc/ssh/sshd_config,后续某个安全补丁把 sshd 配置重置,或者安装别的软件修改了配置,问题可能再次出现。更稳妥的做法是,在/etc/ssh/sshd_config.d/目录下单独建一个文件,比如oracle-rac.conf

sudo tee /etc/ssh/sshd_config.d/oracle-rac.conf <<'EOF' HostKeyAlgorithms +ssh-rsa,ssh-rsa-cert-v01@openssh.com PubkeyAcceptedAlgorithms +ssh-rsa KexAlgorithms +diffie-hellman-group14-sha1,diffie-hellman-group1-sha1 EOF

注意/etc/ssh/sshd_config里至少要有一行Include /etc/ssh/sshd_config.d/*.conf,RHEL 8 默认是有的,确认一下没被注释就行。这样以后即使主配置被重置,独立文件里的配置依然生效,这就是我说的“一劳永逸”的思路:不是靠一次手工修改碰运气,而是把兼容策略做成独立的、可持续的配置单元。

4.3 在 sshd 级别解决后,还要留意客户端侧

服务端开启这些算法后,大多数情况下 OUI 就能连通了。但如果你后续还要让 OpenSSH 命令行客户端(注意这里说的是纯命令行下的 ssh,不是 OUI 里的 JSch)也走 ssh-rsa 签名,比如你生成的公钥格式是老式 RSA 密钥且没有用新算法签名,那么客户端侧也要放开限制。

~/.ssh/config里加:

Host * PubkeyAcceptedAlgorithms +ssh-rsa HostKeyAlgorithms +ssh-rsa

不过对这个案例来说,Oracle 安装界面里的 JSch 是独立实现,它走的是自己的算法逻辑,所以只要服务端 sshd 愿意接受 ssh-rsa,JSch 就应该能连上。我实测下来,服务端改完配置后,OUI 的 “Test” 红叉立刻变成绿勾。

注意:放开 ssh-rsa 相当于降低了 sshd 的默认安全水位。如果你的机器直接暴露在公网,要谨慎评估这个风险。一般内网的数据库服务器问题不大,但安装完成后,如果不需要旧算法了,我建议评估后移除+ssh-rsa这类配置,恢复系统默认的更高安全策略。

4.4 如果不想动 sshd 配置,还有一条“绕行路线”

我后来复盘时也想明白了一个替代方案。如果你极度不想动 sshd 算法配置,或者公司安全基线规定 sshd_config 不允许改动,那么可以在运行 OUI 之前,手工把集群节点间的 SSH 互信准备好,然后在 OUI 的 “SSH Connectivity” 界面选择“跳过”或“不配置”。但如果你用的是图形化 OUI,这一步通常是必填的,跳过的操作不太顺畅;而如果你用静默模式(silent response file)安装,就可以在响应文件里把 SSH 相关参数置空或设为 false,前提是你已经提前把互信配好,并且安装进程能够用当前用户直接免密操作所有节点。

这里推荐提前使用 Oracle 自带的sshUserSetup.sh脚本,在 GI 安装介质解压目录下能找到:

$ORACLE_HOME/oui/bin/sshUserSetup.sh

或者 Grid 安装包解压根目录里也有。它的用法是:

./sshUserSetup.sh -user grid -hosts "db01 db02" -confirm -advanced

这个脚本本质上就是帮你把公钥分发到各节点,比手工一条条敲命令更规范。配好之后,你用grid用户在 db01 上执行ssh db02 hostname能做到免密,那 OUI 里的 JSch 即使算法协商有差异,理论上也可以借你现有的互信做认证。但要注意,我这次遇到的情况并不仅仅是“没有互信”,而是 JSch 即使拿到密钥,也可能因为算法不匹配而认证失败,所以最稳妥的还是先放开 sshd 算法。

5. 安装继续:通过 SSH 检测之后还能遇到哪些坑

5.1 完成 GI 安装和 root.sh

SSH Connectivity 通过后,OUI 会继续执行后续的runInstaller步骤,包括把安装文件同步到其他节点、运行root.sh等脚本。我这次在 db01 和 db02 上依次执行root.sh时,又踩了一个小坑:db01 的root.sh执行完后,db02 的root.sh等了很久才跑完,原因是节点间 SSH 验证又触发了一次。不过由于前面已经配置好兼容算法,这次没有报错,只是慢了几分钟。

执行root.sh时建议在两个终端同时开好日志跟踪:

tail -f /u01/app/oraInventory/logs/installActions*.log

5.2 安装后的基础验证

GI 装完后,用grid用户执行:

crsctl stat res -t cluvfy stage -post hwos -n db01,db02 cluvfy comp ssa -n db01,db02

检查 CRS 资源是否 ONLINE,ASM 实例是否正常。

然后再跑 DBCA 创建数据库。我在创建 RAC 数据库时,ASM 磁盘组、监听配置这些都比较顺利,但如果你是在装完 GI 很久之后才跑 DBCA,要注意ORACLE_HOMEORACLE_SID的环境变量别配错。还有一点,如果是 19c 的 RAC,dbca时一定要选择 “Oracle Real Application Clusters” 选项,别选成单实例。

6. 避坑清单:给后来者的一套速查

6.1 常见问题速查表

问题现象可能原因排查/解决办法
OUI SSH Connectivity 报 The ssh command failedJSch 与 OpenSSH 8.x 算法协商失败修改 sshd_config 开启 ssh-rsa,重启 sshd
日志出现 Auth fail算法不匹配或用户/口令错误先确认手动 ssh 是否免密;再查看 OUI 日志
手动 ssh 免密正常,OUI 仍失败JSch 不使用系统 ssh 命令,而是内置库不要只看命令行,重点看 OUI 的 installActions 日志
修改 sshd_config 后重启 sshd 失败配置参数名写错或重复添加sshd -t检查语法;确认 OpenSSH 版本对应参数名
系统被安全加固过,禁止改 sshd安全基线限制预先用 sshUserSetup.sh 配好互信,或走静默安装绕过 OUI 检测
安装完成后 CRS 资源异常可能是网络心跳、ASM 磁盘权限问题crsctl stat res -tcluvfy逐步排查

6.2 我的最终心得

这个问题的本质,是 Oracle 19c 自带的安装工具链没有跟上 OpenSSH 8.x 的安全策略更新。它不算一个难解决的问题,但排查路径很绕,因为“手动 SSH 正常”这个表象太有迷惑性了。我个人建议是,以后只要是在 OpenSSH 8.x 或者更新版本的系统上装 Oracle 19c RAC,先把/etc/ssh/sshd_config.d/oracle-rac.conf这个兼容文件放到所有节点上,再开始跑安装。不要等到 OUI 报错才动手,省出来的时间和心情都是实实在在的。还有一个小提醒:这些兼容算法配置在安装完成后要记得评估是否需要移除,毕竟安全永远是运维的一根底线。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询