Імперсонізація користувача — це метод, що дозволяє автентифікованим користувачам діяти від імені іншого користувача, групи або облікового запису служби через HTTP-заголовки.
Користувач може діяти від імені іншого користувача через заголовки імперсонізації. Це дозволяє вручну перевизначити інформацію про користувача, який виконує запит. Наприклад, адміністратор може використовувати цю функцію для налагодження політики авторизації, тимчасово видаючи себе за іншого користувача та перевіряючи, чи запит відхилено.
Запити на імперсонізацією спочатку автентифікуються як запити від імені запитувача, потім переключаються на інформацію для імперсонованої особи.
Для здійснення запиту на імперсонізацію можна використовувати такі заголовки HTTP:
Impersonate-User: Імʼя користувача, від імені якого потрібно діяти.Impersonate-Uid: Унікальний ідентифікатор, який представляє користувача, від імені якого потрібно виконувати дії. Опціонально. Вимагається "Impersonate-User". Kubernetes не накладає жодних вимог до формату цього рядка.Impersonate-Group: Імʼя групи, від імені якої потрібно діяти. Може бути надана кілька разів для встановлення кількох груп. Опціонально. Вимагається "Impersonate-User".Impersonate-Extra-( extra name ): Динамічний заголовок, що використовується для асоціації додаткових полів з користувачем. Опціонально. Вимагається "Impersonate-User". Для збереження послідовності, ( extra name ) має бути у нижньому регістрі, а будь-які символи, які не є допустимими у заголовках HTTP мають бути закодовані у UTF8 та процентно-кодовані.( extra name ) міг містити лише символи, які були допустимими в HTTP-заголовках.Impersonate-Uid доступний лише у версіях 1.22.0 і вище.Приклад заголовків імперсонізації при імперсонуванні користувача з групами:
Impersonate-User: jane.doe@example.com
Impersonate-Group: developers
Impersonate-Group: admins
Приклад заголовків імперсонізації при імперсонуванні користувача з UID та додатковими полями:
Impersonate-User: jane.doe@example.com
Impersonate-Uid: 06f6ce97-e2c5-4ab8-7ba5-7654dd08d52b
Impersonate-Extra-dn: cn=jane,ou=engineers,dc=example,dc=com
Impersonate-Extra-acme.com%2Fproject: some-project
Impersonate-Extra-scopes: view
Impersonate-Extra-scopes: development
Для використання kubectl встановіть аргумент командного рядка --as для налаштування заголовка Impersonate-User, ви також можете встановити прапорець --as-group для налаштування заголовка Impersonate-Group,використовуйте прапорець --as-uid (1.23) для налаштування заголовка Impersonate-Uid, встановіть прапорець --as-user-extra (1.35) для налаштування заголовка Impersonate-Extra-( extra name ).
kubectl drain mynode
Error from server (Forbidden): User "clark" cannot get nodes at the cluster scope. (get nodes mynode)
Встановіть прапорці --as і --as-group:
kubectl drain mynode --as=superman --as-group=system:masters
node/mynode cordoned
node/mynode drained
Для імперсонізації користувача, ідентифікатора користувача (UID), групи або додаткових полів, користувач, який виконує імперсонізацію, повинен мати можливість виконувати дію impersonate з типом атрибута, який імперсонується ("user", "group", "uid" і т.д.). Для кластерів, що використовують втулок авторизації RBAC, наступна роль ClusterRole охоплює правила, необхідні для налаштування заголовків імперсонізації користувачів і груп:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: impersonator
rules:
- apiGroups: [""]
resources: ["users", "groups", "serviceaccounts"]
verbs: ["impersonate"]
Для імперсонізації, додаткові поля та імперсоновані UID належать до групи apiGroup "authentication.k8s.io". Додаткові поля оцінюються як субресурси ресурсу "userextras". Щоб дозволити користувачеві використовувати заголовки імперсонізації для додаткового поля scopes та для UID, користувачеві слід надати таку роль:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: scopes-and-uid-impersonator
rules:
# Може встановлювати заголовок "Impersonate-Extra-scopes" та заголовок "Impersonate-Uid".
- apiGroups: ["authentication.k8s.io"]
resources: ["userextras/scopes", "uids"]
verbs: ["impersonate"]
Значення заголовків імперсонізації також можна обмежити, обмеживши набір resourceNames, які ресурс може приймати.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: limited-impersonator
rules:
# Може імперсонувати користувача "jane.doe@example.com"
- apiGroups: [""]
resources: ["users"]
verbs: ["impersonate"]
resourceNames: ["jane.doe@example.com"]
# Може імперсонувати групи "developers" та "admins"
- apiGroups: [""]
resources: ["groups"]
verbs: ["impersonate"]
resourceNames: ["developers","admins"]
# Може імперсонувати додаткове поле "scopes" зі значеннями "view" і "development"
- apiGroups: ["authentication.k8s.io"]
resources: ["userextras/scopes"]
verbs: ["impersonate"]
resourceNames: ["view", "development"]
# Може імперсонувати UID "06f6ce97-e2c5-4ab8-7ba5-7654dd08d52b"
- apiGroups: ["authentication.k8s.io"]
resources: ["uids"]
verbs: ["impersonate"]
resourceNames: ["06f6ce97-e2c5-4ab8-7ba5-7654dd08d52b"]
Імперсонізація користувача або групи дозволяє виконувати будь-яку дію від імені цього користувача або групи; з цієї причини імперсонізація не є обмеженою за простором імен. Якщо ви хочете дозволити імперсонізацію за допомогою Kubernetes RBAC, це вимагає використання ClusterRole та ClusterRoleBinding, а не Role та RoleBinding.
Надання імперсонізації через ServiceAccounts є обмеженою за простором імен, але імперсонований ServiceAccount може виконувати дії поза межами простору імен.
Kubernetes v1.35 [alpha](стандартно вимкнено)Дія impersonate не може бути обмежена. Вона або надає повну імперсонізацію, або взагалі не надає її. Після надання дозволу на імперсонізацію користувача, ви можете виконувати будь-яку дію, яку цей користувач може виконувати у всіх ресурсах і просторах імен.
З обмеженою імперсонізацією, імперсонатор може мати обмеження на дії від імені іншого користувача лише для певних дій на певних ресурсах, а не мати можливість виконувати всі дії, які може виконувати імперсонований користувач.
Ця функція вмикається шляхом використання функціональної можливості ConstrainedImpersonation.
Обмежена імперсонізація вимагає два окремі дозволи:
list та watch подів у просторі імен default)Це означає, що імперсонатор може бути обмежений виконанням дій від імені іншого користувача лише для певних операцій.
Обмежена імперсонізація визначає три окремі режими, кожен з яких має свій набір дій:
Використовуйте цей режим для виконання дій від імені звичайного користувача ( не службового облікового запису). Цей режим застосовується, коли значення заголовка Impersonate-User:
system:serviceaccount:system:node:Дієслова:
impersonate:user-info — Дозвіл на імперсонування конкретного користувача, групи, UID або додаткового поляimpersonate-on:user-info:<verb> — Дозвіл на виконання <verb> під час імперсонування загального користувачаВиокристовуйте цей режим для виконання дій від імені ServiceAccounts.
Дієслова:
impersonate:serviceaccount — Дозвіл на імперсонування конкретного службового облікового записуimpersonate-on:serviceaccount:<verb> — Дозвіл на виконання <verb> під час імперсонування службового облікового записуВикористовуйте ці режими для імперсонування вузлів. Цей режим застосовується, коли значення заголовка Impersonate-User починається з system:node:.
Дієслова:
impersonate:arbitrary-node — Дозвіл на імперсонування будь-якого вказаного вузлаimpersonate:associated-node — Дозвіл на імперсонування лише вузла, до якого привʼязаний імперсонаторimpersonate-on:arbitrary-node:<verb> — Дозвіл на виконання <verb> під час імперсонування будь-якого вузлаimpersonate-on:associated-node:<verb> — Дозвіл на виконання <verb> під час імперсонування повʼязаного вузлаimpersonate:associated-node застосовується лише тоді, коли імперсонатор є службовим обліковим записом, привʼязаним до вузла, який він намагається імперсонувати. Це визначається шляхом перевірки, чи містить інформація про користувача службового облікового запису додаткове поле з ключем authentication.kubernetes.io/node-name, яке відповідає вузлу, що імперсонується.Усі дозволи на обмежене імперсонування використовують групу API authentication.k8s.io. Ось як налаштувати різні режими.
Цей приклад показує, як дозволити службовому обліковому запису видавати себе за користувача з іменем jane.doe@example.com, але тільки для list і watch подів у просторі імен default. Вам потрібні як ClusterRoleBinding для дозволу на ідентифікацію, так і RoleBinding для дозволу на дію
Крок 1: Надайте дозвіл видавати себе за користувача
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: impersonate-jane-identity
rules:
- apiGroups: ["authentication.k8s.io"]
resources: ["users"]
resourceNames: ["jane.doe@example.com"]
verbs: ["impersonate:user-info"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: impersonate-jane-identity
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: impersonate-jane-identity
subjects:
- kind: ServiceAccount
name: my-controller
namespace: default
Крок 2: Надайте дозвіл на виконання певних дій під час імперсонізації
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: impersonate-list-watch-pods
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs:
- "impersonate-on:user-info:list"
- "impersonate-on:user-info:watch"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: impersonate-list-watch-pods
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: impersonate-list-watch-pods
subjects:
- kind: ServiceAccount
name: my-controller
namespace: default
Тепер службовий обліковий запис my-controller може видавати себе за jane.doe@example.com, щоб переглядати та спостерігати за подами в просторі імен default, але не може виконувати інші дії, такі як видалення подів або доступ до ресурсів в інших просторах імен.
Щоб дозволити імперсонувати службовий обліковий запис з іменем app-sa у просторі імен production для створення та оновлення Deployment:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: impersonate-app-sa
namespace: default
rules:
- apiGroups: ["authentication.k8s.io"]
resources: ["serviceaccounts"]
resourceNames: ["app-sa"]
# Для службових облікових записів необхідно вказати простір імен у RoleBinding.
verbs: ["impersonate:serviceaccount"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: impersonate-manage-deployments
namespace: production
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs:
- "impersonate-on:serviceaccount:create"
- "impersonate-on:serviceaccount:update"
- "impersonate-on:serviceaccount:patch"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: impersonate-app-sa
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: impersonate-app-sa
subjects:
- kind: ServiceAccount
name: deputy-controller
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: impersonate-manage-deployments
namespace: production
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: impersonate-manage-deployments
subjects:
- kind: ServiceAccount
name: deputy-controller
namespace: default
Щоб дозволити службовому обліковому запису node-impersonator у просторі імен default імперсонувати вузол з іменем mynode для отримання та перегляду подів:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: impersonate-node-sa
rules:
- apiGroups: ["authentication.k8s.io"]
resources: ["nodes"]
resourceNames: ["mynode"]
verbs: ["impersonate:arbitrary-node"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: impersonate-list-pods
rules:
- apiGroups: [""]
resources: ["pods"]
verbs:
- "impersonate-on:arbitrary-node:list"
- "impersonate-on:arbitrary-node:get"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: impersonate-node-sa
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: impersonate-node-sa
subjects:
- kind: ServiceAccount
name: node-impersonator
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: impersonate-list-pods
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: impersonate-list-pods
subjects:
- kind: ServiceAccount
name: node-impersonator
namespace: default
Це типовий шаблон для агентів вузлів (таких як втулки CNI), яким потрібно читати поди на своєму вузлі, не маючи доступу до подів у всьому кластері.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: impersonate-associated-node-identity
rules:
- apiGroups: ["authentication.k8s.io"]
resources: ["nodes"]
verbs: ["impersonate:associated-node"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: impersonate-list-pods-on-node
rules:
- apiGroups: [""]
resources: ["pods"]
verbs:
- "impersonate-on:associated-node:list"
- "impersonate-on:associated-node:get"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: node-agent-impersonate-node
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: impersonate-associated-node-identity
subjects:
- kind: ServiceAccount
name: node-agent
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: node-agent-impersonate-list-pods
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: impersonate-list-pods-on-node
subjects:
- kind: ServiceAccount
name: node-agent
namespace: kube-system
Контролер отримає імʼя вузла за допомогою API downward:
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
Потім налаштуйте kubeconfig для імперсонації:
kubeConfig, _ := clientcmd.BuildConfigFromFlags("", "")
kubeConfig.Impersonate = rest.ImpersonationConfig{
UserName: "system:node:" + os.Getenv("MY_NODE_NAME"),
}
З точки зору клієнта, використання обмеженої імперсонації ідентичне використанню традиційної імперсонації. Ви використовуєте ті самі заголовки імперсонації:
Impersonate-User: jane.doe@example.com
Або з kubectl:
kubectl get pods -n default --as=jane.doe@example.com
Різниця полягає виключно в перевірках авторизації, що виконуються сервером API.
impersonateЯкщо у вас є наявні правила RBAC, що використовують дієслово impersonate, вони продовжують функціонувати, коли функціональну можливість увімкнено.
Коли надходить запит на імперсонацію, сервер API спочатку перевіряє дозволи на обмежену імперсонацію. Якщо ці перевірки не проходять, він переходить до перевірки дозволу impersonate.
Для кожного запиту на імперсонацію реєструється подія аудиту, щоб допомогти відстежувати, як використовується імперсонація.
Коли запит використовує обмежену імперсонацію, подія аудиту включає обʼєкт authenticationMetadata з полем impersonationConstraint, яке вказує, яке обмежене дієслово імперсонації було використано для авторизації запиту.
Приклад події аудиту:
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"user": {
"username": "system:serviceaccount:default:my-controller"
},
"impersonatedUser": {
"username": "jane.doe@example.com"
},
"authenticationMetadata": {
"impersonationConstraint": "impersonate:user-info"
},
"verb": "list",
"objectRef": {
"resource": "pods",
"namespace": "default"
}
}
Значення impersonationConstraint вказує, який режим був використаний (наприклад, impersonate:user-info, impersonate:associated-node). Конкретна дія (наприклад, list) може бути визначена з поля verb в аудиторській події.