Introdução à autorização Kubernetes do Hashicorp Consul
Isso mesmo, após o lançamento Cônsul Hashicorp 1.5.0 no início de maio de 2019, no Consul você pode autorizar aplicações e serviços rodando nativamente no Kubernetes.
Neste tutorial vamos criar passo a passo POC (Prova de conceito, PoC) demonstrando esse novo recurso. Espera-se que você tenha conhecimento básico de Kubernetes e do Consul da Hashicorp. Embora você possa usar qualquer plataforma de nuvem ou ambiente local, neste tutorial usaremos a plataforma de nuvem do Google.
visão global
Se formos para Documentação Consul sobre seu método de autorização, obteremos uma rápida visão geral de sua finalidade e caso de uso, bem como alguns detalhes técnicos e uma visão geral da lógica. Eu recomendo fortemente lê-lo pelo menos uma vez antes de prosseguir, pois agora irei explicar e refletir sobre tudo.
Diagrama 1: Visão geral oficial do método de autorização Consul
Claro, há informações úteis lá, mas não há nenhum guia sobre como realmente usar tudo isso. Então, como qualquer pessoa sã, você vasculha a Internet em busca de orientação. E então... Você falha. Acontece. Vamos consertar isso.
Antes de prosseguirmos com a criação de nosso POC, vamos voltar à visão geral dos métodos de autorização do Consul (Diagrama 1) e refiná-los no contexto do Kubernetes.
Arquitetura
Neste tutorial, criaremos um servidor Consul em uma máquina separada que se comunicará com um cluster Kubernetes com o cliente Consul instalado. Em seguida, criaremos nosso aplicativo fictício no pod e usaremos nosso método de autorização configurado para ler nosso armazenamento de chave/valor Consul.
O diagrama abaixo detalha a arquitetura que estamos criando neste tutorial, bem como a lógica por trás do método de autorização, que será explicada posteriormente.
Diagrama 2: Visão geral do método de autorização do Kubernetes
Uma observação rápida: o servidor Consul não precisa residir fora do cluster Kubernetes para que isso funcione. Mas sim, ele pode fazer isso e aquilo.
Então, pegando o diagrama de visão geral do Consul (Diagrama 1) e aplicando o Kubernetes a ele, obtemos o diagrama acima (Diagrama 2), e a lógica aqui é a seguinte:
Cada pod terá uma conta de serviço anexada contendo um token JWT gerado e conhecido pelo Kubernetes. Esse token também é inserido no pod por padrão.
Nosso aplicativo ou serviço dentro do pod inicia um comando de login para nosso cliente Consul. A solicitação de login também incluirá nosso token e nome especialmente criado método de autorização (tipo Kubernetes). Esta etapa 2 corresponde à etapa 1 do diagrama Consul (Esquema 1).
Nosso cliente Consul encaminhará essa solicitação ao nosso servidor Consul.
MAGIA! É aqui que o servidor Consul verifica a autenticidade da solicitação, coleta informações sobre a identidade da solicitação e a compara com quaisquer regras predefinidas associadas. Abaixo está outro diagrama para ilustrar isso. Esta etapa corresponde às etapas 3, 4 e 5 do diagrama de visão geral do Consul (Diagrama 1).
Nosso servidor Consul gera um token Consul com permissões de acordo com nossas regras de método de autorização especificadas (que definimos) em relação à identidade do solicitante. Em seguida, ele enviará esse token de volta. Isso corresponde à etapa 6 do diagrama Consul (Diagrama 1).
Nosso cliente Consul encaminha o token para a aplicação ou serviço solicitante.
Nosso aplicativo ou serviço agora pode usar esse token Consul para se comunicar com nossos dados Consul, conforme determinado pelos privilégios do token.
A magia é revelada!
Para aqueles de vocês que não estão felizes com apenas um coelho tirado da cartola e querem saber como funciona... deixe-me "mostrar o quão profundo toca do Coelho".
Conforme mencionado anteriormente, nossa etapa “mágica” (Figura 2: Etapa 4) é onde o servidor Consul autentica a solicitação, coleta informações sobre a solicitação e a compara com quaisquer regras predefinidas associadas. Esta etapa corresponde às etapas 3, 4 e 5 do diagrama de visão geral do Consul (Diagrama 1). Abaixo está um diagrama (Diagrama 3), cujo objetivo é mostrar claramente o que realmente está acontecendo sob o capô método de autorização específico do Kubernetes.
Diagrama 3: A magia é revelada!
Como ponto de partida, nosso cliente Consul encaminha a solicitação de login para nosso servidor Consul com o token da conta Kubernetes e o nome da instância específica do método de autorização que foi criado anteriormente. Esta etapa corresponde à etapa 3 da explicação do circuito anterior.
Agora o servidor Consul (ou líder) precisa verificar a autenticidade do token recebido. Portanto, ele consultará o cluster Kubernetes (através do cliente Consul) e, com as devidas permissões, descobriremos se o token é genuíno e a quem pertence.
A solicitação validada é então retornada ao líder Consul, e o servidor Consul procura a instância do método de autorização com o nome especificado na solicitação de login (e tipo Kubernetes).
O líder cônsul identifica a instância do método de autorização especificada (se encontrada) e lê o conjunto de regras vinculativas anexadas a ela. Em seguida, ele lê essas regras e as compara com os atributos de identidade verificados.
Surpresa! Vamos passar para a etapa 5 da explicação do circuito anterior.
Execute o Consul-server em uma máquina virtual normal
De agora em diante, darei principalmente instruções sobre como criar este POC, geralmente em marcadores, sem explicações de frases completas. Além disso, conforme observado anteriormente, usarei o GCP para criar toda a infraestrutura, mas você pode criar a mesma infraestrutura em qualquer outro lugar.
Inicie a máquina virtual (instância/servidor).
Crie uma regra para o firewall (grupo de segurança na AWS):
Gosto de atribuir o mesmo nome de máquina à regra e à tag de rede, neste caso "skywiz-consul-server-poc".
Encontre o endereço IP do seu computador local e adicione-o à lista de endereços IP de origem para que possamos acessar a interface do usuário (IU).
Abra a porta 8500 para UI. Clique em Criar. Alteraremos esse firewall novamente em breve [link].
Adicione uma regra de firewall à instância. Volte para o painel da VM no Consul Server e adicione “skywiz-consul-server-poc” ao campo de tags de rede. Clique em Salvar.
Instale o Consul em uma máquina virtual, confira aqui. Lembre-se que você precisa da versão Consul ≥ 1.5 [link]
Vamos criar um único nó Consul - a configuração é a seguinte.
groupadd --system consul
useradd -s /sbin/nologin --system -g consul consul
mkdir -p /var/lib/consul
chown -R consul:consul /var/lib/consul
chmod -R 775 /var/lib/consul
mkdir /etc/consul.d
chown -R consul:consul /etc/consul.d
Para obter um guia mais detalhado sobre como instalar o Consul e configurar um cluster de 3 nós, consulte aqui.
Crie um arquivo /etc/consul.d/agent.json da seguinte forma [link]:
consul agent
-server
-ui
-client 0.0.0.0
-data-dir=/var/lib/consul
-bootstrap-expect=1
-config-dir=/etc/consul.d
Você deverá ver vários resultados e acabar com “... atualização bloqueada por ACLs”.
Encontre o endereço IP externo do servidor Consul e abra um navegador com este endereço IP na porta 8500. Certifique-se de que a IU seja aberta.
Tente adicionar um par chave/valor. Deve haver algum engano. Isso ocorre porque carregamos o servidor Consul com uma ACL e desabilitamos todas as regras.
Volte para o seu shell no servidor Consul e inicie o processo em segundo plano ou de alguma outra forma de executá-lo e digite o seguinte:
consul acl bootstrap
Encontre o valor "SecretID" e retorne à IU. Na guia ACL, insira o ID secreto do token que você acabou de copiar. Copie o SecretID para outro lugar, precisaremos dele mais tarde.
Agora adicione um par chave/valor. Para este POC, adicione o seguinte: key: “custom-ns/test_key”, valor: “Estou na pasta custom-ns!”
Lançando um cluster Kubernetes para nosso aplicativo com o cliente Consul como um Daemonset
Crie um cluster K8s (Kubernetes). Iremos criá-lo na mesma zona do servidor para um acesso mais rápido e para que possamos usar a mesma sub-rede para conectar-se facilmente com endereços IP internos. Chamaremos isso de "skywiz-app-with-consul-client-poc".
Como observação lateral, aqui está um bom tutorial que encontrei ao configurar um cluster POC Consul com Consul Connect.
Também usaremos o gráfico de leme da Hashicorp com um arquivo de valores estendido.
Instale e configure o Helm. Etapas de configuração:
Use o seguinte arquivo de valor (observe que desativei a maioria):
### poc-helm-consul-values.yaml
global:
enabled: false
image: "consul:latest"
# Expose the Consul UI through this LoadBalancer
ui:
enabled: false
# Allow Consul to inject the Connect proxy into Kubernetes containers
connectInject:
enabled: false
# Configure a Consul client on Kubernetes nodes. GRPC listener is required for Connect.
client:
enabled: true
join: ["<PRIVATE_IP_CONSUL_SERVER>"]
extraConfig: |
{
"acl" : {
"enabled": true,
"default_policy": "deny",
"enable_token_persistence": true
}
}
# Minimal Consul configuration. Not suitable for production.
server:
enabled: false
# Sync Kubernetes and Consul services
syncCatalog:
enabled: false
Aplicar gráfico do leme:
./helm install -f poc-helm-consul-values.yaml ./consul-helm - name skywiz-app-with-consul-client-poc
Ao tentar rodar, ele precisará de permissões para o servidor Consul, então vamos adicioná-las.
Observe o “Pod Address Range” localizado no painel do cluster e consulte nossa regra de firewall “skywiz-consul-server-poc”.
Adicione o intervalo de endereços do pod à lista de endereços IP e abra as portas 8301 e 8300.
Vá para a UI do Consul e após alguns minutos você verá nosso cluster aparecer na aba de nós.
Configurando um método de autorização integrando o Consul ao Kubernetes
Retorne ao shell do servidor Consul e exporte o token que você salvou anteriormente:
export CONSUL_HTTP_TOKEN=<SecretID>
Precisaremos de informações do nosso cluster Kubernetes para criar uma instância do método de autenticação:
host kubernetes
kubectl get endpoints | grep kubernetes
conta de serviço kubernetes-jwt
kubectl get sa <helm_deployment_name>-consul-client -o yaml | grep "- name:"
kubectl get secret <secret_name_from_prev_command> -o yaml | grep token:
O token é codificado em base64, então descriptografe-o usando sua ferramenta favorita [link]
kubernetes-ca-cert
kubectl get secret <secret_name_from_prev_command> -o yaml | grep ca.crt:
Pegue o certificado “ca.crt” (após a decodificação base64) e escreva-o no arquivo “ca.crt”.
Agora instancie o método auth, substituindo os espaços reservados pelos valores que você acabou de receber.
consul acl auth-method create
-type "kubernetes"
-name "auth-method-skywiz-consul-poc"
-description "This is an auth method using kubernetes for the cluster skywiz-app-with-consul-client-poc"
-kubernetes-host "<k8s_endpoint_retrieved earlier>"
[email protected]
-kubernetes-service-account-
jwt="<decoded_token_retrieved_earlier>"
Em seguida, precisamos criar uma regra e anexá-la à nova função. Para esta parte você pode usar o Consul UI, mas usaremos a linha de comando.
Em seguida, use o seguinte comando interno para criar um configmap [link]. Observe que nos referimos ao nome do nosso serviço, substitua-o se necessário.
Crie várias outras pastas de chaves com a mesma chave de nível superior (ou seja, /sample_key) e um valor de sua escolha. Crie políticas e funções apropriadas para novos caminhos principais. Faremos as ligações mais tarde.
Teste de namespace personalizado:
Vamos criar nosso próprio namespace:
kubectl create namespace custom-ns
Vamos criar um pod em nosso novo namespace. Escreva a configuração do pod.
Você pode decodificar "Valor" em base64 e ver se ele corresponde ao valor em custom-ns/test_key na interface do usuário. Se você usou o mesmo valor acima neste tutorial, seu valor codificado seria IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.
Teste de conta de serviço do usuário:
Crie uma ServiceAccount personalizada usando o seguinte comando [link].
Permissão negada. Ah, esquecemos de adicionar uma nova vinculação de regras com as permissões apropriadas, vamos fazer isso agora.
Repita as etapas anteriores acima:
a) Crie uma Política idêntica para o prefixo “custom-sa/”.
b) Crie uma função, chame-a de “função personalizada”
c) Anexe a Política à Função.
Crie uma ligação de regra (possível apenas em cli/api). Observe o significado diferente do sinalizador seletor.
consul acl binding-rule create
-method=auth-method-skywiz-consul-poc
-bind-type=role
-bind-name='custom-sa-role'
-selector='serviceaccount.name=="custom-sa"'
Faça login novamente no contêiner "poc-ubuntu-custom-sa". Sucesso!
Você também pode garantir que esse token não conceda acesso ao kv em "custom-ns/". Basta repetir o comando acima após substituir “custom-sa” pelo prefixo “custom-ns”.
Permissão negada.
Exemplo de sobreposição:
Vale a pena notar que todos os mapeamentos de vinculação de regras serão adicionados ao token com esses direitos.
Nosso contêiner "poc-ubuntu-custom-sa" está no namespace padrão - então vamos usá-lo para uma vinculação de regras diferente.
Repita as etapas anteriores:
a) Crie uma Política idêntica para o prefixo de chave “default/”.
b) Crie uma função, nomeie-a como “default-ns-role”
c) Anexe a Política à Função.
Crie uma vinculação de regras (possível apenas em cli/api)
consul acl binding-rule create
-method=auth-method-skywiz-consul-poc
-bind-type=role
-bind-name='default-ns-role'
-selector='serviceaccount.namespace=="default"'
Volte para o nosso contêiner "poc-ubuntu-custom-sa" e tente acessar o caminho kv "default/".
Permissão negada.
Você pode visualizar as credenciais especificadas para cada token na UI em ACL > Tokens. Como você pode ver, nosso token atual possui apenas uma “função personalizada” anexada a ele. O token que estamos usando atualmente foi gerado quando efetuamos login e havia apenas uma vinculação de regra correspondente. Precisamos fazer login novamente e usar o novo token.
Certifique-se de poder ler os caminhos kv "custom-sa/" e "default/".
Sucesso!
Isso ocorre porque nosso “poc-ubuntu-custom-sa” corresponde às ligações de regras “custom-sa” e “default-ns”.
Conclusão
Gerenciamento de token TTL?
No momento em que este artigo foi escrito, não havia uma maneira integrada de determinar o TTL para tokens gerados por esse método de autorização. Seria uma oportunidade fantástica para fornecer automação segura da autorização Consul.
Existe uma opção para criar manualmente um token com TTL: