Aller au contenu

Installation et configuration

Prerequis

Composant Version minimale Objectif
Podman 4.0+ Runtime conteneurs (ou Kubernetes 1.26+)
Podman Compose 1.0+ Orchestration multi-conteneurs
PostgreSQL 15+ Backend de persistance
Certificat TLS Let's Encrypt ou PKI interne Chiffrement HTTPS
DNS Enregistrement auth.example.com Accès au service

Option A : Déploiement Podman Compose

Préparation du système

# Creer l'utilisateur dedie
sudo useradd -r -m -s /sbin/nologin keycloak

# Creer les repertoires
sudo -u keycloak mkdir -p /home/keycloak/{certs,data}

# Copier les certificats TLS
sudo cp /etc/pki/tls/certs/auth.example.com.{crt,key} /home/keycloak/certs/
sudo chown -R keycloak:keycloak /home/keycloak/certs/
sudo chmod 600 /home/keycloak/certs/*.key

Fichier Podman Compose

# /home/keycloak/podman-compose.yml
version: "3.9"

services:
  postgres:
    image: docker.io/library/postgres:15-alpine
    container_name: keycloak-db
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - keycloak-net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U keycloak"]
      interval: 10s
      timeout: 5s
      retries: 5

  keycloak:
    image: quay.io/keycloak/keycloak:25.0
    container_name: keycloak
    command: start
    environment:
      # Base de donnees
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD_FILE: /run/secrets/db_password

      # Proxy et hostname
      KC_HOSTNAME: auth.example.com
      KC_PROXY_HEADERS: xforwarded
      KC_HTTP_ENABLED: "true"
      KC_HTTP_PORT: "8080"
      KC_HEALTH_ENABLED: "true"
      KC_METRICS_ENABLED: "true"

      # Clustering (JDBC_PING)
      KC_CACHE: ispn
      KC_CACHE_STACK: jdbc-ping

      # JVM
      JAVA_OPTS_KC_HEAP: "-Xms512m -Xmx768m"
    secrets:
      - db_password
      - admin_password
    ports:
      - "8080:8080"
      - "9000:9000"
    networks:
      - keycloak-net
    depends_on:
      postgres:
        condition: service_healthy

  traefik:
    image: docker.io/library/traefik:v3.1
    container_name: keycloak-proxy
    command:
      - "--entrypoints.websecure.address=:443"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
    ports:
      - "443:443"
    volumes:
      - /run/user/1001/podman/podman.sock:/var/run/docker.sock:ro
      - /home/keycloak/certs:/certs:ro
    networks:
      - keycloak-net
    labels:
      - "traefik.enable=true"

volumes:
  pgdata:

networks:
  keycloak-net:
    driver: bridge

secrets:
  db_password:
    file: /home/keycloak/.secrets/db_password
  admin_password:
    file: /home/keycloak/.secrets/admin_password

Initialisation des secrets

# Creer le repertoire de secrets
sudo -u keycloak mkdir -p /home/keycloak/.secrets
sudo chmod 700 /home/keycloak/.secrets

# Generer les mots de passe
openssl rand -base64 32 | sudo -u keycloak tee /home/keycloak/.secrets/db_password > /dev/null
openssl rand -base64 32 | sudo -u keycloak tee /home/keycloak/.secrets/admin_password > /dev/null
sudo chmod 600 /home/keycloak/.secrets/*

Demarrage

# Demarrer la stack
sudo -u keycloak podman-compose -f /home/keycloak/podman-compose.yml up -d

# Verifier les logs
sudo -u keycloak podman logs -f keycloak

# Attendre le message "Keycloak started in Xs"

Creation de l'administrateur initial

# Creer l'admin via la CLI Keycloak
sudo -u keycloak podman exec keycloak \
  /opt/keycloak/bin/kcadm.sh config credentials \
    --server http://localhost:8080 \
    --realm master \
    --user temp-admin \
    --password "$(cat /home/keycloak/.secrets/admin_password)"

# Creer l'utilisateur admin permanent
sudo -u keycloak podman exec keycloak \
  /opt/keycloak/bin/kcadm.sh create users \
    -r master \
    -s username=admin \
    -s enabled=true \
    -s emailVerified=true \
    -s "email=admin@example.com"

# Attribuer le role admin
sudo -u keycloak podman exec keycloak \
  /opt/keycloak/bin/kcadm.sh add-roles \
    -r master \
    --uusername admin \
    --rolename admin

Supprimer le compte temporaire

Apres avoir cree l'administrateur permanent, supprimez le compte temp-admin utilise lors du premier demarrage.

Option B : Déploiement Kubernetes (Helm)

Ajout du repository Helm

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

Fichier de valeurs

# values-keycloak.yaml
replicaCount: 3

image:
  registry: quay.io
  repository: keycloak/keycloak
  tag: "25.0"

auth:
  adminUser: admin
  existingSecret: keycloak-admin-secret
  passwordSecretKey: admin-password

postgresql:
  enabled: true
  auth:
    existingSecret: keycloak-db-secret
    secretKeys:
      adminPasswordKey: postgres-password
      userPasswordKey: password
  primary:
    persistence:
      size: 10Gi

ingress:
  enabled: true
  ingressClassName: nginx
  hostname: auth.example.com
  tls: true
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod

metrics:
  enabled: true
  serviceMonitor:
    enabled: true

podDisruptionBudget:
  create: true
  minAvailable: 2

resources:
  requests:
    cpu: 500m
    memory: 512Mi
  limits:
    cpu: "2"
    memory: 1Gi

Installation

# Creer le namespace
kubectl create namespace keycloak-system

# Creer les secrets
kubectl create secret generic keycloak-admin-secret \
  --namespace keycloak-system \
  --from-literal=admin-password="$(openssl rand -base64 32)"

kubectl create secret generic keycloak-db-secret \
  --namespace keycloak-system \
  --from-literal=postgres-password="$(openssl rand -base64 32)" \
  --from-literal=password="$(openssl rand -base64 32)"

# Deployer
helm install keycloak bitnami/keycloak \
  --namespace keycloak-system \
  --values values-keycloak.yaml \
  --wait --timeout 10m

Configuration initiale

Créer le realm principal

Un realm isole un ensemble d'utilisateurs, de clients et de rôles. Ne jamais utiliser le realm master pour les applications.

# Via kcadm.sh
kcadm.sh create realms \
  -s realm=organization \
  -s enabled=true \
  -s displayName="Organisation" \
  -s loginWithEmailAllowed=true \
  -s registrationAllowed=false \
  -s resetPasswordAllowed=true \
  -s sslRequired=external \
  -s bruteForceProtected=true \
  -s failureFactor=5 \
  -s maxDeltaTimeSeconds=3600 \
  -s minimumQuickLoginWaitSeconds=60

Ne jamais utiliser le realm master

Le realm master est reserve a l'administration de Keycloak lui-même. Créer un realm dedie pour les utilisateurs et les applications.

Configurer la politique de mot de passe

# Politique de mot de passe robuste
kcadm.sh update realms/organization \
  -s 'passwordPolicy="length(12) and upperCase(1) and lowerCase(1) and digits(1) and specialChars(1) and notUsername and passwordHistory(5)"'
Regle Valeur Objectif
length 12 Longueur minimale
upperCase 1 Au moins une majuscule
lowerCase 1 Au moins une minuscule
digits 1 Au moins un chiffre
specialChars 1 Au moins un caractère special
notUsername - Le mot de passe ne doit pas contenir le login
passwordHistory 5 Interdire les 5 derniers mots de passe

Activer MFA obligatoire

# Rendre TOTP obligatoire pour tous les utilisateurs
kcadm.sh update realms/organization \
  -s 'otpPolicyType=totp' \
  -s 'otpPolicyAlgorithm=HmacSHA256' \
  -s 'otpPolicyDigits=6' \
  -s 'otpPolicyPeriod=30'

Pour imposer le MFA dans le flux de login :

  1. Aller dans Authentication > Flows > Browser
  2. Ajouter l'execution OTP Form apres Username Password Form
  3. Définir l'execution comme Required

Configurer les sessions

# Durees de session
kcadm.sh update realms/organization \
  -s 'ssoSessionIdleTimeout=1800' \
  -s 'ssoSessionMaxLifespan=36000' \
  -s 'accessTokenLifespan=300' \
  -s 'accessTokenLifespanForImplicitFlow=900'
Parametre Valeur Description
ssoSessionIdleTimeout 1800 (30 min) Timeout d'inactivite SSO
ssoSessionMaxLifespan 36000 (10h) Duree max d'une session SSO
accessTokenLifespan 300 (5 min) Duree de vie de l'access token

Integration LDAP backend

Pour les organisations qui ont déjà un annuaire LDAP (Active Directory, OpenLDAP), Keycloak peut federer les identités.

Ajouter une fédération LDAP

kcadm.sh create components \
  -r organization \
  -s name="Corporate LDAP" \
  -s providerId=ldap \
  -s providerType=org.keycloak.storage.UserStorageProvider \
  -s 'config.vendor=["other"]' \
  -s 'config.connectionUrl=["ldaps://ldap.example.com:636"]' \
  -s 'config.bindDn=["cn=keycloak,ou=services,dc=example,dc=com"]' \
  -s 'config.bindCredential=["VAULT_REF"]' \
  -s 'config.usersDn=["ou=users,dc=example,dc=com"]' \
  -s 'config.usernameLDAPAttribute=["uid"]' \
  -s 'config.uuidLDAPAttribute=["entryUUID"]' \
  -s 'config.userObjectClasses=["inetOrgPerson"]' \
  -s 'config.editMode=["READ_ONLY"]' \
  -s 'config.syncRegistrations=["false"]' \
  -s 'config.importEnabled=["true"]' \
  -s 'config.batchSizeForSync=["1000"]' \
  -s 'config.fullSyncPeriod=["3600"]' \
  -s 'config.changedSyncPeriod=["60"]'
Parametre Recommandation
editMode READ_ONLY — Keycloak lit les identités, ne les modifie pas dans LDAP
importEnabled true — importe les utilisateurs localement pour les performances
fullSyncPeriod 3600 (1h) — synchronisation complète periodique
changedSyncPeriod 60 (1 min) — synchronisation incrementale fréquente

Mapper les groupes LDAP

Apres avoir configuré la fédération, ajouter un mapper de type group-ldap-mapper pour synchroniser les groupes LDAP vers les groupes Keycloak. Cela permet d'utiliser les groupes existants pour le RBAC.

Vérifier la synchronisation

# Lancer une synchronisation manuelle
kcadm.sh create user-storage/$COMPONENT_ID/sync \
  -r organization \
  -s action=triggerFullSync

# Verifier les utilisateurs importes
kcadm.sh get users -r organization --limit 10

Service systemd (Podman)

# /etc/systemd/system/keycloak.service
[Unit]
Description=Keycloak IAM Stack
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=keycloak
WorkingDirectory=/home/keycloak
ExecStartPre=/usr/bin/podman-compose pull
ExecStart=/usr/bin/podman-compose up
ExecStop=/usr/bin/podman-compose down
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now keycloak.service

Vérification post-installation

Vérification Commande / URL Résultat attendu
Health check curl -s https://auth.example.com/health/ready {"status": "UP"}
Page de login https://auth.example.com/realms/organization/account Page de login
Admin console https://auth.example.com/admin/ Console d'administration
Metriques curl -s http://localhost:9000/metrics Metriques Prometheus
OIDC discovery https://auth.example.com/realms/organization/.well-known/openid-configuration JSON de configuration OIDC