In my team, we're trying to deploy a microservice stack based on JHipster (6.8.0) on OpenShift (4.2).
We have currently an issue when the gateway starts and tries to communicate with Keycloak through HTTPS (using Red Hat Single Sign On 7.3 based on Keycloak to be precise).
Here is the exception that is raised:
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
We think it is because our gateway doesn't trust certificates from Keycloak. Indeed, this one is using organization certificates. We have logged in to the Keycloak administration interface on the realm the gateway is trying to connect with. And we have extracted certificates as X.509 binary-encoded DER files; thanks to Chrome browser functionality.
We first tried to simply add these certificates to the etc/ssl/certs/java/cacerts
folder of our gateway container. To do so, we created these folders in the project jib repository, src/main/jib/etc/ssl/certs/java/cacerts
, and copied the certificates to it.
We have generated our gateway Docker image using Maven and the jib:dockerBuild
option. We pushed it to our Docker registry and deployed it to OpenShift.
After a check in the OpenShift pod, certificates are well in place in etc/ssl/certs/java/cacerts
. But we still get the same error as before.
We then tried to use a truststore. So we created one using this command for each certificate:
keytool -import -file path/to/certificate.cer -alias certificateAlias -keystore applicationTrustStore.jks
We checked that all certificates were properly added, thanks to this command:
keytool -list -v -keystore applicationTrustStore.jks
Then we added this applicationTrustStore.jks file into the src/main/jib/etc/ssl/certs/java/cacerts
folder of our project and added this in the pom.xml:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>${jib-maven-plugin.version}</version>
<configuration>
<from>
<image>adoptopenjdk:11-jre-hotspot</image>
</from>
<to>
<image>application:latest</image>
</to>
<container>
…
<jvmFlags>
<jvmFlag>-Djavax.net.ssl.trustStore=etc/ssl/certs/java/cacerts/applicationTrustStore.jks</jvmFlag>
<jvmFlag>-Djavax.net.ssl.trustStoreType=jks</jvmFlag>
<jvmFlag>-Djavax.net.ssl.trustStorePassword=password</jvmFlag>
</jvmFlags>
</container>
…
</configuration>
</plugin>
Once again, we have generated and redeployed to OpenShift with no luck; still exactly the same issue.
We're certainly missing something obvious but we can't put our finger on it.
TL;DR — Try adding the certificate to the
cacerts
keystore of the JRE on which your application's Docker image is based.The long-winded answer
Ahh yes! The old
…PKIX path building failed…
problem. Been there. And OpenShift was also involved to boot, in one instance.Having come across that same error maybe a dozen or so times at this point, I would bet that the reason why your efforts so far had no effect, is because that
javax.net.ssl.SSLHandshakeException
is coming from the JRE running your application; not from whatever it is at/etc/ssl/certs/java/
.The solution
From your browser, obtain the Root CA certificate in question (what you referred to as: „…the Realm the gateway is trying to connect with…“)
Add the certificate to the
cacerts
keystore of the JRE on which your application's Docker image is based (<image>adoptopenjdk:11-jre-hotspot</image>
)You can pull from Docker Hub, the image that Dockerfile builds…
Run it to observe that the cert with the alias was added…2
If even that doesn't solve your problem, then the next thing I would suggest is to change this…
To this…
In case you didn't spot the difference, you've left out the leading forward slash from:
/etc/…
1 You'll have to adapt however you build your image to jibe with the instructions in the example Dockerfile.
2 I used the Stack Overflow cert for this experiment.