Kubernetes Secrets Engine для Stronghold генерирует токены ServiceAccount Kubernetes (не путать с токенами Stronghold), а также, по желанию, сами объекты ServiceAccount, Role и RoleBinding. Созданные токены имеют настраиваемый срок жизни (TTL), а все созданные объекты автоматически удаляются по истечении срока аренды (lease) Stronghold.
На каждую аренду Stronghold создаёт токен для конкретного ServiceAccount. Токен возвращается вызывающей стороне.
Для большей информации о ресурсах Kubernetes ознакомьтесь с официальной документацией Kubernetes service account и Kubernetes RBAC.
Не используйте токены, созданные механизмом секретов Kubernetes, для аутентификации с помощью Kubernetes Auth Method. Это приведёт к созданию множества уникальных идентификаторов в Stronghold, которыми будет сложно управлять.
Настройка
Перед использованием механизма секретов Kubernetes, необходимо предварительно его настроить. Эти шаги обычно выполняются администратором Stronghold или инструментом автоматического управления конфигурацией.
По умолчанию Stronghold подключается к Kubernetes, используя собственный ServiceAccount.
При использовании Helm chart этот ServiceAccount
создаётся автоматически по умолчанию и называется по имени релиза Helm (по умолчанию stronghold,
но это можно настроить через значение Helm server.serviceAccount.name).
Убедитесь, что ServiceAccount, который использует Stronghold, имеет права на управление токенами ServiceAccount, а при использовании соответствующих функций — и на управление ServiceAccount, ролями и привязками ролей. Этими правами можно управлять с помощью тех же ролей Kubernetes. Роль привязывается к ServiceAccount Stronghold с помощью привязки роли или привязки кластерной роли.
Например, роль кластера только для создания токенов ServiceAccount:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: k8s-minimal-secrets-abilities
rules:
- apiGroups: [""]
resources: ["serviceaccounts/token"]
verbs: ["create"]Аналогичным образом можно создать кластерную роль с бóльшими правами. В данном случае установлены права на управление токенами, ServiceAccount, привязками ролей к ServiceAccount и ролями.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: k8s-full-secrets-abilities
rules:
- apiGroups: [""]
resources: ["serviceaccounts", "serviceaccounts/token"]
verbs: ["create", "update", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings", "clusterrolebindings"]
verbs: ["create", "update", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "clusterroles"]
verbs: ["bind", "escalate", "create", "update", "delete"]Создайте эту роль в Kubernetes (например, с помощью d8 k apply -f).
Если вы хотите выбирать неймспейсы, в которых может действовать роль, по лейблам (label selector), предоставьте Stronghold разрешение на чтение неймспейсов.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: k8s-full-secrets-abilities-with-labels
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get"]
- apiGroups: [""]
resources: ["serviceaccounts", "serviceaccounts/token"]
verbs: ["create", "update", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings", "clusterrolebindings"]
verbs: ["create", "update", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "clusterroles"]
verbs: ["bind", "escalate", "create", "update", "delete"]Получение правильных разрешений для Stronghold, скорее всего, потребует проб и ошибок, поскольку Kubernetes имеет строгую защиту от повышения привилегий. Подробнее об этом можно прочитать в документации Kubernetes RBAC
Защитите ServiceAccount Stronghold, особенно если вы выдаёте ему широкие права: по сути он является учётной записью администратора кластера.
Создайте привязку роли, чтобы связать её с ServiceAccount Stronghold и предоставить Stronghold разрешение на управление токенами.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: stronghold-token-creator-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: k8s-minimal-secrets-abilities
subjects:
- kind: ServiceAccount
name: stronghold
namespace: strongholdДля получения дополнительной информации о ролях Kubernetes, ServiceAccount, привязках и токенах посетите раздел документации Kubernetes RBAC.
Если Stronghold не будет автоматически управлять ролями или ServiceAccount, настройте ServiceAccount, для которого Stronghold будет выпускать токены. Подробнее об автоматическом управлении — в разделе «Автоматическое управление ролями и ServiceAccount».
Выпускайте токены для ServiceAccount, который НЕ совпадает с ServiceAccount самого Stronghold. Иначе получатели токенов получат права, которые Stronghold использует для управления кластером.
Примеры ниже находятся в неймспейсе
test, который вы можете создать, если он ещё не существует.
$ d8 k create namespace test
namespace/test created
Здесь представлена простая настройка ServiceAccount, роли и
привязки роли в неймспейсе Kubernetes test с базовыми разрешениями,
используемыми в примерах:
apiVersion: v1
kind: ServiceAccount
metadata:
name: test-service-account-with-generated-token
namespace: test
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: test-role-list-pods
namespace: test
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-role-abilities
namespace: test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: test-role-list-pods
subjects:
- kind: ServiceAccount
name: test-service-account-with-generated-token
namespace: testВы можете создать эти объекты с помощью команды d8 k apply -f.
Включите механизм секретов Kubernetes:
$ stronghold secrets enable kubernetes
Success! Enabled the kubernetes Secrets Engine at: kubernetes/
По умолчанию движок секретов будет монтироваться по тому же имени, что и его название,
то есть kubernetes/. Это можно изменить, передав аргумент -path при включении.
Настройте точку монтирования. Допускается пустая конфигурация.
stronghold write -f kubernetes/config- Теперь можно настроить роль Stronghold в механизме секретов Kubernetes (не то же самое, что роль Kubernetes), которая сможет генерировать токены Kubernetes для созданного нами ServiceAccount:
stronghold write kubernetes/roles/my-role allowed_kubernetes_namespaces="*" service_account_name="test-service-account-with-generated-token" token_default_ttl="10m"Создание учётных данных
После того как пользователь прошёл аутентификацию в Stronghold и получил достаточные права,
запись в эндпоинт creds для роли Stronghold сгенерирует и вернёт новый токен ServiceAccount.
$ stronghold write kubernetes/creds/my-role kubernetes_namespace=test
Key Value
–-- -----
lease_id kubernetes/creds/my-role/31d771a6-...
lease_duration 10m0s
lease_renwable false
service_account_name test-service-account-with-generated-token
service_account_namespace test
service_account_token eyJHbGci0iJSUzI1NiIsImtpZCI6ImlrUEE...
Вы можете использовать указанный выше токен ServiceAccount (eyJHbG...) для любого
авторизованного запроса к Kubernetes API. Авторизацией управляют привязки ролей к ServiceAccount.
$ curl -sk $(d8 k config view --minify -o 'jsonpath={.clusters[].cluster.server}')/api/v1/namespaces/test/pods --header "Authorization: Bearer eyJHbGci0iJSUzI1Ni..."
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "1624"
},
"items": []
}
После истечения срока аренды, можно удостовериться, что токен был отозван и больше не может быть использован для запросов к Kubernetes API.
$ curl -sk $(d8 k config view --minify -o 'jsonpath={.clusters[].cluster.server}')/api/v1/namespaces/test/pods --header "Authorization: Bearer eyJHbGci0iJSUzI1Ni..."
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "Unauthorized",
"reason": "Unauthorized",
"code": 401
}
Время жизни токена (TTL)
Токены ServiceAccount Kubernetes имеют время жизни (TTL). Когда срок действия токена истекает, токен автоматически отзывается.
Можно установить стандартное (token_default_ttl) и максимальное время
жизни (token_max_ttl) при создании или настройке роли Stronghold.
stronghold write kubernetes/roles/my-role allowed_kubernetes_namespaces="*" service_account_name="new-service-account-with-generated-token" token_default_ttl="10m" token_max_ttl="2h"Вы также можете задать время жизни (ttl) при генерации токена из эндпоинта creds.
Если время жизни токена не указано, используется значение по умолчанию (и не может превышать максимальный срок (token_max_ttl) роли, если он есть).
$ stronghold write kubernetes/creds/my-role kubernetes_namespace=test ttl=20m
Key Value
–-- -----
lease_id kubernetes/creds/my-role/31d771a6-...
lease_duration 20m0s
lease_renwable false
service_account_name new-service-account-with-generated-token
service_account_namespace test
service_account_token eyJHbGci0iJSUzI1NiIsImtpZCI6ImlrUEE...
Можно проверить время жизни токена JWT-токена. Для этого декодируем токен и конвертируем
поля iat (issued at) и exp (expiration time) из формата timestamp в удобночитаемый.
$ echo 'eyJhbGc...' | cut -d'.' -f2 | base64 -d | jq -r '.iat,.exp|todate'
2022-05-20T17:14:50Z
2022-05-20T17:34:50Z
Аудитория (aud)
Токены в Kubernetes имеют формат JWT, а значит, используют механизм «утверждений» (claims).
Одним из таких является утверждение aud (аудитория) - это строка или массив строк, которые
идентифицируют получателей, для которых предназначен JWT. Для более подробной информации ознакомьтесь со спецификацией JWT audience claim
Вы можете задать аудитории по умолчанию (token_default_audiences) при создании или настройке роли Stronghold.
Если явно не задано, по умолчанию кластер Kubernetes будет использовать свои значения аудитории для токенов ServiceAccount.
stronghold write kubernetes/roles/my-role allowed_kubernetes_namespaces="*" service_account_name="new-service-account-with-generated-token" token_default_audiences="custom-audience"Вы также можете задать аудитории (audiences) при генерации токена из эндпоинта creds.
Если аудитории токена не заданы, то они будут заданы по умолчанию из значения поля token_default_audiences, которое мы указывали ранее.
$ stronghold write kubernetes/creds/my-role kubernetes_namespace=test audiences="another-custom-audience"
Key Value
–-- -----
lease_id kubernetes/creds/my-role/SriWQf0bPZ...
lease_duration 768h
lease_renwable false
service_account_name new-service-account-with-generated-token
service_account_namespace test
service_account_token eyJHbGci0iJSUzI1NiIsImtpZCI6ImlrUEE...
Аудиторию токена можно проверить, расшифровав JWT.
$ echo 'eyJhbGc...' | cut -d'.' -f2 | base64 -d
{"aud":["another-custom-audience"]...
Автоматическое управление ролями и ServiceAccount
При настройке роли Stronghold вы можете передать параметры, чтобы указать, что вы хотите автоматически генерировать ServiceAccount и привязку роли, а также, по желанию, генерировать саму роль Kubernetes.
Если вы хотите настроить роль Stronghold на использование уже существующей роли
Kubernetes, но при этом автоматически создать ServiceAccount и привязку
роли, вы можете задать параметр kubernetes_role_name.
stronghold write kubernetes/roles/auto-managed-sa-role allowed_kubernetes_namespaces="test" kubernetes_role_name="test-role-list-pods"ServiceAccount Stronghold также потребуется доступ к ресурсам, к которым он предоставляет доступ.
Это можно сделать для приведённых выше примеров с помощью команды d8 k -n test create rolebinding --role test-role-list-pods --serviceaccount=stronghold:stronghold stronghold stronghold-test-role-abilities.
Так Kubernetes предотвращает эскалацию привилегий. Более подробную информацию вы можете прочитать в документации к Kubernetes RBAC.
После чего вы можете получить учётные данные с помощью автоматически созданного ServiceAccount.
$ stronghold write kubernetes/creds/auto-managed-sa-role kubernetes_namespace=test
Key Value
--- -----
lease_id kubernetes/creds/auto-managed-sa-role/cujRLYjKZUMQk6dkHBGGWm67
lease_duration 768h
lease_renewable false
service_account_name v-token-auto-man-1653001548-5z6hrgsxnmzncxejztml4arz
service_account_namespace test
service_account_token eyJHbGci0iJSUzI1Ni...
Кроме того, Stronghold может автоматически создать роль в дополнение к ServiceAccount и
привязке роли, указав параметр generated_role_rules, в который передаётся набор правил
JSON или YAML для создаваемой роли.
stronghold write kubernetes/roles/auto-managed-sa-and-role allowed_kubernetes_namespaces="test" generated_role_rules='{"rules":[{"apiGroups":[""],"resources":["pods"],"verbs":["list"]}]}'После этого можно получить учётные данные тем же способом, что и раньше.
$ stronghold write kubernetes/creds/auto-managed-sa-and-role kubernetes_namespace=test
Key Value
--- -----
lease_id kubernetes/creds/auto-managed-sa-and-role/pehLtegoTP8vCkcaQozUqOHf
lease_duration 768h
lease_renewable false
service_account_name v-token-auto-man-1653002096-4imxf3ytjh5hbyro9s1oqdo3
service_account_namespace test
service_account_token eyJHbGci0iJSUzI1Ni...