Деталі механізмів авторизації Kubernetes і підтримувані режими авторизації.
Авторизація запитів до API в Kubernetes відбувається всередині API-сервера. API-сервер оцінює всі атрибути запиту щодо всіх політик, потенційно також звертаючись до зовнішніх сервісів, і потім дозволяє або відхиляє запит.
Усі частини запиту до API повинні бути дозволені деяким механізмом авторизації, щоб він міг продовжити виконання. Іншими словами: типово доступ заборонений.
Щоб визначити дієслово запиту для точки доступу API ресурсу, Kubernetes зіставляє використаний HTTP-метод із дієсловом і враховує, чи діє запит на окремий ресурс чи на колекцію ресурсів:
Іноді Kubernetes перевіряє авторизацію для додаткових дозволів, використовуючи спеціалізовані дієслова. Наприклад:
Kubernetes очікує атрибути, які є загальними для запитів до REST API. Це означає, що авторизація в Kubernetes працює з наявними системами контролю доступу на рівні організації або хмарного провайдера, які можуть обробляти інші API, крім API Kubernetes.
API-сервер Kubernetes може авторизувати запит, використовуючи один з декількох режимів авторизації:
Налаштування API-сервера за допомогою конфігураційного файлу авторизації
СТАН ФУНКЦІОНАЛУ:
GA since Kubernetes v1.32; (стандартно увімкнено)
More information about this feature
This is a stable feature in Kubernetes, and has been since version 1.32. It was first available in the v1.29 release.
Kubernetes дозволяє налаштовувати ланцюжки авторизації, які можуть включати декілька вебхуків. Елементи авторизації в цьому ланцюжку можуть мати чітко визначені параметри, які перевіряють запити в певному порядку, пропонуючи вам тонке налаштування, наприклад, явну відмову (Deny) у разі збоїв.
Підхід з використанням конфігураційного файлу навіть дозволяє вам вказувати правила CEL для попередньої фільтрації запитів перед їх відправленням до вебхуків, допомагаючи вам уникнути непотрібних викликів. API-сервер також автоматично перезавантажує ланцюжок авторизаторів при зміні конфігураційного файлу.
Ви вказуєте шлях до конфігурації авторизації за допомогою аргументу командного рядка --authorization-config.
Якщо ви хочете використовувати аргументи командного рядка замість конфігураційного файлу, це також є дійсним і підтримуваним підходом. Деякі можливості авторизації (наприклад: кілька вебхуків, політика обробки збоїв вебхука та правила попередньої фільтрації) доступні тільки при використанні конфігураційного файлу авторизації.
Приклад конфігурації
---
#
# НЕ ВИКОРИСТОВУЙТЕ КОНФІГУРАЦІЮ ТАК, ЯК ВОНА Є. ЦЕ ПРИКЛАД.
#
apiVersion: apiserver.config.k8s.io/v1
kind: AuthorizationConfiguration
authorizers:
- type: Webhook
# Назва, що використовується для опису авторизатора
# Це явно використовується в механізмі моніторингу для метрик
# Примітка:
# - Перевірка цього поля схожа на перевірку міток K8s на сьогодні.
# Обовʼязково, немає типового значення
name: webhook
webhook:
# Тривалість кешування відповідей 'authorized' від вебхука
# авторизатора.
# Те саме, що і встановлення прапорця `--authorization-webhook-cache-authorized-ttl`
# Типово: 5m0s
authorizedTTL: 30s
# Якщо встановлено в false, відповіді 'authorized' від вебхука не кешуються
# і вказаний authorizedTTL ігнорується/не має ефекту.
# Те саме, що і встановлення прапорця `--authorization-webhook-cache-authorized-ttl` в `0`.
# Примітка: Встановлення authorizedTTL в `0` призводить до використання його типового значення.
# Типово: true
cacheAuthorizedRequests: true
# Тривалість кешування відповідей 'unauthorized' від вебхука
# авторизатора.
# Те саме, що і встановлення прапорця `--authorization-webhook-cache-unauthorized-ttl`
# Типово: 30s
unauthorizedTTL: 30s
# Якщо встановлено в false, відповіді 'unauthorized' від вебхука не кешуються
# і вказаний unauthorizedTTL ігнорується/не має ефекту.
# Те саме, що і встановлення прапорця `--authorization-webhook-cache-unauthorized-ttl` в `0`.
# Примітка: Встановлення unauthorizedTTL в `0` призводить до використання його типового значення.
# Типово: true
cacheUnauthorizedRequests: true
# Тайм-аут для запиту вебхука
# Максимально допустимий: 30s.
# Обовʼязково, немає типового значення.
timeout: 3s
# Версія API SubjectAccessReview з authorization.k8s.io, яка
# надсилається до вебхука та очікується від нього.
# Те саме, що і встановлення прапорця `--authorization-webhook-version`
# Обовʼязково, немає типового значення
# Допустимі значення: v1beta1, v1
subjectAccessReviewVersion: v1
# MatchConditionSubjectAccessReviewVersion визначає версію SubjectAccessReview,
# за якою обчислюються вирази CEL
# Допустимі значення: v1
# Обовʼязково, немає типового значення
matchConditionSubjectAccessReviewVersion: v1
# Керує рішенням авторизації, коли запит вебхука не вдалося
# виконати, або отримано некоректну відповідь, або сталися помилки під час обчислення
# matchConditions.
# Допустимі значення:
# - NoOpinion: продовжити до наступних авторизаторів, щоб перевірити, чи
# дозволяє один з них запит
# - Deny: відхилити запит без звернення до наступних авторизаторів
# Обовʼязково, немає типового значення.
failurePolicy: Deny
connectionInfo:
# Керує тим, як вебхук повинен спілкуватися з сервером.
# Допустимі значення:
# - KubeConfigFile: використовувати файл, вказаний у kubeConfigFile, для пошуку
# сервера.
# - InClusterConfig: використовувати внутрішньокластерну конфігурацію для виклику
# API SubjectAccessReview, що обслуговується kube-apiserver. Цей режим не
# дозволяється для kube-apiserver.
type: KubeConfigFile
# Шлях до KubeConfigFile з інформацією про підключення
# Обовʼязково, якщо connectionInfo.Type є KubeConfigFile
kubeConfigFile: /kube-system-authz-webhook.yaml
# matchConditions — це список умов, які повинні бути виконані для того, щоб запит було надіслано до цього
# вебхука. Порожній список matchConditions відповідає всім запитам.
# Дозволено не більше 64 умов відповідності.
#
# Точна логіка зіставлення така (по порядку):
# 1. Якщо принаймні одна matchCondition обчислюється як FALSE, тоді вебхук пропускається.
# 2. Якщо ВСІ matchConditions обчислюються як TRUE, тоді вебхук викликається.
# 3. Якщо принаймні одна matchCondition обчислюється з помилкою (але жодна не є FALSE):
# - Якщо failurePolicy=Deny, тоді вебхук відхиляє запит
# - Якщо failurePolicy=NoOpinion, тоді помилка ігнорується, а вебхук пропускається
matchConditions:
# expression — це вираз, який буде обчислено CEL. Має повертати булеве значення.
# Вирази CEL мають доступ до вмісту SubjectAccessReview у версії v1.
# Якщо версія, вказана в subjectAccessReviewVersion, для змінної request є v1beta1,
# вміст буде конвертовано у версію v1 перед обчисленням виразу CEL.
#
# Документація CEL: https://kubernetes.io/docs/reference/using-api/cel/
#
# надсилати до вебхука лише запити до ресурсів
- expression: has(request.resourceAttributes)
# перехоплювати лише запити до kube-system
- expression: request.resourceAttributes.namespace == 'kube-system'
# не перехоплювати запити від службових облікових записів kube-system
- expression: "!('system:serviceaccounts:kube-system' in request.groups)"
- type: Node
name: node
- type: RBAC
name: rbac
- type: Webhook
name: in-cluster-authorizer
webhook:
authorizedTTL: 5m
unauthorizedTTL: 30s
timeout: 3s
subjectAccessReviewVersion: v1
failurePolicy: NoOpinion
connectionInfo:
type: InClusterConfig
Під час налаштування ланцюжка авторизаторів за допомогою файлу конфігурації переконайтеся, що всі вузли панелі управління мають однаковий вміст файлу. Зверніть увагу на конфігурацію API-сервера при оновленні / зниженні версії вашого кластера. Наприклад, якщо ви оновлюєтеся з Kubernetes 1.36 до Kubernetes 1.37, вам потрібно переконатися, що файл конфігурації має формат, який розуміє Kubernetes 1.37, перш ніж ви оновите кластер. Якщо ви знижуєте версію до 1.36, вам потрібно відповідно налаштувати конфігурацію.
Конфігурація авторизації та перезавантаження
Kubernetes перезавантажує файл конфігурації авторизації, коли API-сервер виявляє зміну у файлі, а також за 60-секундним графіком, якщо події змін не спостерігаються.
Примітка:
Ви повинні забезпечити, щоб всі типи авторизаторів, крім вебхука, залишалися незмінними у файлі під час перезавантаження.
Перезавантаження не повинно додавати або видаляти авторизатори Node або RBAC (їх можна перевпорядкувати, але не можна додавати або видаляти).
Конфігурація режиму авторизації через командний рядок
Ви можете використовувати наступні режими:
--authorization-mode=ABAC (режим контролю доступу на основі атрибутів)--authorization-mode=RBAC (режим контролю доступу на основі ролей)--authorization-mode=Node (авторизатор вузлів)--authorization-mode=Webhook (режим авторизації вебхуком)--authorization-mode=AlwaysAllow (завжди дозволяє запити; несе ризики безпеки)--authorization-mode=AlwaysDeny (завжди відхиляє запити)
Ви можете вибрати більше одного режиму авторизації; наприклад:
--authorization-mode=Node,RBAC,Webhook
Kubernetes перевіряє модулі авторизації в порядку, в якому ви вказуєте їх у командному рядку API-сервера, тому раніше зазначений модуль має вищий пріоритет для дозволу або відмови в запиті.
Ви не можете поєднувати аргумент командного рядка --authorization-mode з аргументом командного рядка --authorization-config, який використовується для налаштування авторизації за допомогою локального файлу.
Для отримання додаткової інформації про аргументи командного рядка для API-сервера читайте довідник kube-apiserver.
Підвищення привілеїв через створення або редагування робочих навантажень
Користувачі, які можуть створювати/редагувати Podʼи в просторі імен, або безпосередньо, або через обʼєкт, що дозволяє опосередковане управління робочими навантаженнями, можуть мати можливість підвищити свої привілеї в цьому просторі імен. Потенційні шляхи до підвищення привілеїв включають розширення API Kubernetes та повʼязані з ними контролери.
Увага:
Як адміністратор кластера, будьте обережні, надаючи доступ до створення або редагування робочих навантажень. Деякі деталі того, як вони можуть бути використані не за призначенням, задокументовані в
шляхах підвищення привілеїв.
Шляхи підвищення привілеїв
Існують різні способи, за якими зловмисник або ненадійний користувач може отримати додаткові привілеї в межах простору імен, якщо ви дозволяєте їм запускати довільні Podʼи в цьому просторі імен:
- Монтування довільних Secretʼів в цьому просторі імен
- Може бути використано для доступу до конфіденційної інформації, призначеної для інших робочих навантажень
- Може бути використано для отримання токена службового облікового запису більш привілейованого ServiceAccount
- Використання довільних ServiceAccountʼів в цьому просторі імен
- Може виконувати дії API Kubernetes як інше робоче навантаження (імперсонація)
- Може виконувати будь-які привілейовані дії, які має цей ServiceAccount
- Монтування або використання ConfigMapʼів, призначених для інших робочих навантажень в цьому просторі імен
- Може бути використано для отримання інформації, призначеної для інших робочих навантажень, такої як імена хостів баз даних.
- Монтування томів, призначених для інших робочих навантажень в цьому просторі імен
- Може бути використано для отримання інформації, призначеної для інших робочих навантажень, та її зміни.
Увага:
Як системному адміністратору, вам слід бути обережними при розгортанні CustomResourceDefinition, що дозволяють користувачам вносити зміни у вищезазначених областях. Це може відкрити шляхи до підвищення привілеїв. Розгляньте наслідки такого роду змін, ухвалюючи рішення щодо засобів контролю авторизації.Перевірка доступу до API
kubectl надає підкоманду auth can-i для швидкого запиту до рівня авторизації API. Команда використовує API SelfSubjectAccessReview, щоб визначити, чи може поточний користувач виконати вказану дію, і працює незалежно від режиму авторизації, який використовується.
kubectl auth can-i create deployments --namespace dev
Вивід подібний до цього:
yes
kubectl auth can-i create deployments --namespace prod
Вивід подібний до цього:
no
Адміністратори можуть поєднувати це з імперсонацією користувача, щоб визначити, які дії можуть виконувати інші користувачі.
kubectl auth can-i list secrets --namespace dev --as dave
Вивід подібний до цього:
no
Так само, щоб перевірити, чи може ServiceAccount з іменем dev-sa в Namespace dev отримати перелік Podʼів у Namespace target:
kubectl auth can-i list pods \
--namespace target \
--as system:serviceaccount:dev:dev-sa
Вивід подібний до цього:
yes
SelfSubjectAccessReview є частиною групи API authorization.k8s.io, яка надає доступ до авторизації API-сервера зовнішнім службам. Інші ресурси у цій групі включають:
- SubjectAccessReview
- Перегляд доступу для будь-якого користувача, не лише поточного. Корисно для делегування рішень про авторизацію API-серверу. Наприклад, kubelet та API-сервери розширень використовують це для визначення доступу користувача до своїх власних API.
- LocalSubjectAccessReview
- Подібно до SubjectAccessReview, але обмежено конкретним простором імен.
- SelfSubjectRulesReview
- Перегляд, який повертає набір дій, які користувач може виконати в межах простору імен. Корисно для користувачів для швидкого узагальнення їх власного доступу, або для інтерфейсів користувача для приховування/відображення дій.
Ці API можна опитати, створивши звичайні ресурси Kubernetes, де поле відповіді status поверненого обʼєкта є результатом запиту. Наприклад:
kubectl create -f - -o yaml << EOF
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
spec:
resourceAttributes:
group: apps
resource: deployments
verb: create
namespace: dev
EOF
Створений SelfSubjectAccessReview схожий на:
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
metadata:
creationTimestamp: null
spec:
resourceAttributes:
group: apps
resource: deployments
namespace: dev
verb: create
status:
allowed: true
denied: false
Що далі