Openliberty PostgreDB 与 sslMode=verify-ca 的连接失败

Openliberty PostgreDB connection with sslMode=verify-ca fails

我正在尝试将我的 Openliberty 服务器连接到 sslMode 高于“require”的 PostgreDB。这是 server.xml:

<featureManager>
    <feature>jaxrs-2.1</feature>
    <feature>mpHealth-2.1</feature>
    <feature>ejbLite-3.2</feature>
    <feature>beanValidation-2.0</feature>
    <feature>concurrent-1.0</feature>
    <feature>mpConfig-1.3</feature>
    <feature>jpa-2.2</feature>
    <feature>transportSecurity-1.0</feature>
    <feature>jdbc-4.2</feature>
</featureManager>

...

<sslDefault sslRef="defaultSsl"/>
<ssl id="defaultSsl" trustStoreRef="defaultTrustStore"/>
<keyStore id="defaultTrustStore" location="postgre_store.jks" password="changeit"/>

<library id="postgresql-driver-library">
    <fileset dir="${shared.resource.dir}/postgresql" id="postgresql-driver-fileset" includes="*.jar"/>
</library>

<jdbcDriver id="postgresql-driver" javax.sql.XADataSource="org.postgresql.xa.PGXADataSource"
            javax.sql.ConnectionPoolDataSource="org.postgresql.ds.PGConnectionPoolDataSource"
            libraryRef="postgresql-driver-library"/>

<dataSource id="some-db" jndiName="jdbc/mydb" jdbcDriverRef="postgresql-driver"
            type="javax.sql.ConnectionPoolDataSource" transactional="true">
    <properties serverName="${datasource.servername}"
                portNumber="${datasource.port}"
                databaseName="${datasource.database}"
                user="${datasource.username}"
                password="${datasource.password}"
                ssl="true"
                loggerLevel="DEBUG"
                sslMode="verify-ca"
                sslFactory="org.postgresql.ssl.DefaultJavaSSLFactory"/>
</dataSource>

信任库与 server.xml 位于同一文件夹中。在服务器启动时,一旦 Flyway 尝试连接到 PostgreDB,我就会收到以下错误:

[INFO] SQL State  : 08006
[INFO] Error Code : 0
[INFO] Message    : SSL error: PKIX path building failed: 
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path 
to requested target DSRA0010E: SQL-Status = 08006, Errorcode = 0
[INFO]
[INFO]  at org.flywaydb.core.internal.jdbc.JdbcUtils.openConnection(JdbcUtils.java:60)
[INFO]  at 
org.flywaydb.core.internal.database.DatabaseFactory.createDatabase(DatabaseFactory.java:72)
[INFO]  at org.flywaydb.core.Flyway.execute(Flyway.java:1670)
[INFO]  at org.flywaydb.core.Flyway.info(Flyway.java:1521)

我将根证书(自签名)添加到新创建的信任库中,如下所述:https://jdbc.postgresql.org/documentation/head/ssl-client.html 并将其从 .cer 转换为 .crt.der (尽管我不确定这是否重要)。我如何确定所提供的信任库被 jdbc 识别和使用?我的假设是否正确 <properties> 标签内的 sslRootCert 属性也应该指向 public,用于在 Postgre 服务器端(我想要的服务器)生成证书的可信根证书连接到)?

Openliberty 版本为:21.0.0.3

postgre 驱动程序工件是:

<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.14</version>

关于连接可能无法正常工作的原因有什么想法吗?

我认为这里的问题是您试图同时使用驱动程序 SSL 工厂和本机 java SSL 工厂。

当您设置 sslFactory="org.postgresql.ssl.DefaultJavaSSLFactory" 时,您是在告诉驱动程序忽略 sslRootCert,而是希望在本机 java 信任库中找到证书。

您可以执行以下操作之一来解决此问题:

  1. 将您的根证书添加到您的信任库。
  2. 将您的私钥添加到驱动程序或将您的私钥添加到驱动程序并删除本机 Java SSL Factory
  • 添加:sslKey="${server.config.dir}/postgre_store.jks"
  • 删除:sslFactory="org.postgresql.ssl.DefaultJavaSSLFactory"

要对此进行调试,您应该运行 使用以下 JVM 属性 -Djavax.net.debug=all 并查看输出。 驱动程序尝试验证的受信任证书将列在以下位置:

javax.net.ssl|DEBUG|35|Default Executor-thread-3|X509TrustManagerImpl.java:79|adding as trusted certificates (
  "certificate" : {
    "version"            : "v3",
    "serial number"      : "1C 3D 0F 3E",
    "signature algorithm": "SHA256withRSA",

这是一个有用的博客,它更深入地介绍了自由的 SSL 配置:https://openliberty.io/blog/2021/06/04/database-ssl-primer.html

连接设置正确,本例中的问题是 PostgreSQL 服务器配置不当。