How can I add SSL in keycloak in docker

13,639

Solution 1

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.

Solution 2

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.

Solution 3

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.

Share:
13,639
TimeFrame
Author by

TimeFrame

Updated on June 04, 2022

Comments

  • TimeFrame
    TimeFrame almost 2 years

    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
    
    • rckrd
      rckrd over 5 years
      Why are you publishing the port 8443? When using a reverse proxy for http/https like Traefik the only public published port should be 80 and 443. The "backend"-containers should only be accessible on the private network.
    • TimeFrame
      TimeFrame over 5 years
      @rckrd well how can I access to keycloak in that port other way?
    • TimeFrame
      TimeFrame over 5 years
      @rckrd when you want to login, the app should redirect you to Keycloak login page https://domain:8443/login, so I cant do it other way than accessing the current port
    • rckrd
      rckrd over 5 years
      My suggestion is to read up on the purpose of a reverse proxy en.m.wikipedia.org/wiki/Reverse_proxy
    • TimeFrame
      TimeFrame over 5 years
      @rckrd yep i did it. But the problem is that I dont know how else can I access to that keycloak service
    • rckrd
      rckrd over 5 years
      I would configure traefik to serve keycloak on a subdomain such as account.example.com . I.e reqs to account.example.com is forwarded on the private network to the container running keycloak
    • TimeFrame
      TimeFrame over 5 years
      @rckrd so that would be the only option right? I guess to make that happen i should add traefik.frontend.rule=Host:account.example.com at keycloak service label in docker-compose.yml? And then at the domain need to point it to redirect to public ip of the server?
    • rckrd
      rckrd over 5 years
      Yes, sounds like a good solution
  • TimeFrame
    TimeFrame over 5 years
    Do i need to provide these as volumes in docker-compose.yml and then call tls.crt and tls.key each to a file that contains certificate and private key, or should I call them as flags here in DockerFile CMD ["-b", "0.0.0.0", "-bmanagement", "0.0.0.0", "-Dkeycloak.import=realm-export.json -Dkeycloak.migration.strategy=OVERWRITE_EXISTING"]
  • rckrd
    rckrd over 5 years
    The Asker wrote that a load balancer is used. Why would the certificates be configured on keycloak? The ssl should be terminated at the load balancer, right?
  • TimeFrame
    TimeFrame over 5 years
    @rckrd well the problem is that, when I'm trying to open 'https://stackoverflow.com:8443 which 8443 port is Keycloak port, the SSL is not working. I guess the Keycloak is generating a self-signed certificate by default
  • Jan Garaj
    Jan Garaj over 5 years
    @rckrd Keycloak is a security/auth component - it is always a good idea to use TLS for communication also behind LB. It is not clear what is a role of Traefik here. Is it a router or LB + where is terminated TLS connection, ....?
  • TimeFrame
    TimeFrame over 5 years
    @JanGaraj the person wanted to have the traefik as a reverse proxy implemented
  • Balbinator
    Balbinator almost 4 years
    What made the deal for me was mapping the port 8443 and changing the file permissions to 655 before running the stack. I do believe that the dockerhub lacks the documentation of the SSL mode.
  • maximus
    maximus over 2 years
    Thanks for the hint about file permission. In case any one need it, below are the commands that I used to run my keycloak docker: chmod 655 /home/test/keycloak.* and docker run -d --name keycloak --net keycloak-network -p 8443:8443 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin --mount type=bind,source=/home/test/keycloak.key,target=/etc/x509/ht‌​tps/tls.key --mount type=bind,source=/home/test/keycloak.crt,target=/etc/x509/ht‌​tps/tls.crt jboss/keycloak