
---
  categories: security  
  title: HowtoKeycloak  
...

[Keycloak](https://www.keycloak.org/) 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](https://www.keycloak.org/getting-started/getting-started-zip), [git de keycloak](https://github.com/keycloak/keycloak/releases)

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

```{.bash}
  # apt install openjdk-17-jre
```

Lister les releases pour en choisir une

```{.bash}
  $ 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

```{.bash}
  $ 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*

```{.bash}
  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](#configuration)

### Unitée Systemd

On peut wrapper keycloak dans une unitée systemd, adaptez `ExecStart`

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

[Service]
ExecStart=/root/keycloak-23.0.3/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

* 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>

### Base de données

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

lien : [documentation keycloak configuration bdd](https://www.keycloak.org/server/db)

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

* [HowtoPostgreSQL](/HowtoPostgreSQL.md#créer-un-utilisateur-et-une-base-de-données)

* [HowtoMySQL](/HowtoMySQL.md#créer-une-base-de-données-et-un-utilisateur-associé)

* Configuration via fichier configuration `keycloak.conf`

```{.ini}
# 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](/Glossaire.md#odbcjdbc)

* Configuration via arguments au démarrage

```{.bash}
  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 :

```{.ini}
# 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

```{.ini}
# Hostname for the Keycloak server.
hostname-admin=adm-test.example.org
```

> Dans ce cas, il faudra utiliser un [proxy-inverse](#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](#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](/HowtoSSL.md#générer-un-certificat-auto-signé) ou [HowtoLetsEncrypt](/HowtoLetsEncrypt.md#génération-du-certificat) par exemple...

```{.ini}
# The file path to a server certificate or certificate chain in PEM format.
https-certificate-file=/root/keycloak_certificat.crt

# The file path to a private key in PEM format.
https-certificate-key-file=/root/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.



### Exemple de configuration

Exemple de configuration avec

WIP

## 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)
```{.ini}
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

```{.ini}
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](https://infinispan.org/) (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*

```{.bash}
  $ cd $keycloak_folder
  $ bin/kc.sh start-dev
  
  $ bin/kc.sh start
```

Voir les option de démarrage / aide

```{.bash}
  bin/kc.sh start-dev --help
  bin/kc.sh start --help
```

**Lancer Keycloak** en *dev* sur le port 8080

```{.bash}
  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](https://www.keycloak.org/getting-started/getting-started-zip)

suivre les étapes jusqu'a arriver au message "hello, myuser" sur [https://www.keycloak.org/app/](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
:logbook:
  CLOCK: [2023-06-21 Wed 14:43:19]--[2023-06-21 Wed 15:05:04] =>  00:21:45
:END:

[documentation keycloak](https://www.keycloak.org/docs/latest/server_admin/#admin-cli)

# Ressources

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

https://rob-ferguson.me/

