Wir integrieren die ActiveDirectory-Authentifizierung in Kubernetes mithilfe von Keycloak

Dieser Artikel wurde verfasst, um bereits bestehende, beschreibt jedoch die Besonderheiten der Verbindung speziell mit Microsoft ActiveDirectory und ergänzt diese.

In diesem Artikel werde ich erläutern, wie man installiert und konfiguriert:

  • Keycloak — ist ein Open-Source-Projekt. Es bietet einen einheitlichen Einstiegspunkt für Anwendungen. Es funktioniert mit vielen Protokollen, einschließlich LDAP und OpenID, die für uns von Interesse sind.
  • Keycloak Gatekeeper — eine Reverse-Proxy-Anwendung, die die Autorisierung über Keycloak integriert.
  • Gangway — eine Anwendung, die eine Konfiguration für kubectl generiert, mit der man sich über OpenID authentifizieren und mit der Kubernetes API verbinden kann.

Wie Rechte in Kubernetes funktionieren.

Wir können die Benutzer-/Gruppenrechte mit Hilfe von RBAC verwalten. Darüber gibt es bereits zahlreiche Artikel, daher werde ich nicht ausführlich darauf eingehen. Das Problem ist, dass Sie RBAC verwenden können, um die Rechte eines Benutzers einzuschränken, aber Kubernetes keine Informationen über Benutzer hat. Es wird also ein Mechanismus benötigt, um den Benutzer in Kubernetes zu bringen. Dazu fügen wir dem Kubernetes OpenID-Provider hinzu, der bestätigen wird, dass es diesen Benutzer tatsächlich gibt, während Kubernetes ihm die Rechte zuteilt.

Vorbereitung

  • Sie benötigen einen Kubernetes-Cluster oder Minikube
  • Active Directory
  • Domains:
    keycloak.example.org
    kubernetes-dashboard.example.org
    gangway.example.org
  • Zertifikat für die Domains oder ein selbstsigniertes Zertifikat

Ich werde nicht im Detail darauf eingehen, wie man selbstsignierte Zertifikate erstellt. Es müssen 2 Zertifikate erstellt werden: ein Root-Zertifikat (Zertifizierungsstelle) und ein Wildcard-Client-Zertifikat für die Domain *.example.org

Nachdem Sie die Zertifikate erhalten oder erstellt haben, muss das Client-Zertifikat in Kubernetes hinzugefügt werden. Dazu erstellen wir ein Secret:

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

Dann werden wir es für unseren Ingress-Controller verwenden.

Installation von Keycloak

Ich habe beschlossen, dass es am einfachsten ist, fertige Lösungen dafür zu verwenden, nämlich Helm-Charts.

Wir fügen das Repository hinzu und aktualisieren es:

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

Erstellen Sie die Datei keycloak.yml mit folgendem Inhalt:

keycloak.yml

keycloak:
  # Administratorname
  username: "test_admin"
  # Administratorkennwort
  password: "admin"
  # Diese Flags sind notwendig, um Skripte direkt über die Weboberfläche in Keycloak hochladen zu können. Das benötigen wir, um einen Fehler zu beheben, der weiter unten erwähnt wird.
  extraArgs: "-Dkeycloak.profile.feature.script=enabled -Dkeycloak.profile.feature.upload_scripts=enabled"
  # Aktivieren Sie den Ingress, geben Sie den Hostnamen und das Zertifikat an, das wir zuvor in den Secrets gespeichert haben.
  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 benötigt für seinen Betrieb eine Datenbank. Zu Testzwecken setze ich Postgresql direkt in Kubernetes auf; im Produktionsumfeld sollte man das besser nicht machen!
  persistence:
    deployPostgres: true
    dbVendor: postgres

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

Einrichtung der Föderation

Gehen Sie nun in die Weboberfläche keycloak.example.org

Klicken Sie oben links Realm hinzufügen

Schlüssel
Wert

Name
Kubernetes

Anzeigename
Kubernetes

Deaktivieren Sie die E-Mail-Bestätigungsprüfung für den Benutzer:
Client-Scopes —> E-Mail —> Mapper —> E-Mail verifiziert (Löschen)

Wir konfigurieren die Föderation zum Importieren von Benutzern aus Active Directory. Ich werde unten Screenshots hinzufügen, damit es verständlicher wird.

Benutzerföderation —> Anbieter hinzufügen… —> ldap

Einrichtung der FöderationWir integrieren die ActiveDirectory-Authentifizierung in Kubernetes mithilfe von Keycloak
Wir integrieren die ActiveDirectory-Authentifizierung in Kubernetes mithilfe von Keycloak

Wenn alles gut läuft, sehen Sie nach dem Drücken der Taste Alle Benutzer synchronisieren die Nachricht über den erfolgreichen Import von Benutzern.

Dann müssen wir unsere Gruppen zuordnen

Benutzerföderation —> ldap_localhost —> Mapper —> Erstellen

Mapper erstellenWir integrieren die ActiveDirectory-Authentifizierung in Kubernetes mithilfe von Keycloak

Client-Konfiguration

Wir müssen einen Client erstellen, d.h. eine Anwendung, die sich bei Keycloak authentifiziert. Wichtige Punkte hebe ich im Screenshot rot hervor.

Clients —> Erstellen

Client-KonfigurationWir integrieren die ActiveDirectory-Authentifizierung in Kubernetes mithilfe von Keycloak

Lassen Sie uns einen Scope für Gruppen erstellen:

Client-Scopes —> Erstellen

Scope erstellenWir integrieren die ActiveDirectory-Authentifizierung in Kubernetes mithilfe von Keycloak

Und wir konfigurieren den Mapper dafür:

Client-Scopes —> groups —> Mapper —> Erstellen

MapperWir integrieren die ActiveDirectory-Authentifizierung in Kubernetes mithilfe von Keycloak

Fügen Sie die Zuordnung unserer Gruppen zu den Standard-Client-Scopes hinzu:

Clients —> kubernetes —> Client-Scopes —> Standard-Client-Scopes
Wählen Sie Gruppen in Verfügbare Client-Scopes, klicken Sie auf Ausgewählte hinzufügen

Erhalten Sie das Secret (und notieren Sie es sich irgendwo), das wir zur Authentifizierung bei Keycloak verwenden werden:

Clients —> kubernetes —> Anmeldeinformationen —> Geheimnis
Damit ist die Konfiguration abgeschlossen, aber ich erhielt einen Fehler, als ich nach erfolgreicher Authentifizierung einen Fehler 403 erhielt. Fehlerbericht.

Fix:

Client-Scopes —> Rollen —> Mapper —> Erstellen

MapperWir integrieren die ActiveDirectory-Authentifizierung in Kubernetes mithilfe von Keycloak

Skript-Code

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

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

Kubernetes-Konfiguration

Wir müssen angeben, wo unser Stammzertifikat von der Website liegt und wo der OIDC-Anbieter sich befindet.
Dazu bearbeiten wir die Datei /etc/kubernetes/manifests/kube-apiserver.yaml

kube-apiserver.yaml


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

Aktualisierung der kubeadm-Konfiguration im Cluster:

kubeadm-Konfiguration

kubectl edit -n kube-system configmaps kubeadm-config


...\nDaten:\n  ClusterConfiguration: |\n    apiServer:\n      extraArgs:\n        oidc-ca-file: /var/lib/minikube/certs/My_Root.crt\n        oidc-client-id: kubernetes\n        oidc-groups-claim: Gruppen\n        oidc-issuer-url: https://keycloak.example.org/auth/realms/kubernetes\n        oidc-username-claim: E-Mail\n...

Einrichtung des auth-proxy

Zur Sicherung Ihrer Webanwendung kann Keycloak Gatekeeper verwendet werden. Dieser Reverse-Proxy autorisiert nicht nur den Benutzer, bevor die Seite angezeigt wird, sondern überträgt außerdem Informationen über Sie an die Endanwendung in den Headern. Somit wird der Benutzer sofort autorisiert, sofern Ihre Anwendung OpenID unterstützt. Lassen Sie uns dies am Beispiel des Kubernetes-Dashboards betrachten.

Installation des Kubernetes Dashboards


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

values_dashboard.yaml

enableInsecureLogin: true\nservice:\n  externalPort: 80\nrbac:\n  clusterAdminRole: true\n  create: true\nserviceAccount:\n  create: true\n  name: 'dashboard-test'

Zugriffsrechte konfigurieren:

Wir erstellen einen ClusterRoleBinding, der Cluster-Admin-Rechte (Standard-ClusterRole cluster-admin) für Benutzer gewährt, die zur Gruppe DataOPS gehören.


kubectl apply -f rbac.yaml

rbac.yaml


apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: dataops_group\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: cluster-admin\nsubjects:\n- apiGroup: rbac.authorization.k8s.io\n  kind: Group\n  name: DataOPS

Installation von Keycloak Gatekeeper:


helm repo add gabibbo97 https://gabibbo97.github.io/charts/\nhelm repo update\nhelm 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"

Nach diesem Schritt erfolgt bei dem Versuch, auf kubernetes-dashboard.example.org, eine Umleitung zu Keycloak, und im Falle einer erfolgreichen Authentifizierung gelangen wir bereits eingeloggt ins Dashboard.

Installation von Gangway

Zur Vereinfachung kann Gangway hinzugefügt werden, das eine Konfigurationsdatei für kubectl generiert, mit der wir dann unter unserem Benutzer Zugang zu Kubernetes erhalten.


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

values_gangway.yaml


gangway:
  # Willkürlicher Clustername
  clusterName: "my-k8s"
  # Wo unser OIDC-Anbieter ist
  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"
  # Theoretisch können hier Gruppen hinzugefügt werden, die wir abgebildet haben
  scopes: ["openid", "profile", "email", "offline_access"]
  redirectURL: "https://gangway.example.org/callback"
  # Clientname
  clientID: "kubernetes"
  # Geheimnis
  clientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
  # Wenn der Standardwert beibehalten wird, wird der Benutzername als sein Login verwendet
  usernameClaim: "sub"
  # Domainname oder IP-Adresse des API-Servers
  apiServerURL: "https://192.168.99.111:8443"

# Aktivieren Sie 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

# Wenn ein selbst-signiertes Zertifikat verwendet wird, muss es (das öffentliche Root-Zertifikat) angegeben werden.
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----- <b>Vorname</b> <b>Nachname</b>, und bei "sub" sein Login
  usernameClaim: "sub"
  # Domainname oder IP-Adresse des API-Servers
  apiServerURL: "https://192.168.99.111:8443"

# Ingress aktivieren
ningress:
  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

# Wenn wir ein selbstsigniertes Zertifikat verwenden, muss es angegeben werden (das öffentliche Wurzelzertifikat).
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-----

Das sieht ungefähr so aus. Es ermöglicht sowohl das sofortige Herunterladen der Konfigurationsdatei als auch deren Erstellung mittels einer Reihe von Befehlen:

Wir integrieren die ActiveDirectory-Authentifizierung in Kubernetes mithilfe von Keycloak

Quelle: habr.com

60GB SSD 8Gb DDR4