Run Keycloak Server in Docker Containers with Let’s Encrypt SSL

Posted on 130 views

An SSO(Single Sign-On) is a system that allows access to multiple independent, software systems using the same credentials. This simply means that with a single authentication, you can log into several services without providing a password. SSO systems are popular nowadays with Google, Facebook e.t.c using it. Today, there are many SSO servers, they include OneLogin, okta e.t.c

Keycloak is an open-source SSO provider that supports multiple protocols such as OpenID Connect and SAML 2.0. This Identity and Access Management System allows one to easily add authentication to an application and secure it. You can easily enable social login or use an existing Active Directory/LDAP.

Keycloak is a very extensible and highly configurable tool that offers the following features:

  • User Federation – It allows one to sync users from Active Directory and LDAP servers.
  • Kerberos bridge – It can be used to automatically authenticate the users logged in to the Kerberos server.
  • Theme support – Customize its interface to integrate with your applications as desired.
  • Two-factor Authentication Support – It offers support for HOTP/TOTP via Google Authenticator or FreeOTP.
  • Social Login – You can enable login with GitHub, Google, Facebook, Twitter and other social networks.
  • It offers Single-Sign-On and Single-Sign-Out for browser applications.
  • Identity Brokering – it allows one to authenticate with external SAML or Open ID identity providers.
  • Session management – the admins can view and manage the user sessions.
  • Client adapters for JavaScript applications, JBoss EAP, WildFly, Fuse, Jetty, Tomcat, Spring, etc.

Below is an illustration of the Keycloak Architecture.

network-987x1024@2x-987x1024

This guide offers the required knowledge on how to run Keycloak Server in Docker Containers with Let’s Encrypt SSL.

Getting Started.

We will begin by installing the required packages for this setup.

## On Debian/Ubuntu
sudo apt update && sudo apt upgrade
sudo apt install curl vim git

## On RHEL/CentOS/RockyLinux 8
sudo yum -y update
sudo yum -y install curl vim git

## On Fedora
sudo dnf update
sudo dnf -y install curl vim git

Step 1 – Install Docker and Docker-Compose on Linux

This guide requires one to have docker and docker-compose installed. Below is a dedicated guide to help you install Docker on Linux.

Verify the installation as below:

$ docker -v
Docker version 20.10.14, build a224086

Add your system user to the docker group.

sudo usermod -aG docker $USER
newgrp docker

Start and enable the docker service on your system.

sudo systemctl start docker && sudo systemctl enable docker

Step 2 – Create the Database Container.

It is important to have a database when deploying the Keycloak Server Container. In this guide, we will run the PostgreSQL database container.

Create a network for Keycloak.

docker network create keycloak-network

Run PostgreSQL in the pod.

docker run --name db \
  --net keycloak-network \
  -e POSTGRES_USER=admin \
  -e POSTGRES_PASSWORD=Passw0rd \
  -e POSTGRES_DB=keycloakdb \
  -d docker.io/library/postgres:latest

View the container.

$ docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS      NAMES
479b1599d5a0   postgres:latest   "docker-entrypoint.s…"   12 seconds ago   Up 10 seconds   5432/tcp   db

Step 3 – Provisioning the Keycloak Server Container.

This guide provides two methods on how you can provision the Keycloak Server Container. These are:

  • Building your optimized Keycloak docker image
  • Using ready Keycloak docker image

1. Building your optimized Keycloak docker image

You can build your own Keycloak image with token exchange feature, health and metrics endpoints enabled, and uses the PostgreSQL database from the below Dockerfile.

vim Dockerfile

Add the below lines to the file

FROM quay.io/keycloak/keycloak:latest as builder

ENV KC_HEALTH_ENABLED=true
ENV KC_METRICS_ENABLED=true
ENV KC_FEATURES=token-exchange
ENV KC_DB=postgres

# Install custom providers
RUN curl -sL https://github.com/aerogear/keycloak-metrics-spi/releases/download/2.5.3/keycloak-metrics-spi-2.5.3.jar -o /opt/keycloak/providers/keycloak-metrics-spi-2.5.3.jar
RUN /opt/keycloak/bin/kc.sh build

FROM quay.io/keycloak/keycloak:latest
COPY --from=builder /opt/keycloak/ /opt/keycloak/
WORKDIR /opt/keycloak

# For demonstration purposes only, please make sure to use proper certificates in production instead
RUN keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore conf/server.keystore

# Change these values to point to a running postgres instance
ENV KC_DB_URL=jdbc:postgresql://db/keycloakdb
ENV KC_DB_USERNAME=admin
ENV KC_DB_PASSWORD=Passw0rd
ENV KC_HOSTNAME=localhost

ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start"]

Remember to replace the database credentials and the IP address in the DB_URL appropriately before we proceed to build the image.

docker build . -t keycloak_image

Once the image has been built, view it:

$ docker images
REPOSITORY                  TAG       IMAGE ID       CREATED          SIZE
keycloak_image              latest    c7e3a15f28de   5 seconds ago    754MB
                          faf55943f0f2   13 seconds ago   734MB
quay.io/keycloak/keycloak   latest    a669b057e631   36 hours ago     562MB
postgres                    latest    74b0c105737a   44 hours ago     376MB

Now run Keycloak in the created pod using the optimized image.

  • In production mode (with secure defaults)
docker run --name keycloak --net keycloak-network -p 8443:8443 -e KEYCLOAK_ADMIN=myadmin -e KEYCLOAK_ADMIN_PASSWORD=StrongPassw0rd -d keycloak_image

The container will be created as below:

$ docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED         STATUS         PORTS                                                 NAMES
78eb8a3e6ecc   keycloak_image    "/opt/keycloak/bin/k…"   4 seconds ago   Up 3 seconds   8080/tcp, 0.0.0.0:8443->8443/tcp, :::8443->8443/tcp   keycloak
f6f538e7c097   postgres:latest   "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   0.0.0.0:5432->5432/tcp, :::5432->5432/tcp             db

Once complete, the container should be accessible on port 8443 can be accessed using the URL https://IP_address:8443

The health checkpoints are:

Metrics are available at:

2. Using ready Keycloak docker image

You can also use the ready Keycloak docker image. The command below shows how you can run a standard Keycloak image.

docker run -d \
  --net keycloak-network \
  --name keycloak \
  -e KEYCLOAK_USER=myadmin \
  -e KEYCLOAK_PASSWORD=StrongPassw0rd \
  -p 8080:8080 \
  -p 8443:8443 \
  -e KEYCLOAK_DB=postgres \
  -e KEYCLOAK_FEATURES=token-exchange \
  -e KEYCLOAK_DB_URL=jdbc:postgresql://db/keycloakdb \
  -e KEYCLOAK_DB_USERNAME=admin \
  -e KEYCLOAK_DB_PASSWORD=Passw0rd \
  jboss/keycloak

Remember to replace the database and Keycloak admin user credentials.

Check the status of the container.

$ docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED             STATUS             PORTS                                                                                  NAMES
a910a9eaa5e1   jboss/keycloak    "/opt/jboss/tools/do…"   5 seconds ago       Up 4 seconds       0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:8443->8443/tcp, :::8443->8443/tcp   keycloak
8f5e593eb517   postgres:latest   "docker-entrypoint.s…"   About an hour ago   Up About an hour   5432/tcp                                                                               db

Step 4 – Access and Use Keycloak Server

Access Keycloak using the URL https://IP_address:8443

Run-Keycloak-Server-in-Docker-Containers-with-Lets-Encrypt-SSL-1

Proceed to the admin console and log in using the created user.

Run-Keycloak-Server-in-Docker-Containers-with-Lets-Encrypt-SSL-2

With the correct user credentials provided, you will be authenticated to the dashboard below.

Run-Keycloak-Server-in-Docker-Containers-with-Lets-Encrypt-SSL-3-1024x478

We already have a Realm created, we will proceed and add a new client in the Clients tab.

Run-Keycloak-Server-in-Docker-Containers-with-Lets-Encrypt-SSL-4-1024x465

Provide the details for the client.

Run-Keycloak-Server-in-Docker-Containers-with-Lets-Encrypt-SSL-5-1024x482

Provide the URL path of your application under “Valid redirect URL“.

Run-Keycloak-Server-in-Docker-Containers-with-Lets-Encrypt-SSL-6

You can also create a new user in the user tab.

Run-Keycloak-Server-in-Docker-Containers-with-Lets-Encrypt-SSL-7

Proceed to the Credentials tab and set the password for the user.

Run-Keycloak-Server-in-Docker-Containers-with-Lets-Encrypt-SSL-8

Assign roles to the created user in the roles tab

Run-Keycloak-Server-in-Docker-Containers-with-Lets-Encrypt-SSL-9

That was a brief demonstration on how to get started with Keycloak.

Step 5 – Secure Keycloak with Let’s Encrypt SSL

It is necessary to secure your Keycloak server with SSL certificates to prevent the credentials from traveling along the unprotected wire. In this guide, we will use Let’s Encrypt to issue free trusted SSL certificates for our domain name.

First, install and configure a reverse proxy with Nginx.

##On RHEL 8/CentOS/Rocky Linux 8/Fedora
sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm 
sudo yum install nginx certbot python3-certbot-nginx

##On Debian/Ubuntu
sudo apt install nginx certbot python3-certbot-nginx

Proceed and create a Virtual Host file.

sudo vim /etc/nginx/conf.d/keycloak.conf

The file will contain the below lines.

server 
    listen 80;
    server_name keycloak.example.com;
    client_max_body_size 25m;

   location / 
   proxy_pass https://localhost:8443/;
   proxy_set_header Host $http_host;
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-Proto $scheme;
  

  error_page 404 /404.html;
  location = /40x.html 


  error_page 500 502 503 504 /50x.html;
  location = /50x.html 

Save the file restart and enable Nginx

sudo systemctl restart nginx
sudo systemctl enable nginx

Proceed and generate SSL certificates for the domain name with the command:

sudo certbot --nginx

Proceed as below.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): Enter a valid Email address here          

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y
Account registered.

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: keycloak.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1

Requesting a certificate for keycloak.example.com
Performing the following challenges:
http-01 challenge for keycloak.example.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/conf.d/keycloak.conf

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in /etc/nginx/conf.d/keycloak.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://keycloak.example.com
...

Now proceed and access your Keycloak server with HTTPS using the URL https://domain_name

Run-Keycloak-Server-in-Docker-Containers-with-Lets-Encrypt-SSL-10

Closing Thoughts.

This guide not only provides the required knowledge on how to run the Keycloak Server in Docker Containers with Let’s Encrypt SSL but also knowledge on how to get started with the Keycloak SSO system.

 

coffee

Gravatar Image
A systems engineer with excellent skills in systems administration, cloud computing, systems deployment, virtualization, containers, and a certified ethical hacker.