wiki/HowtoKeycloak.md
Tom David--Broglio f048f6d3e0 typo
2024-03-01 12:09:06 +01:00

12 KiB


categories: security
title: HowtoKeycloak
...

Keycloak est un serveur d'authentification et d'autorisation écrit en Java, c'est un "Identity Access Manager" IAM open-source permettant de faire du Single-Sign-On et Single-Sign-Out SS0, c'est à dire d'utiliser un seul compte pour se connecter à différents services.

Installation

liens : documentation officielle, git de keycloak

Installer Keycloak sur son hote avec OpenJDK (openjdk-17 pour Keycloak 23)

Attention on installe keycloak dans un utilisateur non root keycloak avec comme groupe keycloak

  # apt install openjdk-17-jre

Lister les releases pour en choisir une

  $ git ls-remote --tags https://github.com/keycloak/keycloak
  ...
  99774b3f7a776476e7f04e472e13e3915971a6fb	refs/tags/23.x.x

Récupérer et extraire le zip de la release souhaitée

  $ keycloak_release=23.0.3
  $ 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 peut alors lancer Keycloak en mode dev pour tester ou développer des thèmes keycloak en configurant son admin:

  • Au lancement du serveur
  export KEYCLOAK_ADMIN=<username>
  export KEYCLOAK_ADMIN_PASSWORD=<password>
  bin/kc.sh start-dev
  • Ou en mode "click"

Se connecter à http://localhost:8080/ et créer un username et password admin

Se connecter à http://localhost:8080/admin avec les identifiant admin

Pour Lancer en production, il va falloir configurer d'autres elements, voirs configuration

Unitée Systemd

On peut wrapper keycloak dans une unitée systemd, adaptez Environment=... pour le nom et mod de passe de l'administrateur et ExecStart si besoin.

Attention on ne crée pas une unitée utilisateur

# vim /etc/systemd/system/keycloak.service
[Unit]
Description=Keycloak server
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service

[Service]
User=keycloak
Group=keycloak
Environment="KEYCLOAK_ADMIN=evolix"
Environment="KEYCLOAK_ADMIN_PASSWORD=MOTDEPASSEADMIN"
ExecStart=/home/keycloak/keycloak-23.0.6/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

Configuration pour de la production

Configuration d'une instance/server de prodution...

On peut spécifier de la configuration via des envs, arguments, fichier de configuration et KeyStore java. Celle-ci sera prise en comte dans cette ordre precedence (des env pourrons surcharger la conf en dur par exemple)

On peut voir la configuration qui sera chargé en jouant $keycloak_folder/bin/kc.sh show-config

Ici pour simplifier, on configurera via l'instance via son fichier de configuration dans $keycloak_folder/conf/keycloak.conf

Remarque : la configuration par envs et arguments est persisté par Quarkus

Base de données

Keycloak en production a besoin d'un accès à une base de donnée

lien : documentation keycloak configuration bdd

Il faut créer une base de donnée keycloak et utilisateur associé pour Keycloak

Si on utilise un autre nom de base, il faut alors specifier db-schema dans la configuration

# The database vendor.
db=postgres
# The username of the database user.
db-username=keycloak
# The password of the database user.
db-password=CHANGEZMOI
# The hostname of the default JDBC URL of the chosen vendor.
db-url-host=127.0.0.1

On peut spécifier en plus si besoin db-url-port pour le port ou même db-url pour spécifier entièrement l'URL jdbc

  • Configuration via arguments au démarrage
  bin/kc.sh start --db mariadb --db-url-host mymariadb --db-username evocloak --db-password change_me

Hostname

https://www.keycloak.org/server/hostname

En production, un client doit se connecter en utilisant le hostname indiqué dans la configuration :

# Hostname for the Keycloak server.
hostname=test.example.org

De plus il est fortement recommandé d'exposer la console d'administration sur un hostname différent de celui utilisé pour les clients

# Hostname for the Keycloak server.
hostname-admin=adm-test.example.org

Dans ce cas, il faudra utiliser un proxy-inverse pour contrôler les accès des hostnames.

SSL/TLS

https://www.keycloak.org/server/enabletls

On ne doit jamais exposer une instance de production en HTTP.

  • Pour un contrôle d'accès fin, il faudra utiliser un proxy-inverse
  • Sinon nous allons configurer celle-ci en HTTPS/TLS

Pour cela, nous avons besoin d'un certificat et de sa clef privé pour le hostname choisi... voir HowtoSSL ou HowtoLetsEncrypt par exemple...

# Chemin vers le certificat en format PEM
https-certificate-file=/home/keycloak/keycloak_certificat.crt

# Chemin vers la clef privé en format PEM
https-certificate-key-file=/home/keycloak/keycloak_private.key

Proxy inverse

Documentation : https://www.keycloak.org/server/reverseproxy

  • edge : Terminaison SSL au niveau du proxy et communication avec keycloak en HTTP

Attention : dans ce mode le traffic entre le proxy est donc en clair. Le reseaux interne doit être sécurisé.

  • reencrypt : La terminaison SSL se fait au niveau du proxy inverse ET au niveau de keycloak, chacun ont une clef et un certificat (different). C'est utile dans un environnement ou le reseaux interne doit aussi être protégé, cela permet aussi au reverse proxy de voir le contenu des requêtes

    Requires communication through HTTPS between the proxy and Keycloak. This mode is suitable for deployments where internal communication between the reverse proxy and Keycloak should also be protected. Different keys and certificates are used on the reverse proxy as well as on Keycloak.

  • passthrough : Terminaison SSl au niveau de keycloak uniquement, le trafique https est forwardé par le proxy. Le proxy n'a pas connaissance du contenu du traffique

    The proxy forwards the HTTPS connection to Keycloak without terminating TLS. The secure connections between the server and clients are based on the keys and certificates used by the Keycloak server.

proxy=reencrypt
hostname-url=https://sso.example.org

Exemple avec Nginx

On utilise Nginx avec keycloak en mode reencrypt, de cette maniere keycloak peut utiliser un certificat autosigné et Nginx fait la terminaison ssl d'un client. Cela nous permet d'utiliser letsencript :

$ vim /etc/nginx/sites-available/keycloak.conf
server {
  server_name sso.example.org;
  listen 80;
  include /etc/nginx/snippets/letsencrypt.conf;
  location / {
    return 301 https://$host$request_uri;
  }
}

server {
  server_name sso.example.org;
  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 https://127.0.0.1:8443;

       proxy_redirect off;
       proxy_set_header Host $host;
       # proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $remote_addr;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_set_header X-Forwarded-Port 443;
  }
}

Voir HowtoSSL et HowtoNginx. Il faut notamment que le port 80 soit accessible à tous.

Exemple de configuration

Exemple de configuration complete de $keycloak_folder/conf/keycloak.conf

# 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=true

Configuration avancée

Logging

  • Par défaut les logs ne sont pas persisté dans un fichier, on peut l'activer et indiquer un fichier (par défaut dans data/log/keycloak.log dans le dossier de keycloak)
log=console,file
log-level=debug
log-file=/var/log/keycloak.log

Monitoring

https://www.keycloak.org/server/health

  • On peut activer les endpoints de health check pour surveiller l'état de keycloak
health-enabled=true

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

Administration

Lancer Keycloak en mode dev, pour tester Keycloak en http avec des valeurs par defaut ou en mode prod

Remarque avec l'untiée systemd, utiliser des start, stop etc.

  $ cd $keycloak_folder
  $ bin/kc.sh start-dev
  
  $ bin/kc.sh start

Voir les option de démarrage / aide

  bin/kc.sh start-dev --help
  bin/kc.sh start --help

Lancer Keycloak en dev sur le port 8080

  keycloak_http_port=8080
  bin/kc.sh start-dev --http-port ${keycloak_http_port}

Gestion des royaumes "realm"

Un royaume est un ensemble isolé d'utilisateurs et d'applications géré par un administrateur

Le royaume master est seulement utilisé pour gérer Keycloak et ne doit pas être utiliser pour gérer d'autres applications

Tester le fonctionnement des royaume 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, sauf cas particulier, il faudra éviter le royaume master

Créer client

TODO ajouter nextcloud https://stackoverflow.com/questions/48400812/sso-with-saml-keycloak-and-nextcloud

User Federation permet d'avoir acces à LDAP et Active Directory
TODO Connection au à OpenLDAP https://rob-ferguson.me/keycloak-flowable-and-openldap/

TODO Identity providers

TODO Gestion via la cli

documentation keycloak

Ressources

https://github.com/thomasdarimont/awesome-keycloak

https://rob-ferguson.me/