Autenticando com Tokens de Inicialização

FEATURE STATE: Kubernetes v1.18 [stable]

Os tokens de inicialização são um bearer token simples que devem ser utilizados ao criar novos clusters ou para quando novos nós são registrados a clusters existentes. Eles foram construídos para suportar a ferramenta kubeadm, mas podem ser utilizados em outros contextos para usuários que desejam inicializar clusters sem utilizar o kubeadm. Foram também construídos para funcionar, via políticas RBAC, com o sistema de Inicialização do Kubelet via TLS.

Visão geral dos tokens de inicialização

Os tokens de inicialização são definidos com um tipo especifico de secrets (bootstrap.kubernetes.io/token) que existem no namespace kube-system. Estes secrets são então lidos pelo autenticador de inicialização do servidor de API. Tokens expirados são removidos pelo controlador TokenCleaner no gerenciador de controle - kube-controller-manager. Os tokens também são utilizados para criar uma assinatura para um ConfigMap específico usado no processo de descoberta através de um controlador denominado BootstrapSigner.

Formato do Token

Tokens de inicialização tem o formato abcdef.0123456789abcdef. Mais formalmente, eles devem corresponder a expressão regular [a-z0-9]{6}\.[a-z0-9]{16}.

A primeira parte do token é um identificador ("Token ID") e é considerado informação pública. Ele é utilizado para se referir a um token sem vazar a parte secreta usada para autenticação. A segunda parte é o secret do token e somente deve ser compartilhado com partes confiáveis.

Habilitando autenticação com tokens de inicialização

O autenticador de tokens de inicialização pode ser habilitado utilizando a seguinte opção no servidor de API:

--enable-bootstrap-token-auth

Quando habilitado, tokens de inicialização podem ser utilizado como credenciais bearer token para autenticar requisições no servidor de API.

Authorization: Bearer 07401b.f395accd246ae52d

Tokens são autenticados como o usuário system:bootstrap:<token id> e são membros do grupo system:bootstrappers. Grupos adicionais podem ser especificados dentro do secret do token.

Tokens expirados podem ser removidos automaticamente ao habilitar o controlador tokencleaner do gerenciador de controle - kube-controller-manager.

--controllers=*,tokencleaner

Formato do secret dos tokens de inicialização

Cada token válido possui um secret no namespace kube-system. Você pode encontrar a documentação completa aqui.

Um secret de token se parece com o exemplo abaixo:

apiVersion: v1
kind: Secret
metadata:
 # Nome DEVE seguir o formato "bootstrap-token-<token id>"
 name: bootstrap-token-07401b
 namespace: kube-system
 
# Tipo DEVE ser 'bootstrap.kubernetes.io/token'
type: bootstrap.kubernetes.io/token
stringData:
 # Descrição legível. Opcional.
 description: "The default bootstrap token generated by 'kubeadm init'."
 
 # identificador do token e _secret_. Obrigatório.
 token-id: 07401b
 token-secret: f395accd246ae52d
 
 # Validade. Opcional.
 expiration: 2017-03-10T03:22:11Z
 
 # Usos permitidos.
 usage-bootstrap-authentication: "true"
 usage-bootstrap-signing: "true"
 
 # Grupos adicionais para autenticar o token. Devem começar com "system:bootstrappers:"
 auth-extra-groups: system:bootstrappers:worker,system:bootstrappers:ingress

O tipo do secret deve ser bootstrap.kubernetes.io/token e o nome deve seguir o formato bootstrap-token-<token id>. Ele também tem que existir no namespace kube-system.

Os membros listados em usage-bootstrap-* indicam qual a intenção de uso deste secret. O valor true deve ser definido para que seja ativado.

  • usage-bootstrap-authentication indica que o token pode ser utilizado para autenticar no servidor de API como um bearer token.
  • usage-bootstrap-signing indica que o token pode ser utilizado para assinar o ConfigMap cluster-info como descrito abaixo.

O campo expiration controla a expiração do token. Tokens expirados são rejeitados quando usados para autenticação e ignorados durante assinatura de ConfigMaps. O valor de expiração é codificado como um tempo absoluto UTC utilizando a RFC3339. Para automaticamente remover tokens expirados basta habilitar o controlador tokencleaner.

Gerenciamento de tokens com kubeadm

Você pode usar a ferramenta kubeadm para gerenciar tokens em um cluster. Veja documentação de tokens kubeadm para mais detalhes.

Assinatura de ConfigMap

Além de autenticação, os tokens podem ser utilizados para assinar um ConfigMap. Isto pode ser utilizado em estágio inicial do processo de inicialização de um cluster, antes que o cliente confie no servidor de API. O Configmap assinado pode ser autenticado por um token compartilhado.

Habilite a assinatura de ConfigMap ao habilitar o controlador bootstrapsigner no gerenciador de controle - kube-controller-manager.

--controllers=*,bootstrapsigner

O ConfigMap assinado é o cluster-info no namespace kube-public. No fluxo típico, um cliente lê o ConfigMap enquanto ainda não autenticado e ignora os erros da camada de transporte seguro (TLS). Ele então valida o conteúdo do ConfigMap ao verificar a assinatura contida no ConfigMap.

O ConfigMap pode se parecer com o exemplo abaixo:

apiVersion: v1
kind: ConfigMap
metadata:
 name: cluster-info
 namespace: kube-public
data:
 jws-kubeconfig-07401b: eyJhbGciOiJIUzI1NiIsImtpZCI6IjA3NDAxYiJ9..tYEfbo6zDNo40MQE07aZcQX2m3EB2rO3NuXtxVMYm9U
 kubeconfig: |
   apiVersion: v1
   clusters:
   - cluster:
       certificate-authority-data: <really long certificate data>
       server: https://10.138.0.2:6443
     name: ""
   contexts: []
   current-context: ""
   kind: Config
   preferences: {}
   users: []   

O membro kubeconfig do ConfigMap é um arquivo de configuração contendo somente as informações do cluster preenchidas. A informação chave sendo comunicada aqui está em certificate-authority-data. Isto poderá ser expandido no futuro.

A assinatura é feita utilizando-se assinatura JWS em modo "separado". Para validar a assinatura, o usuário deve codificar o conteúdo do kubeconfig de acordo com as regras do JWS (codificando em base64 e descartando qualquer = ao final). O conteúdo codificado e então usado para formar um JWS inteiro, inserindo-o entre os 2 pontos. Você pode verificar o JWS utilizando o esquema HS256 (HMAC-SHA256) com o token completo (por exemplo: 07401b.f395accd246ae52d) como o secret compartilhado. Usuários devem verificar que o algoritmo HS256 (que é um método de assinatura simétrica) está sendo utilizado.

Aviso: Qualquer parte em posse de um token de inicialização pode criar uma assinatura válida daquele token. Não é recomendável, quando utilizando assinatura de ConfigMap, que se compartilhe o mesmo token com muitos clientes, uma vez que um cliente comprometido pode abrir brecha para potenciais "homem no meio" entre outro cliente que confia na assinatura para estabelecer inicialização via camada de transporte seguro (TLS).

Consulte a seção de detalhes de implementação do kubeadm para mais informações.