I'm trying to run liquibase update command using
liquibase --driver="com.ibm.db2.jcc.DB2Driver" --changeLogFile="masterchangelog.xml " --url="jdbc:db2://localhost:60001/SMDINTDB:retrieveMessageFromServerOnGetMessage=true;sslConnection=true;" --username="" --password="" --classpath=/home/db2inst1/sqllib/java/db2jcc4.jar validate
But I'm getting following error. Can anyone help me how to resolve this issue? How I can specify the location of certs ?
Unexpected error running Liquibase: com.ibm.db2.jcc.am.DisconnectNonTransientConnectionException: [jcc][t4][2030][11211][4.26.14] A communication error occurred during operations on the connection's underlying socket, socket input stream,
or socket output stream. Error location: Reply.fill() - socketInputStream.read (-1). Message: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. ERRORCODE=-4499, SQLSTATE=08001
Several pre-requisites exist for on-premises Db2-LUW SSL connectivity with jdbc.
liquibase works correctly with SSL connections to on-premises Db2-LUW, if all the prerequisite configuration completed successfully. Here are some tips.
the target Db2-LUW instance has to be already configured for SSL as per IBM Db2 documentation here. If you are using a cloud based Db2 service from IBM then this is already done for you, although you may need to use the IBM supplied root cert on the client side.
your client side JRE needs to be configured per IBM's Db2-LUW documentation here. I use the IBM JRE (as supplied with the Db2-LUW server) for liquibase.
for on-premises Db2-LUW your client side needs the java keystore created, and the server's certificate imported into it (keytool -importcert -file /your/path/to/server_certificate ... ).
for your specific error, for on-premises Db2-LUW you might try additional options in the connection string to tell the JRE how to access the client side keystore into which you already imported the server certificate. Specifically sslTrustStoreLocation=/path/to/.keystore;sslTrustStorePassword=whatever; . Note that I did not need these options if using Db2-on-cloud (liquibase worked correctly with SSL to Db2-on-cloud once I added DigiCertGlobalRootCA.crt to my keystore (although even that may be unnecessary) , but I did not try Db2-warehouse-on-cloud as I don't use that service.
Related
Am using WebSphere 9.0.5.10 and trying to connect DB2 database over SSL port.
I tried to retrieve the certificate from DB2 database by using the below procedure.
Import the database server certificate.
1.Open the WebSphere Application Server administrative console.
Security > SSL certificate and key management > Key stores and certificates > {NodeDefKeystore}
Signer certificates > Retrieve from port.
Clicked Retrieve from port.
Enter the host name and security port of the database server.
Type an alias name for the certificate.
Click Retrieve signer information.
Click OK to save the configuration.
2.Configure the data source to support SSL connections.
Select Resources > JDBC > Data sources.
Select WebSphere Commerce database DataSource demo in the data source list, where database can be either DB2 or Oracle.
Update the port number in the Common and required data source properties section. Enter the value of the security port that you set in the database server.
Clicked Apply.
In the Additional Properties section, select Custom properties.
Clicked New
Enter sslConnection in the Name field, and enter true in the Value field.
Click OK to save the configurations.
Post service restart, tried to check the database connection and got below error.
Someone please help to resolve the issue.
Error: The test connection operation failed for data source on server nodeagent at node with the following exception: java.sql.SQLException: [jcc][t4][2030][11211][4.29.24] A communication error occurred during operations on the connection's underlying socket, socket input stream, or socket output stream. Error location: Reply.fill() - socketInputStream.read (-1). Message: com.ibm.jsse2.util.h: PKIX path building failed: java.security.cert.CertPathBuilderException: unable to find valid certification path to requested target. ERRORCODE=-4499, SQLSTATE=08001 DSRA0010E: SQL State = 08001, Error Code = -4,499. View JVM logs for further details.
The Test Connection function makes a best attempt at connecting, but some security requirements are not supported by this, since Test Connection is not an equivalent application.
Test Connection does not have the same quality of function available as an application, hence, an application in this case is the best method to test any database connections.
Another document that is well worth checking is:
WebSphere Application Server Data Source driver connection over SSL with Database server
https://community.ibm.com/community/user/wasdevops/blogs/ajit-jariwala/2021/10/06/websphere-application-server-data-source-driver-c
Otherwise it's more of a DB2 JDBC Driver issue with the error -4499
Perhaps, also test the very latest JDBC Driver 4.32.28
https://www.ibm.com/support/pages/db2-jdbc-driver-versions-and-downloads
Hope it helps!
Dave
I'm trying to connect to a free tier Heroku database from the Wolfram Language. The DatabaseLink package uses JDBC to make the connection. When I specify that SSL should be used for the connection, I get:
JDBC: SSL error: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
The support article at:
https://reference.wolfram.com/language/DatabaseLink/tutorial/SecureSocketLayer.html
... seems to suggest that one needs to get the security certificate for the site, generate a "truststore" file, and then load the JVM in a way that specifies which truststore file should be used.
I'm unsure if this is leading me in the right direction or not. But as of now, I'm unsure how I would go about getting this security certificate.
I seem to have stumbled upon at least one way to get around the failure I was seeing, as described in the "Using SSL without Certificate Validation" section of:
https://jdbc.postgresql.org/documentation/head/ssl-client.html
I was able to specify the sslfactory option via:
OpenSQLConnection[
...,
"Properties" -> {"ssl" -> "true", "sslfactory" -> "org.postgresql.ssl.NonValidatingFactory"}
]
Now the database connection is succeeding.
I try to run a microservice (based on Eclipse Microprofile) on OpenLiberty (v20.0.0.1/wlp-1.0.36.cl200120200108-0300) on Eclipse OpenJ9 VM, version 1.8.0_242-b08 (en_US))
I run the server as the official Docker image (open-liberty:kernel)
In my service I try to connect to another rest service via HTTPS
Client client = ClientBuilder.newClient();
client.target("https://myservice.foo.com/").request(....);
This throws the following exception:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
I already added the features 'transportSecurity-1.0' and 'ssl-1.0' into the server.xml file:
<featureManager>
<feature>jaxrs-2.1</feature>
<feature>microProfile-2.2</feature>
<feature>transportSecurity-1.0</feature>
<feature>ssl-1.0</feature>
</featureManager>
and I also tweaked the jvm.options file like this:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=7777
-Dhttps.protocols=TLSv11,TLSv12
-Djdk.tls.client.protocols=TLSv11,TLSv12
-Dhttps.protocols=TLSv11,TLSv12
-Dcom.ibm.jsse2.overrideDefaultProtocol=TLSv11,TLSv12
But nothing helps to get rid of the exception.
How is the correct configuration for OpenLiberty to enable outgoing ssl connections?
Liberty doesn't trust anything over ssl by default, so unless the service you are connecting to uses an identical keystore/truststore file, or you've otherwise configured your service to trust the microservice in some way, you can get that exception. If this is the problem, something like this will probably be seen in messages.log as well:
com.ibm.ws.ssl.core.WSX509TrustManager E CWPKI0823E: SSL HANDSHAKE FAILURE: A signer with SubjectDN [CN=localhost, OU=oidcdemo_client, O=ibm, C=us] was sent from the host [localhost:19443]. The signer might need to be added to local trust store [/Users/tester/tmp/liberty/20003wlp/wlp/usr/servers/urlcheck/resources/security/key.p12], located in SSL configuration alias [defaultSSLConfig]. The extended error message from the SSL handshake exception is: [PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target].
How to manually patch up the truststore is documented here,
https://www.ibm.com/support/knowledgecenter/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/twlp_add_trust_cert.html
but what you will probably want to do in a docker environment is modify your images to either include a common keystore/truststore, or read one from outside somewhere (such as a kubernetes secret). By default, each docker image creates it's own unique key/truststore, and they won't be able to "talk" over ssl.
If you only need to communicate with services that have a certificate signed by a well-known authority, you can add
ENV SEC_TLS_TRUSTDEFAULTCERTS=true
to your Dockerfile (20.0003+) to enable that.
As mentioned by Bruce in the answer above, Liberty doesn't trust any certificates by default. If you are making outgoing connections from Liberty to a server, you either need to add their certificate to the truststore you have configured OR you need to trust the JRE's cacerts if the remote endpoint is using a certificate from a well-known CA.
When you say you are using Let's Encrypt certificates, do you mean the remote end-point is using them, or your Liberty server is?
If the remote end-point is, most JRE's cacerts include Let's Encrypt in their cacerts. If the Liberty server is using a certificate signed by Let's Encrypt, that doesn't really have an effect on the outgoing connection unless you are using mutual SSL authentication.
As an FYI, if you are using a certificate signed by Let's Encrypt in Liberty as the default certificate, we will be adding built-in support for the ACME protocol in a few releases. See here for progress: https://github.com/OpenLiberty/open-liberty/issues/9017
I am using Spring3, Hibernate4 and postgres9.2.
For enabling the SSL database connection, I followed following steps :
Creating self signed Certificate : refer : http://www.postgresql.org/docs/9.2/static/ssl-tcp.html#SSL-CERTIFICATE-CREATION
Copied the generated server.crt and server.key into postgres/9.2/data folder.
URL for hibernate connection : jdbc:postgresql://localhost:5432/DB_NAME?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory
After restarting the postgres I run my application and it gives error as :
org.postgresql.util.PSQLException: The server does not support SSL.
at org.postgresql.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:307)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:105)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:65)
at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:140)
at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:29)
at org.postgresql.jdbc3g.AbstractJdbc3gConnection.<init>(AbstractJdbc3gConnection.java:21)
at org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:31)
at org.postgresql.jdbc4.Jdbc4Connection.<init>(Jdbc4Connection.java:23)
at org.postgresql.Driver.makeConnection(Driver.java:393)
at org.postgresql.Driver.connect(Driver.java:267)
Even I tried to add this line at the end of pg_hba.conf file but postgres does not get restarted :
hostssl all all 127.0.0.1/32 trust
EDIT
It is for other folks who received such error or wants to add database ssl connection :
I added ssl = true and removed comments for ssl related entries from postgresql.conf and it worked. :)
The root of your problem appears to be that your server does not support SSL or does not have it enabled. The message:
The server does not support SSL
may only be emitted by org/postgresql/core/v3/ConnectionFactoryImpl.java in enableSSL(...) when the server refuses or doesn't understand SSL requests.
Sure enough, in your update you say that you had the SSL-related options in postgresql.conf commented out. Them being commented out is the same as them being not there at all to the server; it will ignore them. This will cause the server to say it doesn't support SSL and refuse SSL connections because it doesn't know what server certificate to send. PgJDBC will report the error above when this happens.
When you un-commented the SSL options in postgresql.conf and re-started the server it started working.
You were probably confused by the fact that:
&ssl
&ssl=true
&ssl=false
all do the same thing: they enable SSL. Yes, that's kind of crazy. It's like that for historical reasons that we're stuck with, but it's clearly documented in the JDBC driver parameter reference:
ssl
Connect using SSL. The driver must have been compiled with SSL
support. This property does not need a value associated with it. The
mere presence of it specifies a SSL connection. However, for
compatibility with future versions, the value "true" is preferred. For
more information see Chapter 4, Using SSL.
As you can see, you should still write ssl=true since this may change in future.
Reading the server configuration and client configuration sections of the manual will help you with setting up the certificates and installing the certificate in your local certificate list so you don't have to disable certificate trust checking.
For anyone else with this problem: There will be more details in your PostgreSQL error logs, but my guess is your PostgreSQL config isn't right or you're using a hand-compiled PostgreSQL and you didn't compile it with SSL support.
If you are using a self-signed certificate you need to add it to your trusted key store of your Java installation on the client side.
You find the detailed instructions to achieve this here: telling java to accept self-signed ssl certificate
In your connection string, try
?sslmode=require
instead of
?ssl=true
Use param sslmode=disable. Work for me. Postgresql 9.5 with jdbc driver SlickPostgresDriver.
I'm wanting to connect to an Azure SQL Server from jdbc.
I copy the connection string from the azure management console. It is something like:
jdbc:sqlserver://XXXX.database.windows.net:1433;database=YYYY;user=ZZZZZ#XXXX;password=PPPPPPPPPPP;encrypt=true;hostNameInCertificate=*.database.windows.net
When I try and connect with this value I get the following error:
com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not
establish a secure connection to SQL Server by using Secure Sockets
Layer (SSL) encryption. Error:
"java.security.cert.CertificateException: Failed to validate the
server name in a certificate during Secure Sockets Layer (SSL)
initialization. The server name is *.database.windows.net, the name in
certificate is data.am2-1.database.windows.net.
Then if I change the *.database.windows.net to data.am2-1.database.windows.net as it says in the exception it works fine.
So is it a problem to set this name? I feel like if it is a wild card as default then it is probably going to change? and when it does I assume I won't be able to connect anymore.
Has anyone else had this issue? I am using the most up to date jdbc drivers for SQL Server that I could find.
Turns out an upgrade of the sql server jdbc version to version 4.0 cleaned up the issue.
I've got the same issue on JDBC driver version 4.1, downgrading to 4.0 resolved issue
You can also add trustServerCertificate=true in your connection string, but it's not recommended from a security perspective.