Свързване на ActiveDirectory авторизация към Kubernetes с помощта на Keycloak

Тази статия е написана с цел да разшири вече съществуващото, но разказва за особеностите на свързването именно с Microsoft ActiveDirectory, а също така го допълва.

В тази статия ще разкажа как да инсталирате и конфигурирате:

  • Keycloak — проект с отворен код. Който осигурява единна точка за достъп до приложения. Работи с множество протоколи, включително LDAP и OpenID, които ни интересуват.
  • Keycloak gatekeeper — реверс прокси приложение, което позволява интегриране на авторизация през Keycloak.
  • Gangway — приложение, което генерира конфигурация за kubectl, с помощта на което може да се авторизирате и свържете към Kubernetes API през OpenID.

Как работят правата в Kubernetes.

Управляваме правата на потребителите/групите с помощта на RBAC, за което вече са създадени много статии, няма да се задълбочавам в това. Проблемът е, че можете да използвате RBAC, за да ограничите правата на потребителя, но Kubernetes не знае нищо за потребителите. Получава се, че необходим е механизъм за доставяне на потребителя в Kubernetes. За това ще добавим в Kubernetes OpenID доставчик, който ще потвърди, че такъв потребител наистина съществува, а правата му вече ще определи самият Kubernetes.

Подготовка

  • Нуждаете се от Kubernetes клъстер или minikube
  • Active Directory
  • Домейни:
    keycloak.example.org
    kubernetes-dashboard.example.org
    gangway.example.org
  • Сертификат за домейни или самоподписан сертификат

Няма да се задълбочавам в това как да създадете самоподписан сертификат, трябва да създадете 2 сертификата: коренов (Център за сертификация) и wildcard клиентски за домейн *.example.org

След като получите/пишете сертификатите, клиентският трябва да бъде добавен в Kubernetes, за което създаваме secret:

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

След това ще го използваме за нашия Ingress контролер.

Инсталиране на Keycloak

Реших, че е най-лесно да използвам готови решения за това, а именно helm chart-ове.

Добавяме репозитория и го обновяваме:

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

Създаваме файл keycloak.yml с следното съдържание:

keycloak.yml

keycloak:
  # Име на администратора
  username: "test_admin"
  # Парола на администратора  
  password: "admin"
  # Тези флагове са необходими, за да позволят да се зареждат скриптове в Keycloak директно през уеб интерфейса. Това ще ни е нужно, за да поправим един бъг, за който ще говорим по-долу.
  extraArgs: "-Dkeycloak.profile.feature.script=enabled -Dkeycloak.profile.feature.upload_scripts=enabled" 
  # Активираме ingress, указваме името на хоста и сертификата, който предварително сме записали в 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 изисква база данни за своята работа; за тестови цели разгръщам Postgresql директно в Kubernetes, но в продукция е по-добре да не се прави!
  persistence:
    deployPostgres: true
    dbVendor: postgres

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

Настройка на федерацията

След това влизаме в уеб интерфейса keycloak.example.org

В левия ъгъл кликваме на Добави област

Ключ
Value

Name
kubernetes

Показвано име
Kubernetes

Деактивираме проверката на потвърждение на имейл адреса на потребителя:
Client scopes —> Email —> Mappers —> Email verified (Изтрий)

Настройваме федерацията за импортиране на потребители от ActiveDirectory, по-долу ще оставя екранниShots, мисля че така ще е по-ясно.

User federation —> Добави доставчик… —> ldap

Настройка на федерациятаСвързване на ActiveDirectory авторизация към Kubernetes с помощта на Keycloak
Свързване на ActiveDirectory авторизация към Kubernetes с помощта на Keycloak

Ако всичко е наред, след натискане на бутона Синхронизирай всички потребители ще видите съобщение за успешно импортиране на потребители.

След това трябва да картографираме нашите групи

User federation —> ldap_localhost —> Mappers —> Създай

Създаване наMapperСвързване на ActiveDirectory авторизация към Kubernetes с помощта на Keycloak

Настройка на клиента

Трябва да създадем клиент, в термини на Keycloak това е приложението, което ще се удостоверява. Важни точки ще подчертая с червено на екранната снимка.

Clients —> Създай

Настройка на клиентаСвързване на ActiveDirectory авторизация към Kubernetes с помощта на Keycloak

Ще създадем обхват за групи:

Client Scopes —> Създай

Създаване на обхватСвързване на ActiveDirectory авторизация към Kubernetes с помощта на Keycloak

И ще настроим мапера за тях:

Client Scopes —> groups —> Mappers —> Създай

МаперСвързване на ActiveDirectory авторизация към Kubernetes с помощта на Keycloak

Добавяме картографиране на нашите групи в Default Client Scopes:

Clients —> kubernetes —> Client Scopes —> Default Client Scopes
Избираме groups в Достъпни Client Scopes, натискаме Добави избраните

Получаваме secret (и го записваме някъде), който ще използваме за удостоверяване в Keycloak:

Clients —> kubernetes —> Credentials —> Secret
Тук настройката е завършена, но получих грешка, когато след успешна автентикация получавах грешка 403. Бъг репорт.

Фикс:

Client Scopes —> roles —> Mappers —> Създай

MapperСвързване на ActiveDirectory авторизация към Kubernetes с помощта на Keycloak

Код на скрипта

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

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

Настройка на Kubernetes

Трябва да посочим къде се намира нашият коренен сертификат от сайта и къде се намира OIDC доставчикът.
За целта редактираме файла \/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
...

Актуализираме kubeadm конфигурацията в клъстера:

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
...

Настройка auth-proxy

За защита на вашето уеб приложение можете да използвате keycloak gatekeeper. Освен че този реверс прокси ще авторизира потребителя преди да покаже страницата, той също ще предава информация за вас в заглавките на крайното приложение. По този начин, ако вашето приложение поддържа OpenID, потребителят веднага ще се авторизира. Нека разгледаме примера с Kubernetes Dashboard.

Инсталация на 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'

Настройка на правата за достъп:

Ще създадем ClusterRoleBinding, който ще даде права на администратора на клъстера (стандартна ClusterRole cluster-admin) за потребители, които са в групата 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

Инсталация на 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"

След това, при опит за достъп до kubernetes-dashboard.example.org, ще бъде направен пренасочване към Keycloak и при успешна авторизация ще влезем в Dashboard вече влязъл.

Инсталация на gangway

За удобство можете да добавите gangway, който ще генерира конфигурационен файл за kubectl, с помощта на който вече под нашия потребител ще влезем в Kubernetes.


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

values_gangway.yaml


gangway:
  # Произвольно име на кластера
  clusterName: "my-k8s"
  # Къде е нашият 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"
  # Теоретично тук можем да добавим групи, които сме свързали
  scopes: ["openid", "profile", "email", "offline_access"]
  redirectURL: "https://gangway.example.org/callback"
  # Име на клиента
  clientID: "kubernetes"
  # Секрет
  clientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
  # Ако оставим дефолтната стойност, името на потребителя ще се взема <b>Име</b> <b>Фамилия</b>, а при "sub" неговият логин
  usernameClaim: "sub"
  # Домен име или IP адрес на API сървъра
  apiServerURL: "https://192.168.99.111:8443"

# Включваме 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

# Ако използваме само-подписан сертификат, трябва да посочим (открития коренов сертификат).
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-----

Изглежда приблизително така. Позволява както веднага да изтеглите конфигурационен файл, така и да го създадете с набор от команди:

Свързване на ActiveDirectory авторизация към Kubernetes с помощта на Keycloak

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster