Вопрос или проблема
У меня определены следующие ClusterRoles:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: deployer-system
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- list
- nonResourceURLs:
- '*'
verbs:
- list
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: deployer-nonsystem
rules:
- apiGroups:
- '*'
resources:
- secrets
- PersistentVolumes
- Role
- RoleBinding
verbs:
- list
- apiGroups:
- '*'
resources:
- deployments
- pods
verbs:
- get
- list
- watch
- create
- update
- patch
- nonResourceURLs:
- '*'
verbs:
- list
Я использую следующие RoleBindings, чтобы назначить пользователю вышеуказанный ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: theuser-nonsystem-role-binding
namespace: nonsystem-namespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: deployer-nonsystem
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: theuser
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: theuser-kube-system-role-binding
namespace: system-namespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: deployer-system
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: theuser
Тем не менее, они могут выполнить kubectl -n [NAMESPACE] get secrets -o yaml
и увидеть все секречные данные. Я ожидал, что этот вызов будет запрещен на основании спецификаций ClusterRole выше.
Что-то у меня упущено или неправильно понято? Почему пользователь может “получить” секречные данные?
ОБНОВЛЕНИЕ: Обратите внимание: моя проблема не в том, что они могут перечислять секречные данные. Моя проблема заключается в том, что пользователь может “получить” секречные данные (разные глаголы!)
Что-то у меня упущено или неправильно понято? Почему пользователь может “получить” секречные данные?
Потому что глагол list
означает “get
, применяемый к нескольким ресурсам”. Когда вы выполняете операцию kubectl get secret
, не указывая конкретный секрет, вы выполняете операцию list
.
Учитывая RBAC в вашем вопросе, я могу запросить все секречные данные в пространстве имен system-namespace
:
$ kubectl -n system-namespace get secret
NAME TYPE DATA AGE
secret1 Opaque 1 2m54s
Но я не могу запросить конкретный секрет:
$ kubectl -n system-namespace get secret secret1
Ошибка с сервера (Forbidden): секреты "secret1" запрещены: Пользователь "lars" не может получить ресурс "secrets" в группе API "" в пространстве имен "system-namespace"
Вы должны рассматривать list
как более мощную версию get
, поскольку она позволяет кому-то перечислять и получать все секречные данные. Только с разрешением get
сущность должна знать имя конкретного секрета, чтобы получить доступ к нему, и вы на самом деле можете ограничить доступ get
к конкретным ресурсам, установив компонент resourceNames
правила.
Предположим, что в system-namespace
есть секречные данные secret1
и secret2
, если у меня есть учетная запись, связанная с следующим ролем:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: deployer-system
rules:
- apiGroups:
- ''
resourceNames:
- secret1
resources:
- secrets
verbs:
- get
Тогда я могу получить только секрет secret1
:
$ kubectl get secret secret1
NAME TYPE DATA AGE
secret1 Opaque 1 10m
$ kubectl get secret secret2
Ошибка с сервера (Forbidden): секреты "secret2" запрещены: Пользователь "lars" не может получить ресурс "secrets" в группе API "" в пространстве имен "system-namespace"
Ответ или решение
Вопрос о том, почему пользователь может получать (get) секреты в Kubernetes, несмотря на предоставленные роли и правила доступа, требует тщательного анализа и понимания механизма распределения прав доступа в кластере.
1. Понимание RBAC и контекста
Система управления доступом на основе ролей (RBAC) в Kubernetes позволяет администраторам контролировать доступ пользователей к ресурсам кластера с помощью ролей (roles) и привязок ролей (role bindings). В вашем случае определены две ClusterRole
— deployer-system
и deployer-nonsystem
, каждая из которых имеет свои правила и ограничения.
2. Анализ ClusterRoles
ClusterRole deployer-system
:
- Позволяет выполнять действие
list
для всех ресурсов и URL. Это означает, что пользователь может получить список всех объектов, но не имеет прав на доступ к конкретным объектам (get).
ClusterRole deployer-nonsystem
:
- Включает явные права на
list
для секретов и других ресурсов, но не имеет прав наget
для секретов в явной форме.
3. Роль привязки и области применения
Пользователь theuser
связан с обеими ролями через RoleBindings:
theuser-nonsystem-role-binding
в пространстве именnonsystem-namespace
.theuser-kube-system-role-binding
в пространстве именsystem-namespace
.
4. Причина, по которой пользователь может получить секреты
Суть в том, что команда kubectl -n [NAMESPACE] get secrets -o yaml
без указания конкретного секрета фактически выполняет действие list
, что разрешено ролью deployer-nonsystem
. Однако ожидаемое вами поведение — ограничение на доступ к конкретным секретам с использованием действия get
.
Когда вы выполняете команду kubectl get secrets
без ключа -o yaml
, Kubernetes считает это list
операцией, и если в правилах указано, что list
разрешен, запрос будет успешным.
5. Как ограничить доступ
Если вы хотите строго контролировать доступ к конкретным секретам, вам необходимо создать более специфические правила с использованием параметра resourceNames
в ClusterRole
. Например:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: deployer-system-limited
rules:
- apiGroups:
- ''
resources:
- secrets
resourceNames:
- secret1
verbs:
- get
Эта роль позволит пользователю получать только указанный секрет secret1
, и запросы к другим секретам вызовут ошибку доступа.
Заключение
Вопрос о получении секретов в Kubernetes не прост и требует внимательного анализа RBAC-правил и их применения. Понимание того, как работают методы get
и list
, критично для управления доступом. Использование параметра resourceNames
для задания конкретных объектов в разрешениях — это способ повышения безопасности и контроля в вашем кластере.