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.
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
<none> <none> 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:
- https://localhost:8443/health
- https://localhost:8443/health/ready
- https://localhost:8443/health/live
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
Proceed to the admin console and log in using the created user.
With the correct user credentials provided, you will be authenticated to the dashboard below.
We already have a Realm created, we will proceed and add a new client in the Clients tab.
Provide the details for the client.
Provide the URL path of your application under “Valid redirect URL“.
You can also create a new user in the user tab.
Proceed to the Credentials tab and set the password for the user.
Assign roles to the created user in the roles tab
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
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.
Related guides:
- How To Run Ghost CMS in Docker Containers
- How To Run Graylog Server in Docker Containers
- How To Run Plex Media Server in Docker Containers