我们注意到 Java 应用程序 Metabase 在连接到 SQL Server 2016 时出现错误,并且使用相同的配置,该问题发生在 Red Hat Enterprise Linux 9 上,但不发生在 Red Hat Enterprise Linux 7 上。因此,我们希望得到帮助以确认是否由于操作系统导致,并对其进行修复。
更长的故事:
我们正在测试 Metabase 的升级实例,升级后的组件包括
- Red Hat Enterprise Linux(从 v7 到 v9)操作系统,
- Java(从 11 到 21),以及
- Metabase 软件(从 v0.32.x 到当前的 v0.50.x)。
并且我们在连接到 SQL Server 2016 的数据源时发现升级后的实例中出现以下错误。
“encrypt”属性设置为“false”,“trustServerCertificate”属性设置为“false”,但驱动程序无法使用安全套接字层 (SSL) 加密与 SQL Server 建立安全连接:错误:证书不符合算法约束。ClientConnectionId:6bf62750-d5c4-49c5-8ada-4253d8b55055
我们怀疑该错误与 Red Hat Enterprise Linux 9 的系统行为有关,因此我们设计了以下简化的测试用例来支持我们的观点:
测试配置:
- Java openjdk v11.0.23
- metabase.jar v0.32.5
我们通过调用命令来启动应用程序java -jar metabase.jar
,因此它会为应用程序数据库启动一个在本地 H2 上运行的 Metabase 的全新演示实例。
然后,我们尝试添加一个配置了不需要加密的 SQL Server 2016 数据源。
在 Red Hat Enterprise Linux 7 上运行时,上述测试成功。然而,在 Red Hat Enterprise Linux 9 上运行时,测试失败,并出现以下日志事件,请注意时间戳12-19 14:58:44
:
12-19 14:58:09 DEBUG middleware.log :: GET /api/setup/admin_checklist 200 14 ms (10 DB calls) Jetty threads: 8/50 (3 busy, 5 idle, 0 queued) (48 total active threads)
12-19 14:58:44 INFO metabase.driver :: Initializing driver :sqlserver...
12-19 14:58:44 DEBUG plugins.classloader :: Setting current thread context classloader to shared classloader clojure.lang.DynamicClassLoader@1dc9fc0...
12-19 14:58:44 INFO plugins.classloader :: Added URL file:/data/metabase-test/v0.32.5/plugins/sqlserver.metabase-driver.jar to classpath
12-19 14:58:44 DEBUG plugins.init-steps :: Loading plugin namespace metabase.driver.sqlserver...
12-19 14:58:44 INFO metabase.driver :: Registered driver :sqlserver (parents: :sql-jdbc) 🚚
12-19 14:58:44 DEBUG plugins.jdbc-proxy :: Registering JDBC proxy driver for class com.microsoft.sqlserver.jdbc.SQLServerDriver...
Load lazy loading driver :sqlserver took 173 ms
12-19 14:58:44 DEBUG middleware.log :: POST /api/database 400 314 ms (0 DB calls) Jetty threads: 8/50 (3 busy, 4 idle, 0 queued) (45 total active threads)
{:valid false,
:dbname
"com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: \"Certificates do not conform to algorithm constraints\". ClientConnectionId:ca179b99-b3b3-4351-a0de-736b7dc8e765",
:message
"com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: \"Certificates do not conform to algorithm constraints\". ClientConnectionId:ca179b99-b3b3-4351-a0de-736b7dc8e765"}
12-19 14:58:44 DEBUG middleware.log :: GET /api/database 200 5 ms (3 DB calls) Jetty threads: 8/50 (3 busy, 4 idle, 0 queued) (45 total active threads)
12-19 15:00:00 INFO task. Send-pulses :: Sending scheduled pulses...
我们想知道我们是否错过了有关新操作系统的任何信息,我们非常感谢任何指点和提示。
附加信息
关于 TLS:
测试的SQL Server 2016没有安装SSL证书,并且配置为“不需要加密”。
- 我们在“SQLServerManager13.msc > SQL Server 网络配置 > MSSQLSERVER 协议 > 属性”中检查了 Windows 主机,发现“强制加密”为
No
,而“证书”选项卡中没有任何内容。 - 该命令
openssl s_client
输出以下结果:# openssl s_client -connect <sql-server-hostname>:1433 -showcerts Connecting to xxx.xxx.xxx.xxx CONNECTED(00000003) 001EA5D0C87F0000:error:0A000126:SSL routines::unexpected eof while reading:ssl/record/rec_layer_s3.c:689: --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 0 bytes and written 309 bytes Verification: OK --- New, (NONE), Cipher is (NONE) This TLS version forbids renegotiation. Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok) ---
关于SQL Server版本:
在运行 Metabase 的所有内容相同的情况下,我们测试在 SQL Server 2022 而不是 2016 上添加数据源,并且测试在 RHEL9 上通过。
关于差异java. Security
:
我们分别从 RHEL7 和 RHEL9 中获取java.security
文件,然后过滤掉注释和空白,得到净内容。通过比较两个文件,我们发现了以下几个不同之处。
RHEL9 上的文件
java.security
不再支持我们 SQL Server 2016 上的旧算法,因此最佳做法应该是升级 SQL Server。