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

372 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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)
> **Attention** on installe keycloak dans un utilisateur non root `keycloak` avec comme groupe `keycloak`
```{.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 `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
```{.bash}
# 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
* 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}
# 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.
```{.ini}
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 :
```{.bash}
$ 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](/HowtoSSL.md) et [HowtoNginx](/HowtoNginx.md). Il faut notamment que le port 80 soit accessible à tous.
### Exemple de configuration
Exemple de configuration complete de `$keycloak_folder/conf/keycloak.conf`
```{.ini}
# 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)
```{.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*
> **Remarque** avec l'untiée systemd, utiliser des start, stop etc.
```{.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
[documentation keycloak](https://www.keycloak.org/docs/latest/server_admin/#admin-cli)
# Ressources
https://github.com/thomasdarimont/awesome-keycloak
https://rob-ferguson.me/