Migration Keycloak Quarkus et Certificats TLS LDAP

Comment gérer les certificats TLS LDAP avec Keycloak, Quarkus Edition

RV
Rémi Verchère
Platform & Cloud Native
4 min de lecture

J'utilise Keycloak depuis quelques temps sur un cluster kubernetes, installé via Helm, avec une version "legacy" basé sur wildfly. Celle-ci étant dépréciée depuis "un moment", il a bien fallu mettre à jour.

Cependant, j'ai eu quelques soucis avec la gestion des certificats TLS lorsque keycloak doit fédérer des utilisateurs depuis un annuaire LDAP. Il y a pas mal de documentation sur le net, mais rien de bien clair.

Nous allons voir ci-après comment résoudre le problème, avec une configuration qui je pense est "propre". Bon OK, pour le troll, Java, Truststore et propre je ne suis pas sûr que ça aille ensemble ^^.

Gestion Certificat TLS mode Wildfly

Lorsque keycloak wildfly était déployé (via chart helm codecentric), la procédure était "simple" :

  1. Création d'une ConfigMap contenant tous les certificats des annuaires LDAP
# Fichier keycloak-outgoing-ca-configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: keycloak-outgoing-ca
  namespace: keycloak
data:
 
  # Certificat raccourci pour l'exemple
  ldap-server-1.crt: |-
    -----BEGIN CERTIFICATE-----
    MIIFHDCCBASgAwIBAgISA97LrVW9BV88dCiH/SxYOguZMA0GCSqGSIb3DQEBCwUA
    MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
    EwJSMzAeFw0yMzA4MzEwNjE4MjdaFw0yMzExMjkwNjE4MjZaMBYxFDASBgNVBAMT
    pKA0HK66WLqZC6dSqaEHvyM87L0BMgw0Y1sC12O6fHqcmTdtHMcbfzb98Row6ubX
    Hgy6H75N33qgbC0ZqoYHsbZyJgs04enfix0FMd3qITJuwYeISve3zkFtKTAbZfos
    qfAo6lbCsHF9/sv540yZ7A==
    -----END CERTIFICATE-----
  1. Référence de cette ConfigMap lors du déploiement du chart Helm, via l'utilisation de "custom values" :
# Paramètres défini dans un fichier custom-values.yaml
extraVolumes: |
  - name: keycloak-outgoing-ca
    configMap:
      name: keycloak-outgoing-ca
 
extraVolumeMounts: |
  - name: keycloak-outgoing-ca
    mountPath: /tmp/certs
  1. Déploiement du chart :
$ helm repo add codecentric https://codecentric.github.io/helm-charts
$ helm repo update
$ helm upgrade --install keycloak codecentric/keycloak -f custom-values.yaml

Gestion Certificat TLS mode Quarkus

Malheureusement, cette méthode ne fonctionne pas avec les déploiements actuels de Keycloak avec Quarkus, en utilisant le chart Bitnami ! Voir ici pour plus d'information.

Je ne comprends pas grand-chose dans les truststores and co., mais on me parle de "Truststore SPI" qui n'est pas paramétrable, qu'il faut passer par la surcharge de JAVA_OPTS etc. Pourtant, dans le chart Helm de Bitnami il y a bien une référence à du SPI, on doit en tirer quelque chose !

Configuration du chart

Après quelques essais, voici une configuration qui fonctionne, et qui me semble pas trop mal :

  1. Génération d'un truststore, contenant l'ensemble des certificats TLS des serveurs LDAP que je souhaite joindre. Un mot de passe devra être créé pour sécuriser l'accès au truststore. Pour éviter tout problème, j'utilise la même image de conteneur que ce qui tournera sur mon cluster (ici 19.0.3) :
$ docker run -it --rm -v ./:/tmp docker.io/bitnami/keycloak:19.0.3 bash
keycloak@25d1c6186533:/$ cd /tmp
keycloak@25d1c6186533:/tmp$ openssl x509 -text -noout -in ldap-server-1.crt 
keycloak@25d1c6186533:/tmp$ keytool -import -alias ldap.192.168.1.1.nip.io -keystore truststore.jks -file ldap-server-1.crt
keycloak@25d1c6186533:/tmp$ openssl x509 -text -noout -in ldap-server-2.crt
keycloak@25d1c6186533:/tmp$ keytool -import -alias ldap.192.168.1.2.nip.io -keystore truststore.jks -file ldap-server-2.crt
keycloak@25d1c6186533:/tmp$ keytool -list -keystore truststore.jks
Enter keystore password:
Keystore type: PKCS12
Keystore provider: SUN
 
Your keystore contains 2 entries
 
ldap.192.168.1.1.nip.io, Oct 4, 2023, trustedCertEntry, 
Certificate fingerprint (SHA-256): 13:F3:F8:65:90:C6:8A:EC:F7:86:B9:E7:82:E4:4B:09:C0:E8:B0:E4:A4:AD:1C:76:7F:B6:CE:56:1B:55:51:8F
ldap.192.168.1.2.nip.io, Oct 4, 2023, trustedCertEntry, 
Certificate fingerprint (SHA-256): A2:B2:01:9D:7B:87:FD:04:7F:F2:98:AF:28:80:B6:CE:9B:8F:73:88:9A:5A:DE:6D:82:D3:33:18:85:BA:66:25
  1. Génération d'un secret contenant ce truststore. Le contenu du secret devra être dans keycloak-spi.truststore.jks :
$ kubectl create secret generic keycloak-spi-store --from-file=keycloak-spi.truststore.jks=truststore.jks
  1. Il est possible également de créer ce secret directement en les définissant dans les values du chart Helm (optionnel) :
[...]
extraDeploy:
  ### Creates truststore used for validating certs for outgoing connexions (LDAPs)
  - |
    apiVersion: v1
    kind: Secret
    metadata:
      name: {{ .Values.spi.existingSecret }}
    data:
      keycloak-spi.truststore.jks: <BASE_64_FILE>
[...]
  1. Reste à paramétrer le chart Helm pour utiliser ce truststore. On nous parle de variables d'environnement KEYCLOAK_SPI_TRUSTSTORE_FILE, KEYCLOAK_SPI_TRUSTSTORE_PASSWORD ou encore KEYCLOAK_SPI_TRUSTSTORE_FILE_HOSTNAME_VERIFICATION_POLICY, celles-ci seront définies via les paramètres du chart (le contenu des values est disponible ici) :
# Extract du fichier custom-values.yaml
[...]
## SPI TLS settings
spi:
  existingSecret: "keycloak-spi-store" # Nom du secret contenant le truststore
  truststorePassword: "changeme" # Mot de passe du truststore pour l'exemple, en production on utilisera un secret, à définir dans passwordsSecret
  truststoreFilename: "keycloak-spi.truststore.jks"
  passwordsSecret: "" # Voir commentaires pour truststorePassword
  hostnameVerificationPolicy: ""STRICT" # On vérifie le nom du serveur portant le certificat
[...]
  1. On déploie le tout !
$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm repo update
$ helm upgrade --install keycloak bitnami/keycloak --namespace keycloak --values custom-values.yaml

Vérification

Maintenant, il ne reste plus qu'à vérifier sur Keycloak que la connexion est OK.

Configuration Keycloak LDAP TLS

Allons dans la partie "User federation" du royaume qui utilise le lien vers mes serveurs LDAP, testons la connexion... Bingo !

Liaison Keycloak LDAP OK

© Gravitek. Tous droits réservés.

logo

Gravitek est une Société à taille humaine, guidée par la qualité de service et la construction d'une relation durable avec ses clients.