How do I import a CA root certificate to trust store in JBoss EAP for OpenShift?
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- 7.4
- Red Hat OpenShift Container Platform (OCP)
- 4
Issue
-
How do I import a CA root certificate to trust store in JBoss EAP for OpenShift?
-
update-ca-trustfails in a JBoss EAP Pod as follows. How do I updatecacertsin the container?$ oc rsh <pod-name> sh-4.2$ update-ca-trust p11-kit: couldn't create file: /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt: Permission denied p11-kit: couldn't create file: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem: Permission denied p11-kit: couldn't create file: /etc/pki/ca-trust/extracted/pem/email-ca-bundle.pem: Permission denied p11-kit: couldn't create file: /etc/pki/ca-trust/extracted/pem/objsign-ca-bundle.pem: Permission denied p11-kit: couldn't create file: /etc/pki/ca-trust/extracted/java/cacerts: Permission denied -
keytool -importalso fails in JBoss EAP Pod due toPermission denied:$ oc rsh <pod-name> sh-4.2$ keytool -import -keystore /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/security/cacerts -trustcacerts -alias my-root-cert -file /opt/eap/standalone/configuration/root-ca.crt -storepass changeit -noprompt Certificate was added to keystore keytool error: java.io.FileNotFoundException: /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/security/cacerts (Permission denied)
Resolution
Option 1. Mount cacerts as a Secret - Runtime option:
Extract cacerts from the JBoss EAP container, add a root certificate to cacerts, and mount it as Secret. The sample steps are as follows.
NOTE: Updating the JBoss EAP container image will also update ca-certificates-<date-version>.el7_9.noarch package in the image. If you update the version of JBoss EAP image, you need to re-extract cacerts from the new version of the container image.
1. Deploy an arbitrary application to OpenShift
$ oc new-project eap74-test
$ oc create -f https://raw.githubusercontent.com/jboss-container-images/jboss-eap-openshift-templates/eap74/templates/eap74-basic-s2i.json
$ oc create -f https://raw.githubusercontent.com/jboss-container-images/jboss-eap-openshift-templates/eap74/eap74-openjdk8-image-stream.json
$ oc new-app --template=eap74-basic-s2i -p APPLICATION_NAME=helloworld -p IMAGE_STREAM_NAMESPACE=eap74-test -p EAP_IMAGE_NAME=jboss-eap74-openjdk8-openshift:7.4.0 -p EAP_RUNTIME_IMAGE_NAME=jboss-eap74-openjdk8-runtime-openshift:7.4.0 -p SOURCE_REPOSITORY_URL=https://github.com/jboss-developer/jboss-eap-quickstarts -p SOURCE_REPOSITORY_REF=7.4.x -p CONTEXT_DIR=helloworld-html5
$ oc get pod | grep Running
helloworld-1-mp7cl 1/1 Running 0 19m
2. Extract the cacerts file from the pod
$ oc rsync helloworld-1-mp7cl:/etc/pki/ca-trust/extracted/java/cacerts .
$ ls
cacerts root-ca.crt
3. Import a CA certificate to cacerts
$ chmod 744 cacerts
$ keytool -keystore cacerts -alias my-root-cert -import -file root-ca.crt -storepass changeit -noprompt
Certificate was added to keystore
4. Mount cacerts as a Secret
$ oc create secret generic cacerts --from-file=cacerts
$ oc set volume dc/helloworld --add --name=cacerts-vol -m /opt/eap/cert/ -t secret --secret-name=cacerts
5. Add -Djavax.net.ssl.trustStore and -Djavax.net.ssl.trustStorePassword to replace default trusted store in the Pod
$ oc set env dc/helloworld JAVA_OPTS_APPEND="-Djavax.net.ssl.trustStore=/opt/eap/cert/cacerts -Djavax.net.ssl.trustStorePassword=changeit"
Option 2. Add a CA certification when building a container - Build time option:
If you have already created a custom EAP image with a Dockerfile, this is a simple option. The copy command will succeed given higher privileges at build time - see below:
USER root
COPY ./root-ca.crt /usr/share/pki/ca-trust-source/anchors/
RUN update-ca-trust
Root Cause
update-ca-trustcommand requires privileges and cannot be run on JBoss EAP for OpenShift Pod.- The default java trust store
/etc/pki/ca-trust/extracted/java/cacertsis read-only. We cannot updatecacertsafter JBoss EAP Pod has been started.
sh-4.2$ ls -l /etc/pki/ca-trust/extracted/java/cacerts
-r--r--r--. 1 root root 154622 Dec 13 05:57 /etc/pki/ca-trust/extracted/java/cacerts
The solution Injecting CA certificate inside OpenJDK container at runtime and build time, discuss a generalized approaches for this problem for OpenJDK containers including Service-CA Operator usage at runtime injection.
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.