paketo-buildpacks / libjvm

A library and helper applications that form the basis for building the different Paketo-style JVM-providing buildpacks
Apache License 2.0
19 stars 21 forks source link

Import CA Certificate at runtime #424

Closed alexist closed 2 months ago

alexist commented 2 months ago

Hi,

I'm trying to import a CA Certificate into JVM truststore at runtime. I have provided a volume containing 2 files:

certificate
     certificate.pem
     type

This volumes is mounted into /bindings/certificate

When i start the container, i provide theses options :

   --volume src/test/resources/bff/bindings/certificates:/bindings/s2e  
   --env SERVICE_BINDING_ROOT=/bindings 

The ouput logs :

Enabling Java Native Memory Tracking
Adding 137 container CA certificates to JVM truststore
Added 1 additional CA certificate(s) to system truststore
Spring Cloud Bindings Enabled

I can see that 1 additional CA certificate is added to system trustore.

When i start the container without the 2 options :

Enabling Java Native Memory Tracking
Adding 137 container CA certificates to JVM truststore
Spring Cloud Bindings Enabled

In both case, 137 container CA certificates are added to JVM truststore. So my own CA is not here.

Can you tell me what's wrong ?

dmikusa commented 2 months ago

Nothing is wrong, that's working as designed. You need those arguments, the volume mount and the service binding root location, or the CA certificate is not present in the container and visible to the buildpacks. If it's not present and found, then it won't be loaded correctly.

This is because by default certificates are not embedded into the container. Thus you need to provide them to the container when you start/launch the container. This is also a powerful option because it allows you to change the certificates that are loaded at runtime/launch time, without rebuilding your container.

If you have a CA certificate that you always need or otherwise want bundled into the container, see BP_EMBED_CERTS, which when set at build time will add the CA certificates present at build time into the container. https://github.com/paketo-buildpacks/ca-certificates/?tab=readme-ov-file#configuration

alexist commented 2 months ago

Sorry, my message was not clear, my issue is that CA is not imported into the JVM truststore.

If i run this command inside the container, the CA is imported, and there is not more SSL error "unable to find valid .... PKIX" :

keytool -importcert -file /bindings/s2e/certificate.pem -cacerts

dmikusa commented 2 months ago

No worries, I got overly focused on the arguments and missed something.

Enabling Java Native Memory Tracking
Adding 137 container CA certificates to JVM truststore
Added 1 additional CA certificate(s) to system truststore
Spring Cloud Bindings Enabled

Is the exact order that you're seeing when your app starts? No modifications?

The helpers that load the certificates need to run in the correct order. It looks like your JVM helper is running before the CA certificates system helper. They should run in the reverse order so that when the JVM helper runs, it can read all of the system CA certs and load them into the JVM keystore.

My guess is that because yours are running in the reverse order, your CA cert isn't in the system store when the JVM helper runs and so it's not in the JVM keystore.

Are you by chance using a different JVM vendor buildpack?

There is one drawback to this approach. When using the method above to specify an alternative JVM vendor buildpack, this alternate buildpack ends up running before the CA certs buildpack and therefore traffic from the alternate JVM vendor buildpack won’t trust any additional CA certs. This is not expected to impact many users because JVM buildpacks should reach out to URLs that have a cert signed by a known authority with a CA in the default system truststore.

https://paketo.io/docs/howto/java/#use-an-alternative-jvm

If so, just follow the advice there. The helpers will run in buildpack order, so it is important to keep the ca-certificates buildpack before the JVM vendor buildpack in your order group.

Hope that helps!

alexist commented 2 months ago

Many thanks ! You were right, i'm using an alternate JVM Vendor. Following the advice works fine : Adding 138 container CA certificates to JVM truststore