Integrando o Azure Active Directory no AKS

Já passamos por artigos sobre como criar usuários e também como atribuir permissões a estes usuários usando RBAC. Porém, utilizar o Kubernetes para poder realizar gerenciamentos de usuários, apesar de simples, não é muito prático justamente por conta da natureza distribuída dos clusters.

Quando criamos um cluster, temos duas boas práticas de segurança que devemos considerar. A primeira é o controle que você tem sobre os recursos da própria Azure, como o próprio cluster e todos os objetos que estão dentro do resource group dele, a outra boa prática é o controle sobre o que seus usuários podem fazer e ver dentro desse cluster.

Azure AD

Uma opção sensacional, provavelmente a melhor para o AKS, para centralizar o gerenciamento de usuários é o chamado Azure Active Directory (AAD). Essencialmente esta é uma integração com o Active Directory nativo da Azure de forma, centralizando o controle.

Utilizar esta opção pode ser uma das melhores práticas porque temos todo o controle sobre tanto os usuários quanto os seus roles e bindings dentro do mesmo local, o portal da Azure.

O AAD funciona sempre que o usuário requisita o arquivo de configuração através do comando az aks get-credentials. Quando isso acontece, existem dois principais roles que são enviados de volta:

  • Role administrativo: Acesso completo a todos os recursos
  • Role de usuário: Acesso restrito à recursos

Quando temos a integração com o AAD habilitada, durante o primeiro download de configurações, o usuário vai ter que logar no portal, a partir daí o perfil correspondente será baixado.

Como funciona

Para entendermos melhor como o AAD funciona, o ideal é entendermos o fluxo completo de como uma integração com active directory funciona em si.

De acordo com a própria documentação da Microsoft, a integração com o AAD provê a usuários e grupos o acesso aos recursos do cluster independentemente se os mesmos estiverem em um namespace ou não.

Quando um usuário faz o login e baixa o arquivo kubeconfig com o comando que vimos anteriormente, o primeiro passo do fluxo é pedir que o usuário se autentique no portal.

Após a autenticação no portal, o cluster verifica no servidor de AD da azure se o usuário existe e pede um token de acesso para o mesmo, este token é utilizado para preencher o arquivo kubeconfig.

Depois do download do arquivo config, o usuário não vai ter as permissões direto no token, mas vai estar integrado no webook do AAD e no servidor de API. Sempre que o usuário executar qualquer comando no Kubectl, um interceptador de chamadas vai usar este token para validar o usuário contra os servidores da Azure e verificar se ele tem permissão para executar o comando.

Se tanto o token JWT quanto o resultado da query na API do MS Graph mostrarem que o usuário tem existe e tem permissão, então a chamada procede para a API do kubernetes que utiliza os próprios Roles e Bindings para verificar se o usuário tem acesso.

O fluxo completo seria mais ou menos assim:

Integrando seu cluster com o AAD

Antes de junho de 2020, precisávamos criar todas as etapas de um servidor AD padrão, isso incluia a criação de uma aplicação de servidor e um client dentro do portal para integrar com a aplicação do AAD.

Agora tudo ficou muito mais simples com a chegada do Azure Managed AAD Integration (Managed AAD). Que, basicamente, abstrai todos os comandos que você teria que executar.

Por mais que seja mais simples, essa facilidade inclui algumas limitações

O primeiro passo para habilitar o Managed AAD no seu cluster é instalar as duas ferramentas mais famosas, o kubectl e o kubelogin, por sorte ambas podem ser instaladas usando o comando az aks install-cli.

Vamos precisar ter um grupo e um usuário iniciais para podermos ter privilégios administrativos para o primeiro usuário do cluster, então podemos usar um grupo existente ou então criar um novo com o seguinte comando:

az ad group create --display-name AKSAdminGroup --mail-nickname AKSAdminGroup

Isso vai te retornar uma série de informações, porém a mais importante delas é o ObjectID. Copie essa informação e guarde, porque vamos precisar dela para nos adicionar ao grupo. Mas para isso vamos precisar descobrir o nosso próprio ID:

az ad user show --id email@delogin.com --query objectId -o tsv

A informação que voltar é o seu ID de usuário. Guarde-o para podermos nos adicionar ao grupo. Mas temos um problema, o email de login não é o mesmo email que o AD pode estar usando, então precisamos achar esse email. Para isso vamos usar o comando de listagem de usuários:

az ad user list --query "[*].{name: displayName, id: userPrincipalName, objectId: objectId}" -o json

Isso te retorna uma lista de todos os usuários e seus IDs de login, você poe então filtrá-los através da chave --id ou então só copiar o ObjectID, porque é só o que é preciso para poder se adicionar no grupo. Então vamos fazer isso:

az ad group member add --group AKSAdminGroup --member-id seuobjectid

Agora já temos nosso usuário dentro do grupo de permissão geral, vamos criar o nosso cluster habilitado:

az aks create \
  -g aks-aad \
  -n aad-cluster \
  --enable-aad \
  --aad-admin-group-object-ids objectIdDoGrupoAdmin

Pegamos as credenciais com az aks get-credentials -g aks-aad -n aad-cluster. Agora que temos o arquivo de configuração, tente executar qualquer comando no kubectl, como kubectl get nodes, veja que você vai receber uma mensagem pedindo para logar no portal.

O AAD já está funcionando, partindo sempre do princípio de Zero Trust, você nunca vai ter nenhuma permissão, somente as que você adicionar.

Adicionando novos usuários e grupos

Agora que temos todas as permissões, vamos adicionar novos usuários e grupos assim como fizemos nos outros artigos. Primeiro precisamos do ID do nosso cluster AKS:

AKSID=$(az aks show -g aks-aad -n aad-cluster --query id -o tsv)

Agora vamos criar um grupo somente leitura chamado AKSReadOnlyGroup e vamos salvar o ObjectID:

GROUPID=$(az ad group create \
  --display-name AKSReadOnlyGroup \
  --mail-nickname \
  --query objectId -o tsv)
 

Esses usuários precisam se logar como usuários e não como administradores. Isso pode ser feito adicionando este grupo a um role existente no AD chamado "Azure Kubernetes Service Cluster User Role". Como vimos antes, isso vai fazer com que os usuários sejam logados como usuários e não como administradores.

O objeto que liga um grupo a um role na Azure é chamado de Role Assignment. Vamos criar um para podermos linkar os dois:

az role assignment create \
  --assignee $GROUPID \
  --role "Azure Kubernetes Service Cluster User Role" \
  --scope $AKSID

Vamos adicionar um novo usuário chamado Alice a este grupo que acabamos de criar, vamos então copiar o ObjectID quando criarmos:

ALICE=$(az ad user create \
  --display-name "Alice Doe" \
  --user-principal-name alice@dominio.com \
  --password S3gr3d0 \
  --query objectid -o tsv)
Lembre-se: Quando criarmos um usuário precisamos de um domínio válido. Para obter este domínio podemos executar o seguinte comando e copiar tudo o que vier depois do "@": az ad user list --query "[*].userPrincipalName" -o json

Adicionamos o usuário ao grupo:

az ad group member add --group AKSReadOnlyGroup --member-id $ALICE

Agora que temos o usuário já criado no AD, vamos criar o role e o binding dele no kubernetes. Como vimos antes, o AAD e o RBAC do kubernetes trabalham juntos para poder prover a solução completa de autenticação.

Dentro do Kubernetes

Primeiro vamos criar o role chamado ReadOnlyRole:

kubectl create clusterrole ReadOnlyRole --verb=get,list,watch --resource="*"

Vamos criar agora o binding deste role ao nosso ID do grupo no AD:

kubectl create clusterrolebinding ReadOnlyBinding \
  --clusterrole=ReadOnlyRole \
  --group=$GROUPID
Podemos também vincular o role a um usuário utilizando o ObjectID do usuário ao invés do ObjectID do grupo no comando acima.

Agora podemos testar essas roles baixando o arquivo de configuração novamente e sobrescrevendo o atual:

az aks get-credentials -g aks-aad -n aad-cluster --overwrite-existing

Na primeira chamada, você precisará fazer o login novamente com email e senha. Vamos usar o email da Alice para fazer isso (o email que você usou quando criou o usuário da Alice), assim como a senha definida.

Depois de um login bem sucedido, tente executar uma lista de pods do namespace kube-system. Você vai conseguir porque o usuário da Alice tem permissão para listar todos os pods em todos os namespaces, porém se você tentar criar qualquer coisa, como:

kubectl run nginx-dev --image nginx --namespace default

Você vai receber uma mensagem de "proibido".

Conclusão

Aprendemos como podemos utilizar ainda mais do poder da Azure para integrar autenticações e mais facilidades no nosso cluster AKS. Com esse tipo de integração podemos deixar nosso cluster ainda mais seguro.

Até mais!