Howto Keycloak
- Documentation : https://www.keycloak.org/documentation
- Statut de cette page : test / bookworm
Keycloak est un Logiciel Libre permettant l’authentification unique (SSO) d’utilisateurs à diverses applications. Il supporte notamment le rotocole OpenID.
Installation
Pré-requis :
- installer PostgreSQL et avoir
/homeenexec - installer Nginx et certbot
On identifie la dernière version de Keycloak sur https://github.com/keycloak/keycloak/releases afin de l’utiliser ci-dessous.
# apt install openjdk-17-jre unzip
# useradd -r -m keycloak
# chmod 700 /home/keycloak
# su - keycloak
$ keycloak_release=26.5.6
$ keycloak_zip=keycloak-${keycloak_release}.zip
$ wget https://github.com/keycloak/keycloak/releases/download/${keycloak_release}/keycloak-${keycloak_release}.zip
$ unzip $keycloak_zip
$ keycloak_folder=${keycloak_zip%".zip"}
$ ln -s "${keycloak_folder}" keycloak
$./keycloak/bin/kc.sh --version
Keycloak 26.5.6
JVM: 17.0.18 (Debian OpenJDK 64-Bit Server VM 17.0.18+8-Debian-1deb12u1)
OS: Linux 6.1.0-42-cloud-amd64 amd64
On crée une configuration minimale dans
/home/keycloak/keycloak/conf/keycloak.conf :o
# su - keycloak
$ cp keycloak/conf/keycloak.conf keycloak/conf/keycloak.conf.ori
$ vim keycloak/conf/keycloak.conf
hostname=https://sso.example.com
http-enabled=true
proxy-headers=xforwarded
PostgreSQL
- Documentation : https://www.keycloak.org/server/db
On crée la configuration pour PostgreSQL :
# su - postgres
$ createuser -P keycloak
$ createdb -O keycloak keycloak
Et l’on met la configuration pour PostgreSQL dans
/home/keycloak/keycloak/conf/keycloak.conf
# su - keycloak
$ vim keycloak/conf/keycloak.conf
db=postgres
db-username=keycloak
db-password=PASSWORD
db-url=jdbc:postgresql://127.0.0.1/keycloak
On peut alors lancer Keycloak manuellement ce qui va créer les tables / données dans PostgreSQL :
$ ./keycloak/bin/kc.sh start
On peut aussi se connecter sur http://127.0.0.1:8080/ pour créer un identifiant admin et stocker les informations de façon sécurisée.
Une fois l’identifiant créé, on ne pourra plus se connecter sans passer par Nginx, donc on peut couper Keycloak.
Nginx
Il faut ensuite configurer Nginx et certbot, voici une configuration minimale :
server {
server_name sso.example.com
listen 80;
include /etc/nginx/snippets/letsencrypt.conf;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name sso.example.com;
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/sso.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sso.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port 443;
}
}
Unité Systemd
On crée une unité systemd pour lancer Keycloak :
# cat /etc/systemd/system/keycloak.service
[Unit]
Description=Keycloak server
After=network-online.target
Wants=network-online.target
[Service]
User=keycloak
Group=keycloak
ExecStart=/home/keycloak/keycloak/bin/kc.sh start
# Disable timeout logic and wait until process is stopped
TimeoutStopSec=0
# SIGTERM signal is used to stop the Java process
KillSignal=SIGTERM
# Send the signal only to the JVM rather than its control group
KillMode=process
# Java process is never killed
SendSIGKILL=no
# When a JVM receives a SIGTERM signal it exits with code 143
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
On peut ainsi lancer Keycloak :
# systemctl start keycloak
# systemctl status keycloak
● keycloak.service - Keycloak server
Loaded: loaded (/etc/systemd/system/keycloak.service; disabled; preset: enabled)
Active: active (running) since Mon 2026-02-02 11:51:11 CET; 11h ago
Main PID: 27409 (kc.sh)
Tasks: 56 (limit: 2328)
Memory: 510.7M
CPU: 1min 10.926s
CGroup: /system.slice/keycloak.service
├─27409 /bin/sh /home/keycloak/keycloak/bin/kc.sh start
└─27481 java -Djava.util.concurrent.ForkJoinPool.common.threadFactory=io.quarkus.bootstrap.forkjoin.QuarkusForkJoinWorkerThreadFactory -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF>
Et l’on peut se connecter avec l’identifiant préalablement créé sur https://sso.example.com/admin/ afin de créer un « realm » et les paramètres souhaités.
Configuration
Le fichier de configuration est
/home/keycloak/keycloak/conf/keycloak.conf.
On peut voir la configuration en cours via :
# su - keycloak
$ ./keycloak/bin/kc.sh show-config
La documentation complète de la configuration d’une instance en production : https://www.keycloak.org/server/configuration
Liste exhaustive des options de configuration : https://www.keycloak.org/server/all-config
Voici un exemple de configuration :
# Bdd
db=postgres
db-username=keycloak
db-password=A_CHANGER
db-url=127.0.0.1
# HTTPS
https-certificate-file=/home/keycloak/fullchain.pem
https-certificate-key-file=/home/keycloak/privatekey.key
# Proxy
proxy=reencrypt
# Port
https-port=8443
# Logs
log=console,file
log-level=info
log-file=/var/log/keycloak.log
# Observabilité et Monitoring
health-enabled=true
metrics-enabled=trueHostname
- Documentation : https://www.keycloak.org/server/hostname
En production, un client doit se connecter en utilisant le hostname indiqué dans la configuration :
On peut exposer la console d’administration sur un hostname différent de celui utilisé pour les clients :
Attention : nous avons observé que mettre l’interface d’administration sur un domaine différent peut contrarier le fonctionnement de l’impersonation
reverse proxy
- Documentation : https://www.keycloak.org/server/reverseproxy
On peut configurer le trafic entre le reverse proxy (Nginx dans notre cas) et Keycloak de différentes façons :
- edge : Terminaison SSL au niveau du proxy et communication avec keycloak en HTTP
- reencrypt : La terminaison SSL se fait au niveau du proxy inverse ET au niveau de keycloak, chacun ont une clé et un certificat (différent).
- passthrough : Terminaison SSL/TLS au niveau de Keycloak uniquement, le trafic HTTPS est forwardé par le proxy, le proxy n’a pas connaissance du contenu du trafic
Logging
Par défaut les logs ne sont pas stocker dans un fichier, on peut l’activer et indiquer un fichier (par défaut dans data/log/keycloak.log dans le dossier de Keycloak) :
Mise à jour
Pour mettre à jour on va rejouer l’installation avec la version désirée
$ keycloak_release=26.5.6
$ keycloak_zip=keycloak-${keycloak_release}.zip
$ wget https://github.com/keycloak/keycloak/releases/download/${keycloak_release}/keycloak-${keycloak_release}.zip
$ unzip $keycloak_zip
$ keycloak_folder=${keycloak_zip%".zip"}
On vérifie les différences entre les fichiers de configuration :
$ diff keycloak/conf/keycloak.conf.ori ${keycloak_folder}/conf/keycloak.conf
On copie le fichier original, puis on copie le fichier en intégrant les éventuelles différences :
$ cp ${keycloak_folder}/conf/keycloak.conf ${keycloak_folder}/conf/keycloak.conf.ori
$ cp keycloak/conf/keycloak.conf ${keycloak_folder}/conf/keycloak.conf
$ vim ${keycloak_folder}/conf/keycloak.conf
Puis on fait pointer le lien symbolique vers la nouvelle version et on restart :
$ rm keycloak
$ ln -s "${keycloak_folder}" keycloak
# systemctl restart keycloak
start-dev
Si l’on est pas en production, on peut lancer Keycloak en mode « dev » ainsi :
$ ./keycloak/bin/kc.sh start-dev
Il va alors se lancer sans base de données, sans besoin de SSL/TLS, etc.
On pourra se connecter sur http://127.0.0.1:8080/ pour créer un identifiant.
Attention, les paramètres utilisés ne sont valables que le temps d’un démarrage, si on le relance il faudra re-créer un identifiant et tous les paramètres.
Configuration avancée
Nginx
On conseille de limiter l’exposition des URLs en suivant les recommandations de https://www.keycloak.org/server/reverseproxy#_exposed_path_recommendations.
Voici un exemple de configuration Nginx plus fine :
location / {
deny all;
}
location ~ (^/realms/(?!master)/.*|^/resources/.*) {
proxy_pass http://127.0.0.1:8080;
}
location ~ (^/realms/master/.*|^/admin/.*|^/health/.*|^/metric/.*) {
proxy_pass http://127.0.0.1:8080;
include /etc/nginx/snippets/ipaddr_allowlist;
deny all;
}
Si besoin de donner un accès admin uniquement pour un realm en particulier :
location ~ (^/admin/foo/.*|^/admin/realms/foo|^/admin/serverinfo) {
proxy_pass http://127.0.0.1:8080;
}
Monitoring
https://www.keycloak.org/server/health
- On peut activer les endpoints de health check pour surveiller l’état de Keycloak
Cela va activer les endpoints /health,
/health/live, /health/ready et
/health/started. > Généralement, surveiller
health suffit, pour plus de détail : https://quarkus.io/guides/smallrye-health#running-the-health-check
Haute disponibilité (WIP)
Keycloak est conçu pour fonctionner en haute disponibilité avec infinispan (In-Memory Distributed Data Store)
TODO https://www.keycloak.org/server/configuration-production -> https://www.keycloak.org/server/caching
Proxy HTTP sortant
Il faut définir la variable d’environnement HTTP_PROXY
ou HTTPS_PROXY. Dans l’unité systemd, avant la ligne
ExecStart ajouter ligne :
Environment="HTTP_PROXY=http://127.0.0.1:3128/".
Puis exécuter systemctl daemon-reload et redémarrer le
service Keycloak.
Référence : https://www.keycloak.org/server/outgoinghttp
Fail2Ban
Voir HowtoFail2Ban
Administration
Options de démarrage
$ ./keycloak/bin/kc.sh start-dev --help
$ ./keycloak/bin/kc.sh start --help
Gestion des realms
Un realm (royaume) est un ensemble isolé d’utilisateurs et d’applications géré par un administrateur.
Le royaume master est utilisé pour gérer Keycloak et ne doit pas être utilisé pour gérer d’autres applications.
Tester le fonctionnement des royaumes voir getting-started-zip
suivre les étapes jusqu’a arriver au message “hello, myuser” sur https://www.keycloak.org/app/
Créer un royaume
Dans le menu déroulant tout en haut à gauche choisir “Create Realm”
Choisir un nom de royaume “Realm name” puis le créer avec “Create”
Créer un utilisateur
ATTENTION : nous allons créer un utilisateur dans le royaume sélectionné dans le menu déroulant tout en haut à gauche.
Créer client
Un client va être une application qui se referera à keycloak pour identifier ses utilisateur
Exemple Nextcloud : https://stackoverflow.com/questions/48400812/sso-with-saml-keycloak-and-nextcloud
User Federation
Connexion à LDAP : https://rob-ferguson.me/keycloak-flowable-and-openldap/
Mails
Chaque realm à une addresse email et une configuration de connexion à un serveur mail. On peut tester l’envoi de mail et utiliser les mails pour les mots de passe oubliés notamment.
Créer un utilisateur administrateur
Depuis la page d’accueil de l’interface d’administration, cliquer sur Users dans le volet à gauche.
Cliquer sur Add user.
Compléter les champs Username, seul obligatoire, et Email puis cliquer sur Create.
Une fois l’utilisateur créé et sélectionné, cliquer sur l’onglet Role mapping.
En haut à gauche de la fenêtre qui vient de s’ouvrir, choisir Filter by realm roles.
Sélectionner le role
adminpuis cliquer sur Assign.
Restaurer identifiant de l’utilisateur admin temporaire
$ ./keycloak/bin/kc.sh bootstrap-admin user
Le programme demande le nom de l’utilisateur puis son mot de passe.
Exporter et importer les royaumes
https://www.keycloak.org/server/importExport
Export
Il est recommandé d’arrêter tous les nœuds du cluster Keycloak avant de faire un export.
On peut exporter en un seul fichier :
$ ./keycloak/bin/kc.sh export --file dump.json
On peut aussi faire un export par royaume :
$ ./keycloak/bin/kc.sh export --dir dump/
On peut exporter avec des fichiers distincts par utilisateurs :
$ ./keycloak/bin/kc.sh export --dir dump/ --users different_files --users-per-file 100
On peut exporter sans les utilisateurs :
$ ./keycloak/bin/kc.sh export --dir dump/ --users skip
Attention, si vous avez une Federation LDAP, même sans « caching », les utilisateurs seront tout de même exportés et cela peut poser des problèmes à l’import, cf https://github.com/keycloak/keycloak/issues/46537
Import
Il faut arrêter tous les nœuds du cluster Keycloak avant de faire un import.
Pour importer un dump :
$ ./keycloak/bin/kc.sh import --file dump.json
Sauvegarde
Soit on utilise les exports/imports ci-dessus.
On peut aussi faire un dump de la base PostgreSQL et des fichiers tout simplement.
Gestion via CLI
https://www.keycloak.org/docs/latest/server_admin/#admin-cli
On peut faire toutes les opérations que l’on effectue dans
l’interface d’admin aussi via l’utilitaire de commande
kcadm.sh
Celui-ci va simplement parler localement à l’API REST de Keycloak
Quelques exemples : https://wjw465150.gitbooks.io/keycloak-documentation/content/server_admin/topics/admin-cli.html
Se connecter avec kcadm.sh :
$ ./keycloak/bin/kcadm.sh config credentials --server http://localhost:8080 --realm master --user jdoe --client admin-cli
Logging into http://localhost:8080 as user jdoe of realm master
Enter password:
Récuperer de la configuration et la mettre à jour :
# mettre à jour un client
keycloak@MACHINE:~/keycloak-26.1.1/bin$ ./kcadm.sh get clients/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -r master > master.client
keycloak@MACHINE:~/keycloak-26.1.1/bin$ vim master.client
keycloak@MACHINE:~/keycloak-26.1.1/bin$ ./kcadm.sh update clients/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -r master -f master.client
# realm
keycloak@MACHINE:~/keycloak-26.1.1/bin$ ./kcadm.sh get realms/master
FAQ
Ressources intéressantes
Configurer la durée de vie des sessions
On peux configurer la durée de vie “maximum” et “idle” des session pour un royaume.
- La durée de vie “idle” correspond à la durée de vie maximum d’une session à partir du moment où il n’y a plus d’activité
- La durée de vie “max” correspond à maximum de la durée de vie totale d’une session
On peut les configurer dans
admin.sso.exemple.com/admin/master/console/#/foorealm/realm-settings/sessions
Remapper un claim de token
On peut remapper sub pour qu’il corresponde a username par exemple
Dans : Client scopes >
<nom-client>-dedicated >
Configure a new mapper
Mapper type : User Property Name : sub Property : username Token Claim Name : sub Claim JSON Type : String
