Метод Kubernetes auth можно использовать для аутентификации в Stronghold с помощью токена ServiceAccount Kubernetes. Этот метод упрощает использование Stronghold приложениями, работающими в подах Kubernetes.

Токен ServiceAccount Kubernetes также можно использовать для входа в систему через метод JWT auth. Причины, по которым JWT auth может быть использован вместо Kubernetes auth, описаны в разделе «Как работать с короткоживущими токенами Kubernetes».

При обновлении до Kubernetes v1.21+, убедитесь, что для параметра конфигурации disable_iss_validation установлено значение true. Если используется путь монтирования по умолчанию, проверить значение параметра можно с помощью команды d8 stronghold read -field disable_iss_validation auth/kubernetes/config. Подробнее — в подразделе «Изменения в поведении JWT-токенов в Kubernetes 1.21+».

Аутентификация

Через CLI

Имя метода аутентификации зависит от способа его создания. В составе Deckhouse Platform (DP) автоматически создаётся метод kubernetes_local, связанный с кластером, в котором запущен Stronghold. Если метод Kubernetes auth создаётся вручную, по умолчанию используется имя kubernetes, если не указан другой путь.

Если метод аутентификации создан под другим именем, укажите его с помощью параметра -path в CLI. Например:

  • Stronghold в DP
  • Stronghold в Linux
d8 stronghold write -path=your-path auth/kubernetes/login role=demo jwt=...
stronghold write -path=your-path auth/kubernetes/login role=demo jwt=...

Через API

Используйте эндпоинт, соответствующий имени метода аутентификации. Если Stronghold развёрнут в составе DP, автоматически созданный метод использует эндпоинт auth/kubernetes_local/login. Если метод аутентификации создан под другим именем, используйте соответствующий эндпоинт. В примере ниже используется метод аутентификации с именем kubernetes.

curl --request POST --data '{"jwt": "<SERVICE_ACCOUNT_JWT>", "role": "demo"}' https://stronghold.example.com/v1/auth/kubernetes/login

Где <SERVICE_ACCOUNT_JWT> — токен ServiceAccount приложения.

В ответе токен Stronghold возвращается в поле auth.client_token:

{
  "auth": {
    "client_token": "38fe9691-e623-7238-f618-c94d4e7bc674",
    "accessor": "78e87a38-84ed-2692-538f-ca8b9f400ab3",
    "policies": ["default"],
    "metadata": {
      "role": "demo",
      "service_account_name": "myapp",
      "service_account_namespace": "default",
      "service_account_secret_name": "myapp-token-pd21c",
      "service_account_uid": "aa9aa8ff-98d0-11e7-9bb7-0800276d99bf"
    },
    "lease_duration": 2764800,
    "renewable": true
  }
}

Конфигурация

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

Чтобы настроить аутентификацию для другого кластера Kubernetes, включите дополнительный экземпляр метода Kubernetes auth:

  1. Включите метод аутентификации Kubernetes:

    • Stronghold в DP
    • Stronghold в Linux
    d8 stronghold auth enable kubernetes
    stronghold auth enable kubernetes
  2. Используйте эндпоинт /config, чтобы настроить Stronghold для работы с новым кластером Kubernetes. Адрес Kubernetes API и TCP-порт можно получить с помощью команды d8 k cluster-info.

    • Stronghold в DP
    • Stronghold в Linux
    d8 stronghold write auth/kubernetes/config token_reviewer_jwt="<your reviewer service account JWT>" kubernetes_host=https://192.168.99.100:<your TCP port or blank for 443> kubernetes_ca_cert=@ca.crt
    stronghold write auth/kubernetes/config token_reviewer_jwt="<your reviewer service account JWT>" kubernetes_host=https://192.168.99.100:<your TCP port or blank for 443> kubernetes_ca_cert=@ca.crt

    Stronghold использует JWT-токен ServiceAccount для проверки подлинности через Kubernetes API. Не передавайте этот токен другим приложениям или сервисам, так как они смогут выполнять запросы к Kubernetes API с правами соответствующего ServiceAccount.

  3. Создайте именованную роль:

    • Stronghold в DP
    • Stronghold в Linux
    d8 stronghold write auth/kubernetes/role/demo bound_service_account_names=myapp bound_service_account_namespaces=default policies=default ttl=1h
    stronghold write auth/kubernetes/role/demo bound_service_account_names=myapp bound_service_account_namespaces=default policies=default ttl=1h

    Эта роль разрешает ServiceAccount myapp в неймспейсе default проходить аутентификацию и назначает ей политику по умолчанию.

Изменения в поведении JWT-токенов в Kubernetes 1.21+

Начиная с версии Kubernetes 1.21, функция Kubernetes BoundServiceAccountTokenVolume включена по умолчанию. В результате JWT-токены, автоматически монтируемые в контейнеры, обладают следующими особенностями:

  • имеют ограниченный срок действия;
  • привязаны к сроку жизни пода и ServiceAccount;
  • значение поля iss зависит от конфигурации кластера.

Изменения в сроке действия токена важно учитывать при настройке опции token_reviewer_jwt. Если используется короткоживущий токен, Kubernetes отзывает его после удаления пода, удаления ServiceAccount или истечения срока действия. После этого Stronghold больше не сможет использовать API TokenReview. Подробнее — в разделе «Как работать с короткоживущими токенами Kubernetes».

По этой причине Kubernetes auth по умолчанию не проверяет значение поля iss. Проверка выполняется Kubernetes при обработке запросов к API TokenReview, поэтому повторно выполнять её на стороне Stronghold не требуется.

Работа с короткоживущими токенами Kubernetes

Существует несколько способов настроить аутентификацию для подов Kubernetes при использовании короткоживущих токенов ServiceAccount. Каждый из них имеет свои преимущества и ограничения, которые рассмотрены в таблице.

ВариантВсе токены короткоживущиеВозможен досрочный отзыв токеновОсобенности
Использовать локальный токен в качестве JWT для валидацииДаДаТребуется развёрнуть Stronghold в кластере Kubernetes
Использовать клиентский JWT в качестве JWT для валидацииДаДаТребуется дополнительная настройка
Использовать долгоживущий токен в качестве JWT для валидацииНетДаБолее простая настройка
Использовать JWT authДаНетКлиентские токены нельзя отозвать до истечения срока действия

По умолчанию Kubernetes продлевает срок действия токенов ServiceAccount до одного года, чтобы упростить переход на использование короткоживущих токенов. Чтобы отключить это поведение, задайте параметр --service-account-extend-token-expiration=false для kube-apiserver или определите собственную конфигурацию тома serviceAccountToken. Подробный пример приведён в разделе «Указание TTL и целевых групп».

Использование токена Stronghold в качестве рецензента JWT

Если Stronghold запущен в поде Kubernetes, используйте JWT-токен локального ServiceAccount. Stronghold периодически перечитывает файл токена, поэтому короткоживущие токены будут работать.

Чтобы использовать локальный токен и сертификат центра сертификации, не указывайте параметры token_reviewer_jwt и kubernetes_ca_cert при настройке метода аутентификации. Stronghold автоматически загрузит их из файлов token и ca.crt, расположенных в директории /var/run/secrets/kubernetes.io/serviceaccount/.

  • Stronghold в DP
  • Stronghold в Linux
d8 stronghold write auth/kubernetes/config kubernetes_host=https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT
stronghold write auth/kubernetes/config kubernetes_host=https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT

Использование JWT клиента в качестве рецензента JWT

При настройке Kubernetes auth можно не указывать параметр token_reviewer_jwt. В этом случае Stronghold будет использовать JWT-токен клиента при обращении к API TokenReview. Также необходимо установить параметр disable_local_ca_jwt=true.

При таком подходе Stronghold не хранит JWT-токены и может использовать короткоживущие токены для всех клиентов. Однако потребуется дополнительно настроить роли и привязки ролей Kubernetes для ServiceAccount, которым разрешена аутентификация в Stronghold. Каждому такому ServiceAccount необходимо предоставить кластерную роль system:auth-delegator:

d8 k create clusterrolebinding myapp-client-auth-delegator --clusterrole=system:auth-delegator --group=group1 --serviceaccount=default:svcaccount1 ...

Использование долгоживущих токенов

Вы можете создать долгоживущий токен, используя инструкции Kubernetes и использовать его в качестве token_reviewer_jwt. В примере ниже для ServiceAccount myapp необходимо предоставить кластерную роль system:auth-delegator:

d8 k apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: myapp-k8s-auth-secret
  annotations:
    kubernetes.io/service-account.name: myapp
type: kubernetes.io/service-account-token
EOF

Этот способ упрощает настройку, но не позволяет воспользоваться преимуществами безопасности, которые обеспечивают короткоживущие токены.

Использование JWT auth

Kubernetes auth использует API TokenReview. Вместе с тем JWT-токены Kubernetes можно проверять, используя Kubernetes в качестве OIDC-провайдера. Инструкции по настройке приведены в документации по методу JWT auth.

Это решение позволяет использовать короткоживущие токены для всех клиентов и не требует настройки token_reviewer_jwt. Однако клиентские токены нельзя отозвать до истечения срока их действия, поэтому задавайте небольшое значение TTL, чтобы сократить время действия скомпрометированного токена.

Настройка Kubernetes

Метод Kubernetes auth использует Kubernetes TokenReview API для проверки того, что предоставленный JWT-токен действителен.

ServiceAccount, используемый этим методом аутентификации, должен иметь разрешение на доступ к TokenReview API. Пример ClusterRoleBinding, представленный ниже, предоставляет необходимые разрешения:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: role-tokenreview-binding
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
subjects:
  - kind: ServiceAccount
    name: myapp-auth
    namespace: default

Дополнительные ресурсы