How can I add SSL in keycloak in docker

Viewed 15642

I'm having an issue adding SSL certificate to Keycloak that is running on docker. I got an SSL Certificate from AWS EC2 with Load Balancer, but don't know how to add it to Keycloak on docker. I was looking through Google but nothing found yet.

Also when i go to page like: https://stackoverflow.com, the ssl works perfectly. But when I try to open https://stackoverflow.com:8443 (since 8443 is the port of Keycloak) its not working.

Here's the code of Dockerfile of Keycloak:

FROM jboss/keycloak:4.6.0.Final

WORKDIR /opt/jboss/keycloak

COPY realm-export.json /opt/jboss/keycloak/

EXPOSE 8443

ENTRYPOINT [ "/opt/jboss/tools/docker-entrypoint.sh" ]
CMD ["-b", "0.0.0.0", "-bmanagement", "0.0.0.0", "-Dkeycloak.import=realm-export.json -Dkeycloak.migration.strategy=OVERWRITE_EXISTING"]

And here's the docker-compose.yml file:

version: '2'

services:
  keycloak:
    build: "./Keycloak + actibook-app client import"
    depends_on:
      - keycloak-postgres
    environment:
      - KEYCLOAK_USER=${KEYCLOAK_USER}
      - KEYCLOAK_PASSWORD=${KEYCLOAK_PASSWORD}
      - KEYCLOAK_IMPORT=${KEYCLOAK_IMPORT}
      - POSTGRES_USER=${KEYCLOAK_DATABASE_USER}
      - POSTGRES_PASSWORD=${KEYCLOAK_DATABASE_PASSW}
      - POSTGRES_PORT_5432_TCP_ADDR= keycloak-postgres
    ports:
      - "8443:8443"
    labels:
      - "traefik.frontend.passHostHeader=true"

  traefik:
    build: ./traefik
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    restart: unless-stopped
5 Answers

README is a good friend - https://hub.docker.com/r/jboss/keycloak/:

Setting up TLS(SSL)

Keycloak image allows you to specify both a private key and a certificate for serving HTTPS. In that case you need to provide two files:

tls.crt - a certificate
tls.key - a private key

Those files need to be mounted in /etc/x509/https directory. The image will automatically convert them into a Java keystore and reconfigure Wildfly to use it.

But that is only Keycloak TLS container configuration. You are using also Traefik, so you may need to configure TLS in Traefik container - it depends on your configuration.

You will need to make sure the key file is readable by jboss user inside the docker. Here are some key steps in my solution: 1. get cert/key from let's encrypt. 2. change file mode to 655 3. mount them to keycloak: - /opt/www/sso/cert/fullchain.pem:/etc/x509/https/tls.crt - /opt/www/sso/cert/privkey.pem:/etc/x509/https/tls.key 4. launch docker image 5. change file mode back to 600 for the key file.

Steps mentioned in docker documentation are absolutely correct. And same have been quoted by others in above answers. I just want to point out the script which is used to read the mounted certificates & key and then keystores are generated on the fly.

One can refer to the script at path /opt/jboss/tools/x509.sh inside the container or refer it from the github. This was helpful to me in debugging the same.

One must absolutely make sure that they are uploading the key and certificate to the exact path and folder with appropriate permissions. Also, name of the key should tls.key and certificate should be tls.crt as same have been hardcoded in the script.

Bonus: Same script is used to add CA files to the truststore which is also generated on the fly. Hence, if your keycloak is communicating with other https servers, do not forget to mount root CA files to the keycloak container and pass the environment variable as below.

X509_CA_BUNDLE=/path/to/root1.pem /path/to/root2.pem

Also, make sure that the ca files are in PEM format and having appropriate permissions.

I'm below comment rep. level so I'm adding an answer here. My assumption is that all of your components are docker containers.

@Jan Garaj's answer is correct in principle. What's not clear is that the logical routing in your case looks like this (service side):

service --> Keyclaok --> traefik --> network/dns --> user/browser

The actual routing looks like this (i.e. common bridge docker network assumed):

service
   |---------> traefik --> network/dns --> user/browser
keyclaok
  • Keycloak is creating a self signed cert between itself and Traefik
    • you have to specify a volumes: directive in Keyclaok's docker-compose.yml file (as mentioned earlier).
  • If you just want to test that Keycloak is working you can add InsecureSkipVerify = true to the top of your Traefik config file (i.e. traefik.toml).
  • Once you've established that Keycloak is accessible you should either use the AWS cert-pair or create your own self signed cert (with a personal certificate authority).

Just insert in docker-compose.yml in service keycloak user: root

The keycloak image is installed as root but the execution of the container is done as jboss, but the directory permissions do not allow jboss to create the jks to do https.

If you run the container as root it works.

Another alternative is to create a new image by modifying the permissions of the directories where you store the certificates.

Related