У новой учетной записи службы Kubernetes есть разрешения администратора кластера

Я наблюдаю странное поведение недавно созданных учетных записей служб Kubernetes. Похоже, их токены предоставляют неограниченные права доступа в нашем кластере.

Если я создаю новое пространство имен, новую учетную запись службы внутри этого пространства имен, а затем использую токен учетной записи службы в новой конфигурации kube, я могу выполнять все действия в кластере.

# SERVER is the only variable you'll need to change to replicate on your own cluster
SERVER=https://k8s-api.example.com
NAMESPACE=test-namespace
SERVICE_ACCOUNT=test-sa

# Create a new namespace and service account
kubectl create namespace "${NAMESPACE}"
kubectl create serviceaccount -n "${NAMESPACE}" "${SERVICE_ACCOUNT}"

SECRET_NAME=$(kubectl get serviceaccount "${SERVICE_ACCOUNT}" --namespace=test-namespace -o jsonpath='{.secrets[*].name}')
CA=$(kubectl get secret -n "${NAMESPACE}" "${SECRET_NAME}" -o jsonpath='{.data.ca\.crt}')
TOKEN=$(kubectl get secret -n "${NAMESPACE}" "${SECRET_NAME}" -o jsonpath='{.data.token}' | base64 --decode)

# Create the config file using the certificate authority and token from the newly created
# service account
echo "
apiVersion: v1
kind: Config
clusters:
- name: test-cluster
  cluster:
    certificate-authority-data: ${CA}
    server: ${SERVER}
contexts:
- name: test-context
  context:
    cluster: test-cluster
    namespace: ${NAMESPACE}
    user: ${SERVICE_ACCOUNT}
current-context: test-context
users:
- name: ${SERVICE_ACCOUNT}
  user:
    token: ${TOKEN}
" > config

Запуск этого ^ в качестве сценария оболочки дает config в текущем каталоге. Проблема в том, что с помощью этого файла я могу читать и редактировать все ресурсы в кластере. Я бы хотел, чтобы у вновь созданной учетной записи службы не было разрешений, если я явно не предоставлю их через RBAC.

# All pods are shown, including kube-system pods
KUBECONFIG=./config kubectl get pods --all-namespaces

# And I can edit any of them
KUBECONFIG=./config kubectl edit pods -n kube-system some-pod

Я не добавил никаких привязок ролей к вновь созданной учетной записи службы, поэтому я ожидал, что она будет получать ответы об отказе в доступе для всех kubectl запросов с использованием вновь созданной конфигурации.

Ниже приведен пример JWT учетной записи службы test-sa, встроенной в config:

{
  "iss": "kubernetes/serviceaccount",
  "kubernetes.io/serviceaccount/namespace": "test-namespace",
  "kubernetes.io/serviceaccount/secret.name": "test-sa-token-fpfb4",
  "kubernetes.io/serviceaccount/service-account.name": "test-sa",
  "kubernetes.io/serviceaccount/service-account.uid": "7d2ecd36-b709-4299-9ec9-b3a0d754c770",
  "sub": "system:serviceaccount:test-namespace:test-sa"

}

Что нужно учитывать ...

  • Кажется, что RBAC включен в кластере, поскольку я вижу rbac.authorization.k8s.io/v1 и rbac.authorization.k8s.io/v1beta1 в выводе kubectl api-versions | grep rbac, как это предлагается в этот пост. Примечательно, что kubectl cluster-info dump | grep authorization-mode, как предлагается в другом ответе на тот же вопрос, не отображает вывод. Может ли это означать, что RBAC на самом деле не включен?
  • У моего пользователя есть cluster-admin ролевые привилегии, но я не ожидал, что они будут перенесены в учетные записи служб, созданные с его помощью.
  • Мы запускаем наш кластер на GKE.
  • Насколько мне известно, у нас нет неортодоксальных ролей или привязок RBAC в кластере, которые могли бы вызвать это. Я мог что-то упустить или вообще не знаю о конфигурациях K8s RBAC, которые могли бы вызвать это.

Правильно ли я предполагаю, что вновь созданные учетные записи служб должны иметь чрезвычайно ограниченный доступ к кластеру, и описанный выше сценарий не может быть возможен без разрешающих привязок ролей, прикрепленных к новой учетной записи службы? Есть какие-нибудь мысли о том, что здесь происходит, или о способах ограничения доступа к test-sa?


person Brannon    schedule 06.03.2020    source источник
comment
Попробуйте выполнить эту команду, чтобы убедиться, что она выполняется с использованием новой учетной записи службы: kubectl config view --template='{{ range .contexts }}{{ if eq .name "'$(kubectl config current-context)'" }}Current user: {{ .context.user }}{{ end }}{{ end }}'   -  person Mr.KoopaKiller    schedule 09.03.2020
comment
Да, kubectl действительно использует правильный контекст: Current user: test-sa.   -  person Brannon    schedule 09.03.2020
comment
Странно, потому что я выполнил те же самые команды, что и вы, и для меня тестовые команды показали Error from server (Forbidden): pods "some-pod" is forbidden: User "system:serviceaccount:test-namespace:test-sa" cannot get resource "pods" in API group "" in the namespace "kube-system". Я уже проверял kubectl auth can-i, и в моем результате нет ресурсов *.* ... Я пытаюсь понять, почему это происходит. Какая версия кубернетеса?   -  person Mr.KoopaKiller    schedule 09.03.2020
comment
Я только что создал новый кластер GKE (версия 1.15.x, такой же, как и у нашего другого кластера, в котором возникла проблема), и похоже, что вновь созданные учетные записи служб не имеют такого же чрезмерно разрешающего доступа в этом стандартном кластере, как они. делать в кластере выставляя проблему. Мы получаем ту же запрещенную ошибку, которую вы описали, и у нас также нет правила *.*, указанного в команде kubectl auth can-i. Это заставляет меня думать, что @ArghyaSadhu прав, что что-то было неправильно настроено в нашем другом кластере.   -  person Brannon    schedule 09.03.2020


Ответы (3)


Вы можете проверить разрешение учетной записи службы, выполнив команду

kubectl auth can-i --list --as=system:serviceaccount:test-namespace:test-sa

Если вы видите ниже вывод, это очень ограниченное разрешение по умолчанию, которое получает учетная запись службы.

Resources                                       Non-Resource URLs   Resource Names   Verbs
selfsubjectaccessreviews.authorization.k8s.io   []                  []               [create]
selfsubjectrulesreviews.authorization.k8s.io    []                  []               [create]
                                                [/api/*]            []               [get]
                                                [/api]              []               [get]
                                                [/apis/*]           []               [get]
                                                [/apis]             []               [get]
                                                [/healthz]          []               [get]
                                                [/healthz]          []               [get]
                                                [/livez]            []               [get]
                                                [/livez]            []               [get]
                                                [/openapi/*]        []               [get]
                                                [/openapi]          []               [get]
                                                [/readyz]           []               [get]
                                                [/readyz]           []               [get]
                                                [/version/]         []               [get]
                                                [/version/]         []               [get]
                                                [/version]          []               [get]
                                                [/version]          []               [get]
person Arghya Sadhu    schedule 07.03.2020
comment
Это очень полезная команда! Вот результат работы нашего кластера: pastebin.com/raw/zXbk8fR6. Две строки вверху выглядят особенно подозрительно, поскольку их нет в вашем примере и, похоже, они предоставляют широкие разрешения для ресурсов кластера. - person Brannon; 07.03.2020
comment
Есть идеи, что может привести к тому, что новые учетные записи служб будут получать такие разрешения? - person Brannon; 07.03.2020
comment
У вас есть внешний веб-перехватчик, который может выполнять RBAC, то есть назначать роль администратора любой учетной записи службы? что вы получите, если сделаете kubectl get rolebinding - person Arghya Sadhu; 07.03.2020
comment
kubectl get rolebinding в пространстве имен default и test-namespace не показывает никаких неожиданных привязок ролей. Проверяем, выполняем ли мы аутентификацию с помощью внешнего веб-перехватчика ... - person Brannon; 09.03.2020

Мне не удалось воспроизвести вашу проблему на трех разных версиях K8S в моей тестовой лаборатории (включая v1.15.3, v1.14.10-gke.17, v1.11.7-gke.12 - с включенной базовой аутентификацией).

К сожалению, вход в систему на основе токенов не записывается в AuditLogs консоли Cloud Logs для кластеров GKE :(.

Насколько мне известно, записываются только операции доступа к данным, которые проходят через Google Cloud (на основе AIM = kubectl с использованием google auth провайдера).

Если вашей учетной записи службы "test-sa" каким-то образом разрешено выполнять определенные операции через RBAC, я бы все равно попытался изучить Журналы аудита вашего кластера GKE. Возможно, ваша учетная запись службы каким-то образом сопоставляется с учетной записью службы Google и, таким образом, авторизованный.

Вы всегда можете связаться с официальным каналом поддержки GCP, чтобы в дальнейшем устранить неполадки в вашем необычном случае.

person Community    schedule 23.03.2020

Оказывается, к группе system:serviceaccounts был привязан слишком разрешительный cluster-admin ClusterRoleBinding. В результате все учетные записи служб в нашем кластере имели cluster-admin привилегии.

Похоже, что где-то в начале жизни кластера было создано следующее ClusterRoleBinding:

kubectl create clusterrolebinding serviceaccounts-cluster-admin --clusterrole=cluster-admin  --group=system:serviceaccounts

ВНИМАНИЕ: никогда не применяйте это правило к своему кластеру ☝️

С тех пор мы удалили это чрезмерно разрешающее правило и упорядочили все разрешения для учетных записей служб.

Спасибо тем, кто предоставил полезные ответы и комментарии на этот вопрос. Они помогли определить эту проблему. Это была очень опасная конфигурация RBAC, и мы рады, что она решена.

person Brannon    schedule 22.05.2020