Прикручуємо LDAP-авторизацію до Kubernetes

Прикручуємо LDAP-авторизацію до Kubernetes

Невелика інструкція про те, як використовуючи Keycloak, можна зв'язати Kubernetes з вашим LDAP-сервером і налаштувати імпорт користувачів та груп. Це дозволить налаштовувати RBAC для ваших користувачів та використовувати auth-proxy щоб захистити Kubernetes Dashboard та інші програми, які не вміють виконувати авторизацію самостійно.

Установка Keycloak

Припустимо, що у вас вже є LDAP-сервер. Це може бути Active Directory, FreeIPA, OpenLDAP або щось інше. Якщо LDAP-сервера у вас немає, то в принципі ви можете створювати користувачів прямо в інтерфейсі Keycloak, або використовувати публічні провайдери oidc (Google, Github, Gitlab), результат вийде майже такий же.

Насамперед встановимо сам Keycloak, установка може виконуватися окремо, так і відразу в Kubernetes-кластер, як правило якщо у вас є кілька Kubernetes-кластерів, було б простіше встановити його окремо. З іншого боку, ви завжди можете використовувати офіційний helm-чарт і встановити його прямо у ваш кластер.

Для зберігання даних Keycloak вам знадобиться база даних. За замовчуванням використовується h2 (всі дані зберігаються локально), але можна також використовувати postgres, mysql або mariadb.
Якщо ви все ж таки надумали встановити Keycloak окремо, більш докладні інструкції ви знайдете в офіційної документації.

Налаштування федерації

Насамперед створимо новий realm. Realm – це простір нашої програми. Кожна програма може мати свій realm з різними користувачами та налаштуваннями авторизації. Master realm використовується самим Keycloak і використовувати його для чогось ще неправильно.

натискаємо Add realm

варіант
значення

ІМ'Я
kubernetes

Показати ім'я
Kubernetes

HTML Display Name
<img src="https://kubernetes.io/images/nav_logo.svg" width="400" >

Kubernetes за промовчанням перевіряє підтверджений у користувача email чи ні. Оскільки ми використовуємо власний LDAP-сервер, то ця перевірка майже завжди буде повертати false. Давайте відключимо подання цього параметра в Kubernetes:

Клієнтські області -> Електронна адреса -> Картографи -> Email verified (Видалити)

Тепер налаштуємо федерацію, для цього перейдемо до:

User federation -> Add provider… -> ldap

Наведу приклад налаштування для FreeIPA:

варіант
значення

Console Display Name
freeipa.example.org

Продавець
Red Hat Directory Server

UUID LDAP attribute
ipauniqueid

Connection URL
ldaps://freeipa.example.org

Users DN
cn=users,cn=accounts,dc=example,dc=org

Зв'язати DN
uid=keycloak-svc,cn=users,cn=accounts,dc=example,dc=org

Bind Credential
<password>

Allow Kerberos authentication:
on

Kerberos Realm:
EXAMPLE.ORG

Server Principal:
HTTP/[email protected]

KeyTab:
/etc/krb5.keytab

Користувача keycloak-svc потрібно створити заздалегідь на нашому LDAP-сервері.

У випадку з Active Directory досить просто вибрати Vendor: Active Directory та необхідні налаштування підставляються у форму автоматично.

натискаємо зберегти

Тепер перейдемо:

User federation -> freeipa.example.org -> Картографи -> Ім'я

варіант
значення

Ldap attribure
givenName

Тепер увімкнемо мапінг груп:

User federation -> freeipa.example.org -> Картографи -> Створювати

варіант
значення

ІМ'Я
groups

Mapper type
group-ldap-mapper

LDAP Groups DN
cn=groups,cn=accounts,dc=example,dc=org

User Groups Retrieve Strategy
GET_GROUPS_FROM_USER_MEMBEROF_ATTRIBUTE

На цьому налаштування федерації закінчено, перейдемо до налаштування клієнта.

Налаштування клієнта

Створимо нового клієнта (додаток який отримуватиме користувачів з Keycloak). Переходимо:

Клієнти -> Створювати

варіант
значення

ідентифікатор клієнта
kubernetes

Тип доступу
confidenrial

Кореневий URL
http://kubernetes.example.org/

Valid Redirect URIs
http://kubernetes.example.org/*

URL-адреса адміністратора
http://kubernetes.example.org/

Також створимо scope для груп:

Client Scopes -> Створювати

варіант
значення

шаблон
No template

ІМ'Я
groups

Full group path
false

І налаштуємо mapper для них:

Client Scopes -> групи -> Картографи -> Створювати

варіант
значення

ІМ'Я
groups

Тип картографа
Group membership

Token Claim Name
groups

Тепер нам потрібно включити мапінг груп у нашому client scope:

Клієнти -> кубернети -> Client Scopes -> Default Client Scopes

вибираємо групи в Available Client Scopes, натискаємо Додати вибране

Тепер налаштуємо автентифікацію нашої програми, переходимо:

Клієнти -> кубернети

варіант
значення

Authorization Enabled
ON

Натискаємо економити і на цьому налаштування клієнта завершено, тепер на вкладці

Клієнти -> кубернети -> Повноваження

ви зможете отримати секрет який ми будемо використовувати надалі.

Налаштування Kubernetes

Налаштування Kubernetes для OIDC-авторизації досить тривіальне і не є дуже складним. Все, що вам потрібно це покласти CA-сертифікат вашого OIDC-сервера в /etc/kubernetes/pki/oidc-ca.pem та додати необхідні опції для kube-apiserver.
Для цього оновіть /etc/kubernetes/manifests/kube-apiserver.yaml на всіх ваших майстрах:

...
spec:
  containers:
  - command:
    - kube-apiserver
...
    - --oidc-ca-file=/etc/kubernetes/pki/oidc-ca.pem
    - --oidc-client-id=kubernetes
    - --oidc-groups-claim=groups
    - --oidc-issuer-url=https://keycloak.example.org/auth/realms/kubernetes
    - --oidc-username-claim=email
...

А також оновіть kubeadm конфіг у кластері, щоб не втратити ці налаштування при оновленні:

kubectl edit -n kube-system configmaps kubeadm-config

...
data:
  ClusterConfiguration: |
    apiServer:
      extraArgs:
        oidc-ca-file: /etc/kubernetes/pki/oidc-ca.pem
        oidc-client-id: kubernetes
        oidc-groups-claim: groups
        oidc-issuer-url: https://keycloak.example.org/auth/realms/kubernetes
        oidc-username-claim: email
...

На цьому налаштування Kubernetes завершено. Ви можете повторити ці дії у всіх ваших Kubernetes-кластерах.

Початкова авторизація

Після даних дій ви вже матимете Kubernetes-кластер із налаштованою OIDC-авторизацією. Єдиний момент, що ваші користувачі поки що не мають налаштованого клієнта, як і власного kubeconfig. Щоб вирішити цю проблему, потрібно налаштувати автоматичну видачу kubeconfig користувачам після успішної авторизації.

Для цього можна використовувати спеціальні web-додатки, які дозволяють провести аутентифікацію користувача, а потім завантажити готовий kubeconfig. Одне з найзручніших – це KuberosВін дозволяє в одному конфізі описати всі Kubernetes-кластери і легко перемикатися між ними.

Для налаштування Kuberos достатньо описати template для kubeconfig і запустити з наступними параметрами:

kuberos https://keycloak.example.org/auth/realms/kubernetes kubernetes /cfg/secret /cfg/template

Для більш детальної інформації дивіться Використання на Github.

Також можна використовувати kubelogin якщо ви хочете проводити авторизацію безпосередньо на комп'ютері користувача. У цьому випадку користувачу відкриється браузер із формою авторизації на localhost.

Отриманий kubeconfig можна перевірити на сайті jwt.io. Просто скопіюйте значення users[].user.auth-provider.config.id-token з вашого kubeconfig у форму на сайті і відразу отримайте розшифровку.

Налаштування RBAC

При налаштуванні RBAC можна посилатися як на ім'я користувача (поле name в jwt-токені), так і на групу користувачів (поле groups у jwt-токені). Ось приклад налаштування прав для групи kubernetes-default-namespace-admins:

kubernetes-default-namespace-admins.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: default-admins
  namespace: default
rules:
- apiGroups:
  - '*'
  resources:
  - '*'
  verbs:
  - '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: kubernetes-default-namespace-admins
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: default-admins
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: kubernetes-default-namespace-admins

Більше прикладів для RBAC можна знайти у офіційної документації Kubernetes

Налаштування auth-proxy

Є чудовий проект keycloak-gatekeeper, який дозволяє захистити будь-яку програму, надаючи користувачеві можливість автентифікуватися на сервері OIDC. Я покажу як можна настроїти його на прикладі Kubernetes Dashboard:

dashboard-proxy.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: kubernetes-dashboard-proxy
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: kubernetes-dashboard-proxy
    spec:
      containers:
      - args:
        - --listen=0.0.0.0:80
        - --discovery-url=https://keycloak.example.org/auth/realms/kubernetes
        - --client-id=kubernetes
        - --client-secret=<your-client-secret-here>
        - --redirection-url=https://kubernetes-dashboard.example.org
        - --enable-refresh-tokens=true
        - --encryption-key=ooTh6Chei1eefooyovai5ohwienuquoh
        - --upstream-url=https://kubernetes-dashboard.kube-system
        - --resources=uri=/*
        image: keycloak/keycloak-gatekeeper
        name: kubernetes-dashboard-proxy
        ports:
        - containerPort: 80
          livenessProbe:
            httpGet:
              path: /oauth/health
              port: 80
            initialDelaySeconds: 3
            timeoutSeconds: 2
          readinessProbe:
            httpGet:
              path: /oauth/health
              port: 80
            initialDelaySeconds: 3
            timeoutSeconds: 2
---
apiVersion: v1
kind: Service
metadata:
  name: kubernetes-dashboard-proxy
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: kubernetes-dashboard-proxy
  type: ClusterIP

Джерело: habr.com

Додати коментар або відгук