Quest'articolo è scritto con l'obiettivo di espandere già , ma tratta delle peculiarità del collegamento con Microsoft Active Directory, e la integra.
In questo articolo spiegherò come installare e configurare:
- Keycloak Keycloak è un progetto open source. Che fornisce un punto di accesso unico per le applicazioni. Supporta vari protocolli, tra cui LDAP e OpenID, che ci interessano.
- Keycloak gatekeeper è un'applicazione reverse proxy che consente di integrare l'autorizzazione 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 permessi in Kubernetes.
Possiamo gestire i permessi per utenti/gruppi tramite RBAC, di cui sono già stati scritti molti articoli, quindi non mi fermerò qui a discutere in dettaglio. Il problema è che puoi usare RBAC per limitare i permessi di un utente, ma Kubernetes non ha informazioni sugli utenti. Risulta quindi necessario un meccanismo per portare l'utente in Kubernetes. A questo scopo, aggiungeremo a Kubernetes un provider OpenID che confermerà che tale utente esiste realmente, mentre i permessi saranno gestiti direttamente da Kubernetes.
Preparazione
- Avrai bisogno di un cluster Kubernetes o di minikube.
- Active Directory
- Domini:
keycloak.example.org
kubernetes-dashboard.example.org
gangway.example.org - Certificato per i domini o un certificato autofirmato
Non mi soffermerò su come creare certificati autofirmati, è necessario generare 2 certificati: uno radice (Centro di certificazione) e uno wildcard client per il dominio *.example.org.
Dopo aver ottenuto/i certificati, il certificato client deve essere aggiunto a Kubernetes, per questo creiamo un secret:
kubectl create secret tls tls-keycloak --cert=example.org.crt --key=example.org.pemSuccessivamente lo utilizzeremo per il nostro controller Ingress.
Installazione di Keycloak
Ho deciso che fosse più semplice utilizzare soluzioni pronte all'uso, come i chart helm.
Aggiungiamo il repository e lo aggiorniamo:
helm repo add codecentric https://codecentric.github.io/helm-charts
helm repo updateCreiamo un file keycloak.yml con il seguente contenuto:
keycloak.yml
keycloak:
# Nome dell'amministratore
username: "test_admin"
# Password dell'amministratore
password: "admin"
# Questi flag sono necessari per consentire il caricamento di script su Keycloak tramite l'interfaccia web. Questo ci
servirà per risolvere un bug, di cui parlerò di seguito.
extraArgs: "-Dkeycloak.profile.feature.script=enabled -Dkeycloak.profile.feature.upload_scripts=enabled"
# Abilitare 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 funzionare, per scopi di test installo Postgresql direttamente in Kubernetes, in produzione non è consigliato farlo!
persistence:
deployPostgres: true
dbVendor: postgres
postgresql:
postgresUser: keycloak
postgresPassword: ""
postgresDatabase: keycloak
persistence:
enabled: trueConfigurazione della federazione
Successivamente accediamo all'interfaccia web.
In alto a sinistra clicchiamo su Aggiungi realm
Chiave
Valore
Name
kubernetes
Nome visualizzato
Kubernetes
Disabilitiamo la verifica dell'email per gli utenti:
Client scopes —> Email —> Mappers —> Email verified (Elimina)
Configuriamo la federazione per importare utenti da Active Directory, lascerò di seguito degli screenshot per una maggiore chiarezza.
User federation —> Aggiungi provider… —> ldap
Configurazione della federazione

Se va tutto bene, dopo aver premuto il bottone Sincronizza tutti gli utenti vedrai un messaggio di importazione riuscita degli utenti.
Ora dobbiamo mappare i nostri gruppi.
User federation —> ldap_localhost —> Mappers —> Crea
Creazione di un mapper
Configurazione del client
Devi creare un client, nel contesto di Keycloak, questo rappresenta l'applicazione che sarà autorizzata. Sottolineerò i punti importanti nello screenshot in rosso.
Clients —> Crea
Configurazione del client
Creiamo un scope per i gruppi:
Client Scopes —> Crea
Creazione di uno scope
E configureremo il mapper per essi:
Client Scopes —> groups —> Mappers —> Crea
Mapper
Aggiungiamo il mapping dei nostri gruppi negli Default Client Scopes:
Clients —> kubernetes —> Client Scopes —> Default Client Scopes
Selezioniamo groups in Scope client disponibili, facciamo clic su Aggiungi selezionati
Otteniamo il segreto (e lo annotiamo da qualche parte) che useremo per l'autenticazione in Keycloak:
Clients —> kubernetes —> Credentials —> Secret
A questo punto la configurazione è completa, ma ho riscontrato un errore quando, dopo un'autenticazione riuscita, ricevevo un errore 403. .
Correzione:
Client Scopes —> roles —> Mappers —> Crea
Mapper
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 di Kubernetes
Dobbiamo specificare dove si trova il nostro certificato radice del sito e dove si trova il provider OIDC.
Per questo, 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 auth-proxy
Per proteggere la tua applicazione web, puoi utilizzare Keycloak Gatekeeper. Oltre a svolgere la funzione di reverse proxy che autorizza l'utente prima di mostrare la pagina, trasferisce anche le informazioni riguardo a te nell'intestazione all'applicazione finale. In questo modo, se la tua applicazione supporta OpenID, l'utente verrà autenticato immediatamente. Consideriamo l'esempio del Kubernetes Dashboard.
Installazione del 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'
Configurazione dei permessi di accesso:
Creiamo un ClusterRoleBinding che concederà i diritti di amministratore del cluster (la ClusterRole standard cluster-admin) per gli utenti che appartengono 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 tentiamo di accedere a , ci sarà un reindirizzamento a Keycloak e, in caso di autorizzazione riuscita, arriveremo al Dashboard già autenticati.
Installazione di Gangway
Per comodità, possiamo aggiungere Gangway, che genererà un file di configurazione per kubectl, attraverso il quale potremo accedere a Kubernetes con il nostro utente.
helm install --name gangway stable/gangway -f values_gangway.yaml
values_gangway.yaml
gangway:
# Nome del cluster personalizzato
clusterName: "my-k8s"
# Dove si trova il nostro provider 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 lasciato il valore predefinito, il nome utente verrà preso da <b>Nome di battesimo</b> <b>Cognome</b>, e con "sub" il suo nome utente
usernameClaim: "sub"
# Nome di dominio o indirizzo IP del server API
apiServerURL: "https://192.168.99.111:8443"
# Attiviamo l'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 utilizziamo un certificato autofirmato, è necessario specificare il 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-----
Sembra più o meno così. Permette sia di scaricare immediatamente il file di configurazione sia di generarlo utilizzando un insieme di comandi:

Fonte: habr.com
