Свързване на ActiveDirectory удостоверяване с Kubernetes чрез Keycloak

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

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

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

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

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

Подготовка

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

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

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

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

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

Ключ
Стойност

Name
kubernetes

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

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

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

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

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

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

Следващата задача е да свържете нашите групи

User federation —> ldap_localhost —> Mappers —> Създаване

Създаване на мапперСвързване на ActiveDirectory удостоверяване с Kubernetes чрез Keycloak

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

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

Clients —> Създаваме

Настройка на клиентаСвързване на ActiveDirectory удостоверяване с Kubernetes чрез Keycloak

Ще създадем scoupe за групи:

Client Scopes —> Създаване

Създаване на scoupeСвързване на 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