Connecter l'authentification ActiveDirectory à Kubernetes à l'aide de Keycloak

Cet article a pour but d'élargir ce qui existe déjà existant, mais aborde les particularités de l'intégration avec Microsoft Active Directory, tout en l'enrichissant.

Dans cet article, je vais expliquer comment installer et configurer :

  • Keycloak — c'est un projet open source. Il fournit un point d'entrée unique pour les applications. Il fonctionne avec de nombreux protocoles, y compris LDAP et OpenID, qui nous intéressent.
  • Keycloak gatekeeper — une application de proxy inverse qui permet d'intégrer l'authentification via Keycloak.
  • Gangway — une application qui génère une configuration pour kubectl, permettant de s'authentifier et de se connecter à l'API Kubernetes via OpenID.

Comment fonctionnent les droits dans Kubernetes.

Nous pouvons gérer les droits des utilisateurs/groupes à l'aide de RBAC, de nombreux articles ont déjà été écrits à ce sujet, je ne vais pas m'y attarder en détail. Le problème est que vous pouvez utiliser RBAC pour restreindre les droits d'un utilisateur, mais Kubernetes ne sait rien des utilisateurs. Il s'avère qu'un mécanisme de livraison des utilisateurs dans Kubernetes est nécessaire. Pour cela, nous allons ajouter un fournisseur OpenID dans Kubernetes, qui indiquera que cet utilisateur existe réellement, et c'est Kubernetes lui-même qui attribuera les droits.

Préparation

  • Vous aurez besoin d'un cluster Kubernetes ou de minikube
  • Active Directory
  • Domaines :
    keycloak.example.org
    kubernetes-dashboard.example.org
    gangway.example.org
  • Un certificat pour les domaines ou un certificat auto-signé

Je ne vais pas détailler comment créer un certificat auto-signé, il faut créer 2 certificats, un certificat racine (Autorité de certification) et un certificat client wildcard pour le domaine *.example.org

Après avoir obtenu/écrit les certificats, le certificat client doit être ajouté à Kubernetes, pour cela nous créons un secret pour lui :

kubectl create secret tls tls-keycloak --cert=example.org.crt --key=example.org.pem

Ensuite, nous allons l'utiliser pour notre contrôleur Ingress

Installation de Keycloak

J'ai décidé qu'il était plus simple d'utiliser des solutions prêtes à l'emploi pour cela, à savoir les charts helm.

Nous ajoutons le dépôt et le mettons à jour :

helm repo add codecentric https://codecentric.github.io/helm-charts
helm repo update

Créons un fichier keycloak.yml avec le contenu suivant :

keycloak.yml

keycloak:
  # Nom de l'administrateur
  username: "test_admin"
  # Mot de passe administrateur
  password: "admin"
  # Ces flags sont nécessaires pour permettre de charger des scripts dans Keycloak directement via l'interface web. C'est ce dont nous aurons besoin pour corriger un bug, mentionné ci-dessous.
  extraArgs: "-Dkeycloak.profile.feature.script=enabled -Dkeycloak.profile.feature.upload_scripts=enabled"
  # Nous activons l'ingress, spécifions le nom d'hôte et le certificat que nous avons préalablement enregistré dans les secrets
  ingress:
    enabled: true
    path: / 
    annotations:
      kubernetes.io/ingress.class: nginx
      ingress.kubernetes.io/affinity: cookie
    hosts:
      - keycloak.example.org
    tls:
    - hosts:
        - keycloak.example.org
      secretName: tls-keycloak
  # Keycloak nécessite une base de données pour fonctionner, à des fins de test j'implémente Postgresql directement dans Kubernetes, en production, il vaut mieux ne pas faire ça !
  persistence:
    deployPostgres: true
    dbVendor: postgres

postgresql:
  postgresUser: keycloak
  postgresPassword: ""
  postgresDatabase: keycloak
  persistence:
    enabled: true

Configuration de la fédération

Ensuite, connectez-vous à l'interface web keycloak.example.org

Dans le coin gauche, cliquez sur Ajouter un royaume

Clé
Valeur

Nom
kubernetes

Nom d'affichage
Kubernetes

Désactivez la vérification de la confirmation de l'email de l'utilisateur :
Client scopes —> Email —> Mappers —> Email verified (Supprimer)

Configuration de la fédération pour importer des utilisateurs depuis ActiveDirectory, je laisserai des captures d'écran ci-dessous, cela sera plus clair.

User federation —> Ajouter un fournisseur… —> ldap

Configuration de la fédérationConnecter l'authentification ActiveDirectory à Kubernetes à l'aide de Keycloak
Connecter l'authentification ActiveDirectory à Kubernetes à l'aide de Keycloak

Si tout va bien, après avoir cliqué sur le bouton Synchroniser tous les utilisateurs vous verrez un message indiquant que l'importation des utilisateurs a été réussie.

Ensuite, nous devons mapper nos groupes

User federation —> ldap_localhost —> Mappers —> Créer

Créer un mapperConnecter l'authentification ActiveDirectory à Kubernetes à l'aide de Keycloak

Configuration du client

Il faut créer un client, dans le jargon de Keycloak, c'est l'application qui s'authentifie. Les points importants seront soulignés en rouge sur la capture d'écran.

Clients —> Créer

Configuration du clientConnecter l'authentification ActiveDirectory à Kubernetes à l'aide de Keycloak

Créons un scope pour les groupes :

Client Scopes —> Créer

Création de scopeConnecter l'authentification ActiveDirectory à Kubernetes à l'aide de Keycloak

Et nous configurerons un mappeur pour eux :

Client Scopes —> groups —> Mappers —> Créer

MapperConnecter l'authentification ActiveDirectory à Kubernetes à l'aide de Keycloak

Ajoutons le mapping de nos groupes dans les Default Client Scopes :

Clients —> kubernetes —> Client Scopes —> Default Client Scopes
Sélectionnez groups dans Scopes de client disponibles, cliquez sur Ajouter les sélectionnés

Obtenez le secret (et notez-le quelque part) que nous allons utiliser pour l'authentification dans Keycloak :

Clients —> kubernetes —> Credentials —> Secret
Voilà, la configuration est terminée, mais j'ai rencontré une erreur lors de la connexion : j'ai reçu une erreur 403. Rapport de bug.

Solution :

Client Scopes —> roles —> Mappers —> Créer

MapperConnecter l'authentification ActiveDirectory à Kubernetes à l'aide de Keycloak

Code du script

// add current client-id to token audience
token.addAudience(token.getIssuedFor());

// return token issuer as dummy result assigned to iss again
token.getIssuer();

Configuration de Kubernetes

Nous devons indiquer où se trouve notre certificat racine du site, et où se trouve le fournisseur OIDC.
Pour cela, modifiez le fichier /etc/kubernetes/manifests/kube-apiserver.yaml

kube-apiserver.yaml


...
spec:
  containers:
  - command:
    - kube-apiserver
...
    - --oidc-ca-file=/var/lib/minikube/certs/My_Root.crt
    - --oidc-client-id=kubernetes
    - --oidc-groups-claim=groups
    - --oidc-issuer-url=https://keycloak.example.org/auth/realms/kubernetes
    - --oidc-username-claim=email
...

Mettons à jour la configuration de kubeadm dans le cluster :

kubeadm config

kubectl edit -n kube-system configmaps kubeadm-config


...
data:
  ClusterConfiguration: |
    apiServer:
      extraArgs:
        oidc-ca-file: /var/lib/minikube/certs/My_Root.crt
        oidc-client-id: kubernetes
        oidc-groups-claim: groups
        oidc-issuer-url: https://keycloak.example.org/auth/realms/kubernetes
        oidc-username-claim: email
...

Configuration de auth-proxy

Pour protéger votre application Web, vous pouvez utiliser Keycloak Gatekeeper. En plus d'autoriser les utilisateurs avant d'afficher la page, ce reverse proxy transmet également des informations vous concernant dans les en-têtes à l'application finale. Ainsi, si votre application prend en charge OpenID, l'utilisateur est immédiatement authentifié. Prenons l'exemple de Kubernetes Dashboard.

Installation de Kubernetes Dashboard


helm install stable/kubernetes-dashboard --name dashboard -f values_dashboard.yaml

values_dashboard.yaml

enableInsecureLogin: true
service:
  externalPort: 80
rbac:
  clusterAdminRole: true
  create: true
serviceAccount:
  create: true
  name: 'dashboard-test'

Configuration des droits d'accès :

Créons un ClusterRoleBinding qui donnera des droits d'administrateur du cluster (ClusterRole par défaut : cluster-admin) aux utilisateurs appartenant au groupe DataOPS.


kubectl apply -f rbac.yaml

rbac.yaml


apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dataops_group
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: DataOPS

Installation de Keycloak Gatekeeper :


helm repo add gabibbo97 https://gabibbo97.github.io/charts/
helm repo update
helm install gabibbo97/keycloak-gatekeeper --version 2.1.0 --name keycloak-gatekeeper -f values_proxy.yaml

values_proxy.yaml



# Включаем ingress
ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: nginx
  path: /
  hosts:
    - kubernetes-dashboard.example.org
  tls:
   - secretName: tls-keycloak
     hosts:
       - kubernetes-dashboard.example.org

# Говорим где мы будем авторизовываться у OIDC провайдера
discoveryURL: "https://keycloak.example.org/auth/realms/kubernetes"
# Имя клиента которого мы создали в Keycloak
ClientID: "kubernetes"
# Secret который я просил записать
ClientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
# Куда перенаправить в случае успешной авторизации. Формат <SCHEMA>://<SERVICE_NAME>.><NAMESAPCE>.<CLUSTER_NAME>
upstreamURL: "http://dashboard-kubernetes-dashboard.default.svc.cluster.local"
# Пропускаем проверку сертификата, если у нас самоподписанный
skipOpenidProviderTlsVerify: true
# Настройка прав доступа, пускаем на все path если мы в группе DataOPS
rules:
  - "uri=/*|groups=DataOPS"

Après cela, lorsque vous tenterez d'accéder à kubernetes-dashboard.example.org, vous serez redirigé vers Keycloak et, en cas de réussite de l'authentification, vous arriverez au Dashboard déjà connecté.

Installation de Gangway

Pour plus de commodité, vous pouvez ajouter Gangway qui générera un fichier de configuration pour kubectl, grâce auquel nous pourrons accéder à Kubernetes sous notre nom d'utilisateur.


helm install --name gangway stable/gangway -f values_gangway.yaml

values_gangway.yaml


gangway:
  # Nom de cluster personnalisé
  clusterName: "my-k8s"
  # Où se trouve notre fournisseur OIDC
  authorizeURL: "https://keycloak.example.org/auth/realms/kubernetes/protocol/openid-connect/auth"
  tokenURL: "https://keycloak.example.org/auth/realms/kubernetes/protocol/openid-connect/token"
  audience: "https://keycloak.example.org/auth/realms/kubernetes/protocol/openid-connect/userinfo"
  # Théoriquement, nous pouvons ajouter ici des groupes que nous avons mappés
  scopes: ["openid", "profile", "email", "offline_access"]
  redirectURL: "https://gangway.example.org/callback"
  # Nom du client
  clientID: "kubernetes"
  # Secret
  clientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
  # Si la valeur par défaut est laissée, le nom d'utilisateur sera pris par "sub" <b>Prénom</b> <b>Nom</b>, et pour "sub", son identifiant
  usernameClaim: "sub"
  # Nom de domaine ou adresse IP du serveur API
  apiServerURL: "https://192.168.99.111:8443"

# Activer Ingress
-ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/proxy-buffer-size: "64k"
  path: /
  hosts:
  - gangway.example.org
  tls:
  - secretName: tls-keycloak
    hosts:
      - gangway.example.org

# Si nous utilisons un certificat auto-signé, il faut spécifier celui-ci (certificat racine ouvert).
trustedCACert: |-
 -----BEGIN CERTIFICATE-----
 MIIDVzCCAj+gAwIBAgIBATANBgkqhkiG9w0BAQsFADA1MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRGF0YU9QUzEUMBIGA1UEAxMLbXkgcm9vdCBrZXkwHhcNMjAwMjE0MDkxODAwWhcNMzAwMjE0MDkxODAwWjA1MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRGF0YU9QUzEUMBIGA1UEAxMLbXkgcm9vdCBrZXkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDyP749PqqIRwNSqaK6qr0Zsi03G4PTCUlgaYTPZuMrwUVPK8xX2dWWs9MPRMOdXpgr8aSTZnVfmelIlVz4D7o2vK5rfmAe9GPcK0WbwKwXyhFU0flS9sU/g46ogHFrk03SZxQAeJhMLfEmAJm8LF5HghtGDs3t4uwGsB95o+lqPLiBvxRB8ZS3jSpYpvPgXAuZWKdZUQ3UUZf0X3hGLp7uIcIwJ7i4MduOGaQEO4cePeEJy9aDAO6qV78YmHbyh9kaW+1DL/Sgq8NmTgHGV6UOnAPKHTnMKXl6KkyUz8uLBGIdVhPxrlzG1EzXresJbJenSZ+FZqm3oLqZbw54Yp5hAgMBAAGjcjBwMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHISTOU/6BQqqnOZj+1xJfxpjiG0MAsGA1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAAcwHgYJYIZIAYb4QgENBBEWD3hjYSBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAQEAj7HC8ObibwOLT4ZYmISJZwub9lcE0AZ5cWkPW39j/syhdbbqjK/6jy2D3WUEbR+s1Vson5Ov7JhN5In2yfZ/ByDvBnoj7CP8Q/ZMjTJgwN7j0rgmEb3CTZvnDPAz8Ijw3FP0cjxfoZ1Z0V2F44Ry7gtLJWr06+MztXVyto3aIz1/XbMQnXYlzc3c3B5yUQIy44Ce5aLRVsAjmXNqVRmDJ2QPNLicvrhnUJsO0zFWI+zZ2hc4Ge1RotCrjfOc9hQY63jZJ17myCZ6QCD7yzMzAob4vrgmkD4q7tpGrhPY/gDcE+lUNhC7DO3l0oPy2wsnT2TEn87eyWmDiTFG9zWDew==
 -----END CERTIFICATE-----

Il ressemble à peu près à cela. Il permet à la fois de télécharger immédiatement le fichier de configuration et de le générer à l'aide d'un ensemble de commandes :

Connecter l'authentification ActiveDirectory à Kubernetes à l'aide de Keycloak

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster