2

I use Dockerfile to create an image for our web app which requires HTTPS. However, I am getting Certificate not imported, alias <my-cert-name> already exists Java exception. When I tried without using Dockerfile, just from command line, I was able to delete the existing alias and export, import worked. But not with Dockerfile. Any ideas? Thanks!

Dockerfile:

  FROM openjdk:8-alpine

  #Starting https and certs configuration
  #Make directory for certs inside the container
  RUN mkdir -p usr/app/ssl/certs/

  #Copy certs from local to the container
  COPY myWebApp/src/main/resources/PT/certificates/my-cert-name.jks usr/app/ssl/certs/
  COPY myWebApp/src/main/resources/PT/certificates/trustStore.jks usr/app/ssl/certs/

  #Export/Import certificate 
  RUN cd usr/app/ssl/certs/ && \
      keytool -delete -alias my-cert-name -keystore my-cert-name.jks -storepass password123! && \
      keytool -export -alias my-cert-name -keystore my-cert-name.jks -file my-cert-name.crt -storepass password123! && \
      keytool -importcert -keystore trustStore.jks -alias my-cert-name -storepass password123! -file my-cert-name.crt -noprompt
  #Ending https and certs configuration

  RUN mkdir -p /usr/app/myweb

  COPY myWebApp/target/myWeb.war /usr/app/myweb

  CMD java -Xms512M -Xmx6144M -XX:MaxMetaspaceSize=3072M -jar /usr/app/myweb/myWeb.war
  EXPOSE 8080

Docker build command

  >docker build -it test-https-image .

Env:

 Using Docker desktop on windows 10. 

Thanks in advance!

fongfong
  • 175
  • 3
  • 14

1 Answers1

3

I prefer the notation:

RUN cd usr/app/ssl/certs/ && \
    keytool -delete -alias my-cert-name -keystore my-cert-name.jks -storepass password123! && \
    keytool -export -alias my-cert-name -keystore my-cert-namet.jks \
      -file my-cert-name.crt -storepass password123! && \
    keytool -importcert -keystore trustStore.jks -alias my-cert-name -storepass password123! \
      -file my-cert-name.crt -noprompt

It is easier to double-check you are importing the same name you have deleted.
(since -delete is a good way to force update an existing certificate)

But the gist is:

  • you delete in my-cert-name.jks, while you import in trustStore.jks.
  • if the import fails, that means trustStore.jks already has a certificate for that name

If that certificate was already in the copied keystore, I would not export/re-import it. (I only imported it in my previous answer)

Make sure the "usr/app/ssl/certs" is the right path: I would rather use an absolute path, rather than a relative path.

The OP fongfong confirms in the comments:

I should delete the existing alias from trustStore.jks, not my-cert-name.jks

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thank you VonC! I updated my question using the notation you suggested. When you said "I would not export/re-import it. (I only imported it in my previous answer)". Could you explain it more? How to check if the alias already exits or not? If it is there, what if I want to update it with anew one but has the same alias? Thanks! – fongfong Feb 17 '20 at 13:22
  • @fongfong "I only imported it in my previous answer": then why do I see "keytool -export"? Isn't it an export? – VonC Feb 17 '20 at 13:23
  • Based on the instruction that I was provided, it does `-export` first and then `-importcert`. Let me find out why. Another question, I see people copy cert to `$JAVA_HOME/jre/lib/security` and then do import, does the cert (.jks) have to be `$JAVA_HOME/jre/lib/security`? No, right? I was able to run those command locally under `myWebApp/src/main/resources/PT/certificates/` directory, my java is jdk1.8. Any thoughts on this? Thanks! – fongfong Feb 17 '20 at 13:36
  • @fongfong If you want any java process to know of your certificate, then yes, you would need to modify the `$JAVA_HOME/jre/lib/security/cacerts` keystore file. – VonC Feb 17 '20 at 13:41
  • So I need to do this `#Copy certs from local to the container COPY myWebApp/src/main/resources/PT/certificates/my-cert-name.jks /etc/ssl/certs/java/cacerts COPY myWebApp/src/main/resources/PT/certificates/trustStore.jks /etc/ssl/certs/java/cacerts` using `/etc/ssl/certs/java/cacerts` directory instead? Thanks! – fongfong Feb 17 '20 at 14:02
  • @fongfong copy? No. cacerts is modified, not overridden by another file. It has other certificates which needs to still be there. – VonC Feb 17 '20 at 14:03
  • @ VonC: We are provided with two files `my-cert-name.jks` and 'trustStore.jks`. So we need to copy them from local to container somewhere so that we can `export` and 'importcert` inside the container for our app to use. I thought those files can be anywhere that makes sense, then we run `keytool` commands which will import them to `/etc/ssl/certs/java/cacerts`. Is this how it works? Please advice. Thanks! – fongfong Feb 17 '20 at 14:16
  • @fongfong Why not, but do you have a link to those instructions? "Then we run `keytool` commands which will import them to `/etc/ssl/certs/java/cacerts`". Possibly. This is not what you were doing in your question though. – VonC Feb 17 '20 at 14:21
  • In my question, I copy those two files `my-cert-name.jks` and `trustStore.jks` to `usr/app/ssl/certs/` which I `mkdir`. Then I `cd` to ` usr/app/ssl/certs/ ` to use `keytool ` commands. The instruction was given by an external resource from a different company. I also checked the `https://docs.oracle.com/cd/E19798-01/821-1751/ghlgv/index.html`. Thanks! – fongfong Feb 17 '20 at 14:43
  • @fongfong Can you do a keytool -list of `trustStore.jks` (where you want to import), to check if the name of the certificate is not already present? If it is present, then the `keytool -delete` ought to be applied on `trustStore.jks`, not on `my-cert-name.jks` – VonC Feb 17 '20 at 14:49
  • @ VonC Thanks! let me try that. And also, if I see `https://localhost:8080` shows `not secure` does it mean that I installed the `certificate` successfully at least, right? If the certificate is not valid, I see that error in the browser, but at least it shows that my keytool commands worked. Is that right? Thanks! – fongfong Feb 17 '20 at 15:47
  • @fongfong It means it does not recognize the certificate (the trust chain is not complete) Make sure to add it to your browser keystore, in order for said browser to trust it. – VonC Feb 17 '20 at 15:51
  • Hi VonC: I got it this time. I misunderstood from your first reply. I should delete the existing alias from `trustStore.jks` not `my-cert-name.jks`. Thanks again for your help! – fongfong Feb 18 '20 at 03:53