Colleghiamo l'autenticazione ActiveDirectory a Kubernetes tramite Keycloak

Questo articolo è scritto con l'intento di ampliare già esistente, ma parla delle caratteristiche dell'integrazione specificamente con Microsoft ActiveDirectory, e la completa.

In questo articolo spiegherò come installare e configurare:

  • Keycloak è un progetto open source. Fornisce un'unica interfaccia per le applicazioni. Funziona con numerosi protocolli, tra cui LDAP e OpenID, che sono di nostro interesse.
  • Keycloak gatekeeper è un'applicazione reverse proxy che consente di integrare l'autenticazione tramite Keycloak.
  • Gangway è un'applicazione che genera una configurazione per kubectl tramite la quale è possibile autenticarsi e collegarsi all'API di Kubernetes usando OpenID.

Come funzionano i diritti in Kubernetes.

Possiamo gestire i diritti degli utenti/gruppi tramite RBAC, su cui sono stati scritti già molti articoli, non mi soffermerò dettagliatamente su questo. Il problema è che puoi usare RBAC per limitare i diritti di un utente, ma Kubernetes non sa nulla degli utenti. Si rende quindi necessario un meccanismo di consegna dell'utente in Kubernetes. A questo scopo, aggiungeremo in Kubernetes un provider OpenID che indicherà che tale utente esiste realmente, e sono già Kubernetes a concedere i diritti.

Preparazione

  • Avrai bisogno di un cluster Kubernetes o minikube
  • Active Directory
  • Domini:
    keycloak.example.org
    kubernetes-dashboard.example.org
    gangway.example.org
  • Certificato per i domini o certificato auto-firmato

Non approfondirò su come creare certificati auto-firmati, è necessario crearne 2, uno principale (CA) e uno client wildcard per il dominio *.example.org

Dopo aver ottenuto/firmato i certificati, è necessario aggiungere il certificato client in Kubernetes, per questo creiamo un secret:

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

Successivamente lo utilizzeremo per il nostro controller Ingress.

Installazione di Keycloak

Ho deciso che fosse più semplice utilizzare soluzioni pronte, in particolare i chart helm.

Aggiungiamo il repository e lo aggiorniamo:

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

Creiamo il file keycloak.yml con il seguente contenuto:

keycloak.yml

keycloak:
  # Nome dell'amministratore
  username: "test_admin"
  # Password amministratore  
  password: "admin"
  # Questi flag sono necessari per consentire il caricamento di script in Keycloak direttamente tramite l'interfaccia web. Ciò ci sarà utile per risolvere un bug di cui parleremo più avanti.
  extraArgs: "-Dkeycloak.profile.feature.script=enabled -Dkeycloak.profile.feature.upload_scripts=enabled" 
  # Abilitiamo l'ingress, specificando il nome host e il certificato che abbiamo precedentemente salvato nei segreti
  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 richiede un database per il suo funzionamento; per scopi di test, installo Postgresql direttamente in Kubernetes. In produzione è meglio non farlo!
  persistence:
    deployPostgres: true
    dbVendor: postgres

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

Impostazione della federazione

Poi accediamo all'interfaccia web keycloak.example.org

In alto a sinistra clicchiamo su Aggiungi realm

Key
Value

Name
kubernetes

Nome visualizzato
Kubernetes

Disattiviamo la verifica della conferma email dell'utente:
Client scopes —> Email —> Mappers —> Email verificata (Elimina)

Configuriamo la federazione per l'importazione di utenti da Active Directory; lascerò di seguito degli screenshot, penso sia più chiaro.

User federation —> Aggiungi provider… —> ldap

Impostazione della federazioneColleghiamo l'autenticazione ActiveDirectory a Kubernetes tramite Keycloak
Colleghiamo l'autenticazione ActiveDirectory a Kubernetes tramite Keycloak

Se tutto va bene, dopo aver cliccato il pulsante Sincronizza tutti gli utenti visualizzerai un messaggio di successo per l'importazione degli utenti.

Dopo dobbiamo mappare i nostri gruppi

User federation —> ldap_localhost —> Mappers —> Crea

Creazione del mapperColleghiamo l'autenticazione ActiveDirectory a Kubernetes tramite Keycloak

Configurazione del client

Dobbiamo creare un client; nel contesto di Keycloak, questo è un'applicazione che si autentica. Evidenzierò i punti importanti negli screenshot in rosso.

Clients —> Crea

Configurazione del clientColleghiamo l'autenticazione ActiveDirectory a Kubernetes tramite Keycloak

Creiamo uno scopo per i gruppi:

Client Scopes —> Crea

Creazione dello scopoColleghiamo l'autenticazione ActiveDirectory a Kubernetes tramite Keycloak

E configuriamo il mapper per essi:

Client Scopes —> groups —> Mappers —> Crea

MapperColleghiamo l'autenticazione ActiveDirectory a Kubernetes tramite Keycloak

Aggiungiamo il mapping dei nostri gruppi negli Scope Client Predefiniti:

Clients —> kubernetes —> Client Scopes —> Default Client Scopes
Selezioniamo groups in Client Scopes Disponibili, facciamo clic su Aggiungi selezionati

Otteniamo il secret (e lo annotiamo da qualche parte) che useremo per l'autenticazione in Keycloak:

Clients —> kubernetes —> Credentials —> Secret
Con questo la configurazione è completata, ma ho riscontrato un errore quando, dopo un'autenticazione riuscita, ricevevo un errore 403. Segnalazione del bug.

Fix:

Client Scopes —> roles —> Mappers —> Crea

MapperColleghiamo l'autenticazione ActiveDirectory a Kubernetes tramite Keycloak

Codice dello script

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

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

Configurazione Kubernetes

Dobbiamo specificare dove si trova il nostro certificato radice del sito e dove si trova il provider OIDC.
Per fare ciò, modifichiamo il file \/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
...

Aggiorniamo la configurazione di kubeadm nel 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
...

Configurazione dell'auth-proxy

Per proteggere la tua applicazione web, puoi utilizzare keycloak gatekeeper. Oltre a garantire l'autenticazione dell'utente prima di mostrarlo la pagina, invierà ulteriori informazioni all'applicazione finale tramite gli header. In questo modo, se la tua applicazione supporta OpenID, l'utente verrà autenticato immediatamente. Vediamo l'esempio di Kubernetes Dashboard.

Installazione di 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'

Impostazione dei diritti di accesso:

Creeremo un ClusterRoleBinding che darà diritti da amministratore del cluster (il ClusterRole standard cluster-admin) agli utenti appartenenti al gruppo 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

Installazione di 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"

Dopo questo, quando si tenta di accedere a kubernetes-dashboard.example.org, si verrà reindirizzati a Keycloak e, in caso di autorizzazione riuscita, si accede al Dashboard già autenticati.

Installazione di gangway

Per comodità, si può aggiungere gangway che genererà un file di configurazione per kubectl, con cui potremo entrare in Kubernetes con il nostro utente.


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

values_gangway.yaml


gangway:
  # Nome del cluster arbitrarie
  clusterName: "my-k8s"
  # Dove si trova il nostro fornitore 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"
  # Teoricamente qui possiamo aggiungere i gruppi che abbiamo mappato
  scopes: ["openid", "profile", "email", "offline_access"]
  redirectURL: "https://gangway.example.org/callback"
  # Nome del client
  clientID: "kubernetes"
  # Segreto
  clientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
  # Se si lascia il valore predefinito, prenderà il nome utente da "sub" <b>Nome</b> <b>Cognome</b>, e con "sub" il suo login
  usernameClaim: "sub"
  # Nome di dominio o indirizzo IP del server API
  apiServerURL: "https://192.168.99.111:8443"

# Attiviamo 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

# Se usiamo un certificato autofirmato, dobbiamo specificare il suo (certificato radice pubblico).
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-----

Apparirà più o meno così. Consente sia di scaricare immediatamente il file di configurazione sia di generarlo utilizzando un insieme di comandi:

Colleghiamo l'autenticazione ActiveDirectory a Kubernetes tramite Keycloak

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster