Subodh Joshi
Subodh Joshi

Reputation: 13482

Kubernate Pod : How to import Certificate into Java Truststore?

So in my environment i am using Docker and Kubernete ,now i have to import a certificate in Pods Java Keystore . But my Container running as a NON-ROOT user .When i am trying to import the certificate to Java Keystore its failing as to accessing Java Keystore user have to be root user only.

keytool -importcert -alias keycloakTest -keystore $JAVA_HOME/lib/security/cacerts -file $WSO2_SERVER_HOME/keycloak.crt -storepass changeit -noprompt

Now How i can import the certificate into Java trust store? Currently i am doing this manually but later i have to do this through DockerFile

COPY /carFiles/keycloak.crt  $WSO2_SERVER_HOME/
CMD keytool -importcert -alias keycloakTest -keystore $JAVA_HOME/lib/security/cacerts -file $WSO2_SERVER_HOME/keycloak.crt -storepass changeit -noprompt

In Kubernete Pods Java run as a root user only?

Edit

I made changes in Docker File something like this

COPY /carFiles/keycloak.crt /opt
CMD keytool -importcert -alias keycloakTest -keystore $JAVA_HOME/lib/security/cacerts -file /opt/keycloak.crt -storepass changeit -noprompt

So from Pods Shell i am able to see certificate Copied to /opt directory but next CMD command wont able to add the certificate into the truststore of java

enter image description here

Enter key or you will be logged out any time after 101 min.

spec:
      volumes:
        - name: certs
          emptyDir: {}
      initContainers:
        - name: {{ .Chart.Name }}-create-keystore-truststore
          securityContext:
            runAsNonRoot: true
            runAsUser: 100
          image: >-
            <HOST>/foapi-tools:20.0.1

 command:
            - sh
            - '-c'
            - >
             # Import Keycloak server certificate into truststore

              # Extract host name from ckey URL

              KEYCLOAK_HOST=$(echo
              "https://<HOST>/auth" | sed
              's|[^/]*//\([^/]*\)/.*|\1|')

              echo "Importing server cert of '${KEYCLOAK_HOST}'..."

              openssl s_client -connect ${KEYCLOAK_HOST}:443 2>/dev/null
              </dev/null | openssl x509 > keycloak.crt

              ls -lat /certs/truststore;
          workingDir: /certs/truststore
          resources:
            limits:
              cpu: 200m
              memory: 200Mi
            requests:
              cpu: 200m
              memory: 100Mi
          volumeMounts:
            - name: certs
              mountPath: /certs/truststore
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent

Upvotes: 1

Views: 10216

Answers (2)

Athiththan
Athiththan

Reputation: 2218

As per the shared information, you are using WSO2 MI and trying to generate a token from the Mediation sequence with Keycloak. In such a case, it is not required to add the Keycloak's cert to the cacerts of the JDK. You can make use of the WSO2 MI's client-truststore.jks to import the certs.

To access the /opt path, the user needs root permission. As WSO2 MI itself contains a truststore and not requires any root permissions to import the certs, you can simply import the Keycloak's TLS public cert in there. Given is a sample Dockerfile to import the certs

COPY /carFiles/keycloak.crt $WSO2_SERVER_HOME/repository/resources/security/
RUN keytool -importcert -alias keycloakTest -keystore $WSO2_SERVER_HOME/repository/resources/security/client-truststore.jks -file $WSO2_SERVER_HOME/repository/resources/security/keycloak.crt -storepass changeit -noprompt

Note: Replace the CMD with the RUN command, as you are trying to import the certs to the truststore as part of building the images. And not setting that command as an entrypoint to start the containers.

Further, if you have a certifier chain, you have to include all (root, intermediate, and leaf certs) in the truststore. Importing only one of them will result again in an SSL Handshake error.

Upvotes: 1

coderanger
coderanger

Reputation: 54181

This is up to your container, or more specifically the file permissions on the jks file. That file is part of your image and is presumably owned by uid 0 and mode 660 or something, so would need to change something for this to work. Either do this at build time or change ownership/mode of the file or use a different jks file.

Upvotes: 0

Related Questions