使用 RDS 2019 CA 根证书的 RDS PostgreSQL 的 Jetty + HikariCP + JVM SSL 连接问题
Jetty + HikariCP + JVM SSL Connectivity Issues to RDS PostgreSQL with RDS 2019 CA root certificate
我无法尝试使用 Jetty (9.4.26) + JVM (java-1.8.0)
连接到 RDS PostgreSQL
我尝试了一些东西
- 将 2019 RDS CA 导入 Java cacerts
- 为 Java
设置单独的 TrustStore 文件
- 在 start.ini 中为 Jetty 设置 TrustStore 文件
打开 -Djavax.net.debug=ssl
显示已将 2015 RDS CA 添加到信任中,但我无法确定它被告知要信任的位置。我怀疑 webapp
嵌入了 2015 RDS CA...
来自 Jetty 的日志
(-Djavax.net.debug=ssl
)
~
~
adding as trusted cert:
Subject: CN=Amazon RDS Root CA, OU=Amazon RDS, O="Amazon Web Services, Inc.", L=Seattle, ST=Washington, C=US
Issuer: CN=Amazon RDS Root CA, OU=Amazon RDS, O="Amazon Web Services, Inc.", L=Seattle, ST=Washington, C=US
Algorithm: RSA; Serial number: 0x42
Valid from Thu Feb 05 20:11:31 AEDT 2015 until Thu Mar 05 20:11:31 AEDT 2020
~
~
~
~
~
Jan 23, 2020 9:54:46 AM org.postgresql.Driver connect
SEVERE: Connection error:
org.postgresql.util.PSQLException: SSL error: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:67)
at org.postgresql.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:391)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:162)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195)
at org.postgresql.Driver.makeConnection(Driver.java:452)
at org.postgresql.Driver.connect(Driver.java:254)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:95)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:101)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:314)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:171)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:441)
at com.zaxxer.hikari.pool.HikariPool.access0(HikariPool.java:66)
at com.zaxxer.hikari.pool.HikariPool$PoolEntryCreator.call(HikariPool.java:576)
at com.zaxxer.hikari.pool.HikariPool$PoolEntryCreator.call(HikariPool.java:569)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:62)
... 18 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
at sun.security.validator.Validator.validate(Validator.java:262)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:330)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:237)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)
... 26 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
... 32 more
~
~
~
有什么想法吗?
我将尝试回答这个问题,因为我有一个有效的修复方法
修复正在升级 PostgreSQL JDBC 驱动程序。当前版本是 42.2.1
,升级时可用的版本是 42.2.9
现在查看 Psql JDBS 驱动程序 changelog, I found that from version 42.2.5
onwards there was code change,它改变了 sslmode
使用的
查看JDBCdriver source,特别是在42.2.1
版本的驱动程序中的ssl/MakeSSL.java
文件中,这段代码现在已经不存在了
33 SSLSocketFactory factory;
34
35 String sslmode = PGProperty.SSL_MODE.get(info);
36 // Use the default factory if no specific factory is requested
37 // unless sslmode is set
38 String classname = PGProperty.SSL_FACTORY.get(info);
39 if (classname == null) {
40 // If sslmode is set, use the libp compatible factory
41 if (sslmode != null) {
42 factory = new LibPQFactory(info);
43 } else {
44 factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
45 }
46 } else {
47 try {
48 factory = (SSLSocketFactory) instantiate(classname, info, true,
49 PGProperty.SSL_FACTORY_ARG.get(info));
50 } catch (Exception e) {
51 throw new PSQLException(
52 GT.tr("The SSLSocketFactory class provided {0} could not be instantiated.", classname),
53 PSQLState.CONNECTION_FAILURE, e);
54 }
55 }
我无法尝试使用 Jetty (9.4.26) + JVM (java-1.8.0)
连接到 RDS PostgreSQL我尝试了一些东西
- 将 2019 RDS CA 导入 Java cacerts
- 为 Java 设置单独的 TrustStore 文件
- 在 start.ini 中为 Jetty 设置 TrustStore 文件
打开 -Djavax.net.debug=ssl
显示已将 2015 RDS CA 添加到信任中,但我无法确定它被告知要信任的位置。我怀疑 webapp
嵌入了 2015 RDS CA...
来自 Jetty 的日志
(-Djavax.net.debug=ssl
)
~
~
adding as trusted cert:
Subject: CN=Amazon RDS Root CA, OU=Amazon RDS, O="Amazon Web Services, Inc.", L=Seattle, ST=Washington, C=US
Issuer: CN=Amazon RDS Root CA, OU=Amazon RDS, O="Amazon Web Services, Inc.", L=Seattle, ST=Washington, C=US
Algorithm: RSA; Serial number: 0x42
Valid from Thu Feb 05 20:11:31 AEDT 2015 until Thu Mar 05 20:11:31 AEDT 2020
~
~
~
~
~
Jan 23, 2020 9:54:46 AM org.postgresql.Driver connect
SEVERE: Connection error:
org.postgresql.util.PSQLException: SSL error: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:67)
at org.postgresql.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:391)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:162)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195)
at org.postgresql.Driver.makeConnection(Driver.java:452)
at org.postgresql.Driver.connect(Driver.java:254)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:95)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:101)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:314)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:171)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:441)
at com.zaxxer.hikari.pool.HikariPool.access0(HikariPool.java:66)
at com.zaxxer.hikari.pool.HikariPool$PoolEntryCreator.call(HikariPool.java:576)
at com.zaxxer.hikari.pool.HikariPool$PoolEntryCreator.call(HikariPool.java:569)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:62)
... 18 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
at sun.security.validator.Validator.validate(Validator.java:262)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:330)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:237)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)
... 26 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
... 32 more
~
~
~
有什么想法吗?
我将尝试回答这个问题,因为我有一个有效的修复方法
修复正在升级 PostgreSQL JDBC 驱动程序。当前版本是 42.2.1
,升级时可用的版本是 42.2.9
现在查看 Psql JDBS 驱动程序 changelog, I found that from version 42.2.5
onwards there was code change,它改变了 sslmode
使用的
查看JDBCdriver source,特别是在42.2.1
版本的驱动程序中的ssl/MakeSSL.java
文件中,这段代码现在已经不存在了
33 SSLSocketFactory factory;
34
35 String sslmode = PGProperty.SSL_MODE.get(info);
36 // Use the default factory if no specific factory is requested
37 // unless sslmode is set
38 String classname = PGProperty.SSL_FACTORY.get(info);
39 if (classname == null) {
40 // If sslmode is set, use the libp compatible factory
41 if (sslmode != null) {
42 factory = new LibPQFactory(info);
43 } else {
44 factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
45 }
46 } else {
47 try {
48 factory = (SSLSocketFactory) instantiate(classname, info, true,
49 PGProperty.SSL_FACTORY_ARG.get(info));
50 } catch (Exception e) {
51 throw new PSQLException(
52 GT.tr("The SSLSocketFactory class provided {0} could not be instantiated.", classname),
53 PSQLState.CONNECTION_FAILURE, e);
54 }
55 }