Este artículo está escrito con el propósito de ampliar ya , pero habla sobre las particularidades de la integración específicamente con Microsoft Active Directory, además de complementarla.
En este artículo, explicaré cómo instalar y configurar:
- Keycloak es un proyecto de código abierto que proporciona un único punto de entrada para aplicaciones. Funciona con muchos protocolos, incluidos LDAP y OpenID, los cuales son de nuestro interés.
- Keycloak gatekeeper es una aplicación de proxy inverso que permite integrar la autorización a través de Keycloak.
- Gangway es una aplicación que genera la configuración para kubectl mediante la cual se puede autorizar e ingresar al API de Kubernetes a través de OpenID.
Cómo funcionan los derechos en Kubernetes.
Podemos gestionar los derechos de usuario/grupos mediante RBAC; ya se han creado muchos artículos sobre esto, así que no me detendré en detalles. El problema es que, si bien puede usar RBAC para restringir los derechos del usuario, Kubernetes no sabe nada acerca de los usuarios. Por lo tanto, se necesita un mecanismo para introducir al usuario en Kubernetes. Para ello, agregaremos un proveedor OpenID a Kubernetes, que confirmará que el usuario efectivamente existe, y los derechos serán otorgados por Kubernetes mismo.
Preparación
- Necesitará un clúster de Kubernetes o minikube
- Active Directory
- Dominios:
keycloak.example.org
kubernetes-dashboard.example.org
gangway.example.org - Certificado para los dominios o un certificado autofirmado
No me detendré en cómo crear un certificado autofirmado, pero necesitará crear 2 certificados: uno raíz (centro de certificación) y uno wildcard para el dominio *.example.org
Una vez que obtenga/emita los certificados, debe agregar el certificado del cliente a Kubernetes, para eso creamos un secret:
kubectl create secret tls tls-keycloak --cert=example.org.crt --key=example.org.pemA continuación, lo utilizaremos para nuestro controlador de Ingress
Instalación de Keycloak
Decidí que lo más sencillo era usar soluciones ya preparadas, específicamente charts de helm.
Instalamos el repositorio y lo actualizamos:
helm repo add codecentric https://codecentric.github.io/helm-charts
helm repo updateCreamos el archivo keycloak.yml con el siguiente contenido:
keycloak.yml
keycloak:
# Nombre del administrador
username: "test_admin"
# Contraseña del administrador
password: "admin"
# Estas flags son necesarias para permitir cargar scripts en Keycloak directamente a través de la interfaz web. Esto nos
servirá para solucionar un error que se describe a continuación.
extraArgs: "-Dkeycloak.profile.feature.script=enabled -Dkeycloak.profile.feature.upload_scripts=enabled"
# Activamos el ingreso, especificamos el nombre del host y el certificado que guardamos previamente en los secretos
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 requiere una base de datos para su funcionamiento, para propósitos de prueba estoy desplegando Postgresql directamente en Kubernetes, en producción no es recomendable hacer esto!
persistence:
deployPostgres: true
dbVendor: postgres
postgresql:
postgresUser: keycloak
postgresPassword: ""
postgresDatabase: keycloak
persistence:
enabled: trueConfiguración de la federación
A continuación, accedemos a la interfaz web
En la esquina izquierda, hacemos clic en Añadir reino
Clave
Value
Nombre
kubernetes
Nombre para mostrar
Kubernetes
Deshabilitamos la verificación del correo electrónico del usuario:
Client scopes —> Email —> Mappers —> Email verified (Eliminar)
Configuramos la federación para importar usuarios desde ActiveDirectory; dejaré a continuación capturas de pantalla, creo que será más claro.
User federation —> Añadir proveedor… —> ldap
Configuración de la federación

Si todo está bien, después de presionar el botón Sincronizar todos los usuarios verá un mensaje de importación exitosa de usuarios.
A continuación, necesitamos mapear nuestros grupos
User federation —> ldap_localhost —> Mappers —> Crear
Creación de un mapeador
Configuración del cliente
Debemos crear un cliente, en los términos de Keycloak esto es una aplicación que se autenticará con él. Resaltaré los puntos importantes en la captura de pantalla en rojo.
Clients —> Crear
Configuración del cliente
Crearemos un scope para los grupos:
Client Scopes —> Crear
Creación de un scope
Y configuraremos un mapeador para ellos:
Client Scopes —> groups —> Mappers —> Crear
Mapper
Añadimos el mapeo de nuestros grupos en los Default Client Scopes:
Clients —> kubernetes —> Client Scopes —> Default Client Scopes
Seleccionamos groups en Client Scopes Disponibles, hacemos clic en Añadir seleccionados
Obtenemos el secret (y lo anotamos en algún lugar) que utilizaremos para la autenticación en Keycloak:
Clients —> kubernetes —> Credentials —> Secret
Con esto, la configuración ha terminado, pero tuve un error cuando después de una autenticación exitosa recibí un error 403. .
Solución:
Client Scopes —> roles —> Mappers —> Crear
Mapper
Código del script
// add current client-id to token audience
token.addAudience(token.getIssuedFor());
// return token issuer as dummy result assigned to iss again
token.getIssuer();
Configuración de Kubernetes
Debemos indicar dónde se encuentra nuestro certificado raíz del sitio y dónde se encuentra el proveedor OIDC.
Para esto, editamos el archivo \/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
...
Actualizamos la configuración de kubeadm en el clúster:
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
...
Configuración del auth-proxy
Para proteger su aplicación web, se puede utilizar keycloak gatekeeper. Además de que este proxy inverso autorizará al usuario antes de mostrar la página, también pasará la información sobre usted a la aplicación final en las cabeceras. De este modo, si su aplicación soporta OpenID, el usuario se autenticará de inmediato. Veremos esto con el ejemplo de Kubernetes Dashboard.
Instalación 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'
Configuración de permisos:
Crearemos un ClusterRoleBinding que otorgará permisos de administrador de clúster (ClusterRole estándar cluster-admin) a los usuarios que estén en el grupo 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
Instalación 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"
Después de esto, al intentar acceder a , será redirigido a Keycloak y, en caso de una autenticación exitosa, accederemos al Dashboard ya autenticado.
Instalación de gangway
Para mayor comodidad, se puede añadir gangway, que generará un archivo de configuración para kubectl, con el cual ya bajo nuestro usuario accederemos a Kubernetes.
helm install --name gangway stable/gangway -f values_gangway.yaml
values_gangway.yaml
gangway:
# Nombre del clúster
clusterName: "my-k8s"
# Donde se encuentra nuestro proveedor 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"
# Teóricamente, aquí se pueden agregar grupos que hemos asignado
scopes: ["openid", "profile", "email", "offline_access"]
redirectURL: "https://gangway.example.org/callback"
# Nombre del cliente
clientID: "kubernetes"
# Secreto
clientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
# Si se deja el valor predeterminado, el nombre de usuario será utilizado <b>Primer nombre</b> <b>Segundo nombre</b>, y en "sub" su inicio de sesión
usernameClaim: "sub"
# Nombre de dominio o dirección IP del servidor API
apiServerURL: "https://192.168.99.111:8443"
# Activamos 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 utilizamos un certificado autofirmado, debe especificarse el certificado raíz (público).
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-----
Se ve algo así. Permite tanto descargar el archivo de configuración como generarlo utilizando un conjunto de comandos:

Fuente: habr.com
