Keyfactor / ejbca-community-helm

Helm chart for deploying EJBCA in Kubernetes
GNU Lesser General Public License v2.1
12 stars 7 forks source link

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

Open chuegel opened 3 months ago

chuegel commented 3 months ago

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?

svenska-primekey commented 3 months ago

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.

chuegel commented 3 months ago

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

svenska-primekey commented 3 months ago

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.

chuegel commented 3 months ago

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.

svenska-primekey commented 3 months ago

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.

chuegel commented 3 months ago

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.

svenska-primekey commented 3 months ago

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.

chuegel commented 3 months ago

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

svenska-primekey commented 3 months ago

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