Keyfactor/ejbca-community-helm

Question: how to change Java Key Store (JKS) password?

Opened this issue · 9 comments

We deployed the chart with following env variables (some informations are redacted):

    ejbca:
       useEphemeralH2Database: false
       #useH2Persistence: true
       #existingH2PersistenceClaim: ejbca-data-claim
       env:
         TLS_SETUP_ENABLED: "true"
         METRICS_ENABLED: "true"
         OBSERVABLE_BIND: 0.0.0.0
         LOG_LEVEL_APP: INFO
         HTTPSERVER_HOSTNAME: "pki.example.tech"
         SMTP_DESTINATION: "xxxxx"
         SMTP_PORT: '25'
         SMTP_FROM: "noreply@pki.example.tech"
         SMTP_TLS_ENABLED: "false"
         SMTP_SSL_ENABLED: "false"
         DATABASE_JDBC_URL: "jdbc:postgresql://xxxxxx:5000/ejbcadb"
       envRaw:
         - name: DATABASE_PASSWORD
           valueFrom:
             secretKeyRef:
               name: ejbca-credentials
               key: DATABASE_PASSWORD
         - name: DATABASE_USER
           valueFrom:
             secretKeyRef:
               name: ejbca-credentials
               key: DATABASE_USER
         - name: PASSWORD_ENCRYPTION_KEY
           valueFrom:
             secretKeyRef:
                name: ejbca-credentials
                key: PASSWORD_ENCRYPTION_KEY
         - name: CA_KEYSTOREPASS
           valueFrom:
             secretKeyRef:
                name: ejbca-credentials
                key: CA_KEYSTOREPASS
         - name: EJBCA_CLI_DEFAULTPASSWORD
           valueFrom:
             secretKeyRef:
                name: ejbca-credentials
                key: EJBCA_CLI_DEFAULTPASSWORD
         - name: APPSERVER_KEYSTORE_SECRET
           valueFrom:
             secretKeyRef:
                name: ejbca-credentials
                key: APPSERVER_KEYSTORE_SECRET
         - name: APPSERVER_TRUSTSTORE_SECRET
           valueFrom:
             secretKeyRef:
                name: ejbca-credentials
                key: APPSERVER_TRUSTSTORE_SECRET

However, when accessing the RA web page it says:

¹ Java Key Store (JKS) password is set to 'changeit'.

Executing keytool -list -keystore cacerts --storepass changeit in $JAVA_HOME/lib/security confirms this password.
Is there a way to change it during first time installation?

I don't think so for the first time installation. You could mount the keystore file instead and use a secret for the keystore password. That would be the recommended approach to have total control over that password. You could try using a init container to issue the keystore, update the password and then have the container launch.

I'll try that, thanks
Any reason why java.trustpassword=changeit is missing inside the pod? This should be in $ejbca_home/ejbca/conf/web.properties
According to the templates this should be customizable https://github.com/Keyfactor/ejbca-ce/blob/main/conf/web.properties.sample

I'll try that, thanks Any reason why java.trustpassword=changeit is missing inside the pod? This should be in $ejbca_home/ejbca/conf/web.properties According to the templates this should be customizable https://github.com/Keyfactor/ejbca-ce/blob/main/conf/web.properties.sample

The EJBCA container does this differently and does not use that setting. A random password is generated and used for the keystore. You can add a secret APPSERVER_KEYSTORE_SECRET for the keystore password.

Well, changeit isn't quite random isn't it ;) ?
As you can see from the above env, I already set a APPSERVER_KEYSTORE_SECRET but this doesn't have any effect on the keystore.
The initial password is still present.

OK, APPSERVER_KEYSTORE_SECRET only works when providing the keystore. I thought maybe Anton had done something in the helm chart, but that does not appear to be the case from your testing.

OK, but how is the keystore password used inside the container if its not coming from web.properties?
The keystore cacerts must be created during the startup with this secret.

the keystore password is used with the JKS that terminates TLS at the container. In Kubernetes you're not doing this unless you used the nodeport option I think. TLS is terminated at Ingress and sent back to EJBCA over the proxy port or if you had HTTPD in the pod that could also terminate TLS as well.

the keystore password is used with the JKS that terminates TLS at the container. In Kubernetes you're not doing this unless you used the nodeport option I think. TLS is terminated at Ingress and sent back to EJBCA over the proxy port or if you had HTTPD in the pod that could also terminate TLS as well.

I'm not sure I can follow you :) We are still discussing the keystore password for /usr/lib/jvm/java-11-slim/lib/security/cacerts ?
This keystore is part of the container image if I'm not wrong. How does EJBCA "know" the password for that keystore? Variable? Hard coded?
I can for sure mount a new keystore with a different password but how can I pass that password to EJBCA?

Maybe I misunderstand something though

the keystore password is used with the JKS that terminates TLS at the container. In Kubernetes you're not doing this unless you used the nodeport option I think. TLS is terminated at Ingress and sent back to EJBCA over the proxy port or if you had HTTPD in the pod that could also terminate TLS as well.

I'm not sure I can follow you :) We are still discussing the keystore password for /usr/lib/jvm/java-11-slim/lib/security/cacerts ? This keystore is part of the container image if I'm not wrong. How does EJBCA "know" the password for that keystore? Variable? Hard coded? I can for sure mount a new keystore with a different password but how can I pass that password to EJBCA?

Maybe I misunderstand something though

Whoa I'm way off! Sorry about the confusion. Yes the default cacerts file is in the container. The default should be changeit for that file. There is no way currently to provide a password for that file. There is a feature request for the container to support this, but I don't have an ETA when that will be.

What I think you can do is mount the cacerts file and then provide a a JAVA_OPTS_CUSTOM with the password for the file and the JVM settings. I think that would work.

e.g. -Xms2048m -Xmx4096m -Xss256k -XX:MetaspaceSize=160m -XX:MaxMetaspaceSize=512m -Djavax.net.ssl.trustStore=usr/lib/jvm/java-11-slim/lib/security/cacerts -Djavax.net.ssl.trustStoreType=jks -Djavax.net.ssl.trustStorePassword=newpassword