Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Vault em alta disponibilidade no GKE

By Ami MahloofDec 17, 201916 min read

Esta página também está disponível em English, Deutsch, Español, Français, Italiano e 日本語.

1 fskpg2trcdatechlv lqzw

Gerenciar secrets nativamente no Kubernetes não é seguro. No Kubernetes, secrets são apenas texto em base64 que qualquer pod em execução pode consumir.

Aviso:

Este tutorial foi pensado para você entender cada componente da configuração, passo a passo. Nada impede que você use terraform para montar tudo, mas seguir cegamente uma configuração tão crítica pode gerar problemas difíceis de resolver sem esse entendimento mais profundo.

1 3th420mk8ylbebpjutjckw

Claro, dá para criptografar um secret no Kubernetes, mas esse secret só fica criptografado em repouso. Quando ele é montado dentro do Pod, vira apenas um arquivo ou variável de ambiente que pode ser acessado facilmente de dentro do Pod. Em caso de violação, os dados podem ser comprometidos se alguém tiver acesso ao Pod ou até mesmo ao namespace onde ele está rodando, via kubectl.

O HashiCorp Vault é uma forma segura de gerenciar secrets, além de auditar e revogar o acesso a eles. Uma coisa é instalar e usar o Vault, outra bem diferente é consumir esses secrets em um Pod.

Este post mostra como instalar o Vault no GKE com Terraform e Helm. Para consumir esses secrets, leia também meu outro post sobre como consumir secrets do Vault de forma transparente em um Pod.

Essa abordagem é mais simples de gerenciar se você só precisa do Vault e não precisa dos recursos avançados do Consul, como o Consul template com Vault.

Neste tutorial, vou mostrar como instalar um Vault em alta disponibilidade usando o Google Cloud Storage (GCS) como backend, com TLS de ponta a ponta.

Observação:

Crie a configuração do Vault separada por ambiente, para testar atualizações com mais segurança e isolar os ambientes entre si.

Não recomendo expor o Vault como um serviço. Caso precise acessá-lo, use o comando:

$ kubectl port-forward vault-0 8200:8200

e acesse a UI em https://127.0.0.1:8200, conforme detalhado abaixo.

Se você tiver VMs que precisam acessar esse Vault, use VPC peering, já que serviços e pods usam IPs nativos — esse cenário não está coberto aqui.

Tutorial:

Resumo:

  • Criar certificados TLS para o Vault
  • Criar um Bucket no GCS para o backend de armazenamento do Vault
  • Criar keyring KMS e chave de criptografia para o auto-unseal do Vault.
  • Criar service accounts para o Vault acessar o KMS e o backend de armazenamento GCS.
  • Instalar o Helm chart oficial do HashiCorp Vault via helm tillerless.

Criando certificados TLS para o Vault:

0 y3nb5jrvforb rez

Uma das recomendações de hardening para produção é que a comunicação entre o Vault e os clientes seja criptografada por TLS, tanto no tráfego de entrada quanto no de saída.

Vamos criar um certificado para:

  • O endereço do serviço Vault no Kubernetes.
  • 127.0.0.1

Vamos usar o CloudFlare SSL toolkit ( cfssl e cfssljson) para gerar esses certificados.

A instalação requer uma instalação funcional do Go 1.12+ e um GOPATH configurado corretamente.

Importante!: garanta que o bin do GOPATH está no seu path:

export PATH=$GOPATH/bin:$PATH

Instalando o CloudFlare SSL ToolKit:

go get -u github.com/cloudflare/cfssl/cmd/cfssl
go get -u github.com/cloudflare/cfssl/cmd/cfssljson

Inicializar uma Autoridade Certificadora (CA):

$ mkdir vault-ca && cd vault-ca

Crie os arquivos da CA:

Arquivo de configuração da CA com expiração de 5 anos

$ cat <<EOF > ca-config.json
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"default": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "8760h"
}
}
}
}
EOF

Solicitação de Assinatura da CA:

$ cat <<EOF > ca-csr.json
{
"hosts": [\
"cluster.local"\
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [\
{\
"C": "US",\
"L": "NewYork",\
"O": "Kubernetes",\
"OU": "CA",\
"ST": "NewYork"\
}\
]
}
EOF

Solicitação de Assinatura do Certificado VAULT, a ser assinada pela CA acima: nota: altere o namespace do Vault se não for o namespace default

$ cat <<EOF > vault-csr.json
{
"CN": "Vault-GKE",
"hosts": [\
"127.0.0.1",\
"vault.default.svc.cluster.local"\
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [\
{\
"C": "US",\
"L": "NewYork",\
"O": "Innovia",\
"OU": "Vault",\
"ST": "NewYork"\
}\
]
}
EOF

Você pode, claro, alterar as informações do certificado na seção "names" como preferir.

Execute o comando abaixo para inicializar a CA usando o arquivo que você acabou de editar:

$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
2019/11/12 16:35:01 [INFO] generating a new CA key and certificate from CSR
2019/11/12 16:35:01 [INFO] generate received request
2019/11/12 16:35:01 [INFO] received CSR
2019/11/12 16:35:01 [INFO] generating key: rsa-2048
2019/11/12 16:35:01 [INFO] encoded CSR
2019/11/12 16:35:01 [INFO] signed certificate with serial number 425581644650417483788325060652779897454211028144

Crie uma chave privada e assine o certificado TLS:

$ cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=default \
vault-csr.json | cfssljson -bare vault
2019/11/12 16:36:33 [INFO] generate received request
2019/11/12 16:36:33 [INFO] received CSR
2019/11/12 16:36:33 [INFO] generating key: rsa-2048
2019/11/12 16:36:34 [INFO] encoded CSR
2019/11/12 16:36:34 [INFO] signed certificate with serial number 311973563616303179057952194819087555625015840298

Nesse ponto, você deve ter os seguintes arquivos no diretório de trabalho atual:

ca-key.pem
ca.pem
vault-key.pem
vault.pem

Guarde os arquivos da CA em local seguro: você vai precisar deles para reassinar o certificado quando expirar (a CA vale 5 anos, e o Vault, 1 ano).

Crie um secret para o TLS do Vault e o CA.pem:

kubectl create secret generic vault-tls \
--from-file=ca.pem \
--from-file=vault.pem \
--from-file=vault-key.pem

Defina o Projeto GCP para o restante deste tutorial:

$ export GCP_PROJECT=<your_project_id>

Habilitando as APIs do GCP necessárias para este tutorial:

$ gcloud services enable \
cloudapis.googleapis.com \
cloudkms.googleapis.com \
container.googleapis.com \
containerregistry.googleapis.com \
iam.googleapis.com \
--project ${GCP_PROJECT}
Operation "operations/acf.8e126724-bbde-4c0d-b516-5dca5b8443ee" finished successfully.

Backend de armazenamento do Vault

0 kgo4ymq8e12mvigcGoogle Cloud Storage

Em modo HA, os servidores Vault têm dois estados adicionais: standby e active. Em um cluster Vault, apenas uma instância fica active e atende a todas as requisições (leituras e escritas), e todos os nós em standby redirecionam as requisições para o nó active.

Vamos criar o bucket no GCS com o comando gsutil. Os nomes de bucket precisam ser únicos em todo o Google Cloud, então escolha um nome exclusivo.

$ export GCS_BUCKET_NAME=mycompany-vault-data
$ gsutil mb gs://$GCS_BUCKET_NAME
$ gsutil versioning set on gs://$GCS_BUCKET_NAME

Mesmo com os dados criptografados em trânsito e em repouso, defina permissões adequadas no bucket para limitar a exposição. Vale a pena criar uma service account que restrinja, via permissões IAM, a interação do Vault com o Google Cloud apenas aos objetos do bucket de armazenamento.

Auto unseal do Vault

0 29ts5sy8qvx7cern

Quando o Vault é reiniciado, ele sobe selado e criptografado. Para usá-lo, é preciso fazer o unseal. Existe um recurso novo, o auto unseal, que lê automaticamente as master keys e o root token do CloudKMS.

Criar Keyring KMS e Crypto Key:

Nesta seção, vamos criar o keyring KMS e a chave para criptografar e descriptografar as master keys e o root token do Vault:

Crie o keyring kms vault-helm-unseal-kr:

$ gcloud kms keyrings create vault-helm-unseal-kr \
--location global \
--project ${GCP_PROJECT}

Crie a chave de criptografia:

$ gcloud kms keys create vault-helm-unseal-key \
--location global \
--keyring vault-helm-unseal-kr \
--purpose encryption \
--project ${GCP_PROJECT}

Criar as service accounts do GCP e permissões IAM para o Vault

Configure as variáveis:

$ export VAULT_SA_NAME=vault-server;
export VAULT_SA=$VAULT_SA_NAME@$GCP_PROJECT.iam.gserviceaccount.com

Crie a service account do servidor Vault:

$ gcloud iam service-accounts create $VAULT_SA_NAME \
--display-name "Vault server service account" \
--project ${GCP_PROJECT}

Crie a chave da service account do servidor Vault (arquivo JSON de credenciais):

$ gcloud iam service-accounts keys create \
--iam-account $VAULT_SA /tmp/vault_gcs_key.json
created key [be22cfe6e30f3a3fcfc6ebaa23ca3ba905dd60ab] of type [json] as [/tmp/vault_gcs_key.json] for [[email protected]]
Crie o secret para armazenar a service account do Google do Vault
$ kubectl create secret generic vault-gcs \
--from-file=/tmp/vault_gcs_key.json
secret/vault-gcs created

Conceda acesso ao Bucket GCS de armazenamento do Vault:

$ gsutil iam ch \
serviceAccount:${VAULT_SA}:objectAdmin \
gs://${GCS_BUCKET_NAME}

Conceda acesso à chave kms do Vault:

$ gcloud kms keys add-iam-policy-binding \
vault-helm-unseal-key \
--location global \
--keyring vault-helm-unseal-kr \
--member serviceAccount:${VAULT_SA} \
--role roles/cloudkms.cryptoKeyEncrypterDecrypter \
--project ${GCP_PROJECT}
Updated IAM policy for key [vault-helm-unseal-key].
bindings:
- members:
- serviceAccount:[email protected]
role: roles/cloudkms.cryptoKeyEncrypterDecrypter
etag: BwWZ6sIYovk=
version: 1
Nota:
Se por algum motivo você excluiu a service account e a recriou, é preciso excluir a política IAM na chave; caso contrário, vá direto para Obter o chart oficial do HashiCorp Vault
$ gcloud kms keys get-iam-policy vault-helm-unseal-key --location global --keyring vault-helm-unseal-kr > kms-policy.yaml
edite o arquivo de política, remova os members em binding e salve o arquivo
bindings:
etag: BwWXQz4HjuI=
version: 1

Reaplique a política:

$ gcloud kms keys set-iam-policy vault-helm-unseal-key --location global --keyring vault-helm-unseal-kr kms-policy.yaml

Baixe o chart oficial do Vault da HashiCorp:

1 phvmhmqvoj6awvkgmrnhbg

nota:

A partir da versão 0.3.0, existe uma integração do Kubernetes com o Vault que injeta secrets automaticamente no Pod, renderizando o secret como um arquivo em um volume. Recomendo fortemente usar meu vault secrets webhook, que é uma forma mais segura de injetar um secret em um Pod e ainda automatiza o consumo dos secrets.

export CHART_VERSION=0.3.0

Baixe e descompacte o chart:

$ wget https://github.com/hashicorp/vault-helm/archive/v$CHART_VERSION.tar.gz && tar zxf v$CHART_VERSION.tar.gz && rm v$CHART_VERSION.tar.gz

Configurando o values.yaml do chart:

O gist a seguir tem placeholders para substituição de variáveis.

global:
tlsDisable: false
server:
extraEnvironmentVars:
GOOGLE_APPLICATION_CREDENTIALS: /vault/userconfig/vault-gcs/vault_gcs_key.json
extraVolumes:
- type: secret
name: vault-gcs
path: "/vault/userconfig"
- type: secret
name: vault-tls
path: "/etc/tls"
authDelegator:
enabled: true
ha:
enabled: true
config: |
ui = true
listener "tcp" {
tls_disable = 0
tls_cert_file = "/etc/tls/vault-tls/vault.pem"
tls_key_file = "/etc/tls/vault-tls/vault-key.pem"
tls_client_ca_file = "/etc/tls/vault-tls/ca.pem"
tls_min_version = "tls12"
address = "[::]:8200"
cluster_address = "[::]:8201"
}
storage "gcs" {
bucket = "GCS_BUCKET_NAME"
ha_enabled = "true"
}
seal "gcpckms" {
project = "GCP_PROJECT"
region = "global"
key_ring = "vault-helm-unseal-kr"
crypto_key = "vault-helm-unseal-key"
}

Use o comando abaixo para criar um novo arquivo de values chamado vault-gke-values.yaml:

$ curl -s https://gist.githubusercontent.com/innovia/53c05bf69312706fc93ffe3bb685b223/raw/adc169605984da8ba82082191c8f631579b1b199/vault-gke-values.yaml | sed "s/GCP_PROJECT/$GCP_PROJECT/g" | sed "s/GCS_BUCKET_NAME/$GCS_BUCKET_NAME/g" > vault-helm-$CHART_VERSION/vault-gke-values.yaml

Confira o arquivo gerado para garantir que o projeto e o bucket GCS estão corretos.

$ cat vault-helm-$CHART_VERSION/vault-gke-values.yaml | grep -E 'bucket|project'
bucket = "<COMPANY>-vault-data"
project = "ami-playground"

Usando helm 2.x:

Se você não tiver o tiller instalado no cluster, dá para pular essa configuração instalando o plugin tillerless do helm, que sobe um tiller local na sua máquina e faz o helm apontar para ele. Caso contrário, vá direto para a seção instalar o chart do Vault abaixo.

Instale o plugin tillerless do helm:

Se você ainda não tem o helm, instale com:

$ brew install helm@2

Inicialize apenas o cliente para que o servidor tiller não seja instalado:

helm init --client-only
instale o plugin helm-tillerless
helm plugin install https://github.com/rimusz/helm-tiller
inicie o tiller via helm
$ helm tiller start
Installed Helm version v2.16.1
Copied found /usr/local/bin/tiller to helm-tiller/bin
Helm and Tiller are the same version!
Starting Tiller...
Tiller namespace: kube-system

Usando helm 3:

$ brew install helm

Instale o chart do Vault:

nota: se estiver usando helm 3, a saída não vai listar os recursos.

$ helm upgrade --install vault -f vault-helm-$CHART_VERSION/vault-gke-values.yaml vault-helm-$CHART_VERSION
release "vault" does not exist. Installing it now.
NAME: vault
LAST DEPLOYED: Wed Nov 13 15:41:55 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME AGE
vault-config 0s
==> v1/Service
NAME AGE
vault 0s
==> v1/ServiceAccount
NAME AGE
vault 0s
==> v1/StatefulSet
NAME AGE
vault 0s
==> v1beta1/ClusterRoleBinding
NAME AGE
vault-server-binding 0s
==> v1beta1/PodDisruptionBudget
NAME AGE
vault 0s
NOTES:
Thank you for installing HashiCorp Vault!
Now that you have deployed Vault, you should look over the docs on using
Vault with Kubernetes available here:
https://www.vaultproject.io/docs/
Your release is named vault. To learn more about the release, try:
$ helm status vault
$ helm get vault
O Vault deve subir e ficar em estado não inicializado.

Os warnings a seguir são OK, já que o Vault ainda não foi inicializado:

=> Vault server started! Log data will stream in below:
2019-12-17T19:07:37.937Z [INFO] proxy environment: http_proxy= https_proxy= no_proxy=
2019-12-17T19:07:38.909Z [INFO] core: stored unseal keys supported, attempting fetch
2019-12-17T19:07:39.037Z [WARN] failed to unseal core: error="stored unseal keys are supported, but none were found"
2019-12-17T19:07:44.038Z [INFO] core: stored unseal keys supported, attempting fetch
2019-12-17T19:07:44.080Z [INFO] core: autoseal: seal configuration missing, but cannot check old path as core is sealed: seal_type=recovery
2019-12-17T19:07:44.174Z [WARN] failed to unseal core: error="stored unseal keys are supported, but none were found"
---
kubectl describe pod vault-0
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
...
Warning Unhealthy 3s (x9 over 27s) kubelet, minikube Readiness probe failed: Key Value

Inicializar o Vault com auto unseal do KMS

Abra um port-forward para o Vault com o comando:

$ kubectl port-forward vault-0 8200:8200 > /dev/null & export PID=$!; echo "vault port-forward pid: $PID"

Conecte-se ao Vault usando o certificado CA.pem:

$ export VAULT_ADDR=https://127.0.0.1:8200;
export VAULT_CACERT=$PWD/ca.pem
meu vault ca.pem, por exemplo, está em:
VAULT_CACERT: /Users/ami/vault-gke-medium/ca.pem

Instale o cliente vault (use a mesma versão do servidor):

$ brew install vault

Verifique o status:

$ vault status
Key Value
--- -----
Recovery Seal Type gcpckms
Initialized false
Sealed true
Total Recovery Shares 0
Threshold 0
Unseal Progress 0/0
Unseal Nonce n/a
Version n/a
HA Enabled true

Agora inicialize o Vault:

vault operator init
Recovery Key 1: 33nCanHWgYMR/VPj6bNQdHXJiayL6WeB8Ourx4kHYNaX
Recovery Key 2: IMf7RjptFxtGQUbEWUWehanCBiSY7VhElkM7rRVxczGc
Recovery Key 3: zGuzk/PhNet9OHL4cW2H7d3XypDxfwWXkmajclLPklK4
Recovery Key 4: nCFS0dt0cNGB2LWk0F+3Vmz9TbVNpeIsXbIXDbRarlnT
Recovery Key 5: 9GxXr/6T8OJWJrWqyHQxayR0BAK+WTdbT870AzKEFl2V
Initial Root Token: s.1ukhSgycySjZUJRD0bZjSEit
Success! Vault is initialized
Recovery key initialized with 5 key shares and a key threshold of 3. Please
securely distribute the key shares printed above.

Guarde essas chaves em segurança.

Confiando na autoridade certificadora autoassinada:

Como criamos o ca.pem por conta própria, ele não é confiável por padrão, já que não faz parte do bundle de CAs que vem com o seu computador.

Dá para adicionar a confiança seguindo as instruções abaixo, conforme seu sistema operacional.

Mac OS:

Definir "always trust" para a CA permite abrir a UI do Vault no navegador sem erros:

$ sudo security add-trusted-cert -d -k /Library/Keychains/System.keychain $VAULT_CACERT

Windows 10:

Siga as instruções para adicionar o certificado aos publicadores confiáveis:

https://docs.microsoft.com/en-us/visualstudio/deployment/how-to-add-a-trusted-publisher-to-a-client-computer-for-clickonce-applications?view=vs-2019

Configurando a autenticação do backend do Kubernetes com o Vault

Agora que o Vault está no ar e em alta disponibilidade, podemos seguir em frente e conectá-lo ao Kubernetes.

Vamos usar uma service account para fazer o login inicial do Vault no Kubernetes.

O token dessa service account será configurado dentro do Vault usando o vault CLI.

Essa service account tem uma permissão especial chamada "system:auth-delegator", que permite ao Vault repassar a service account do pod para o Kubernetes para autenticação. Uma vez autenticado, o Vault devolve um token de login para o cliente, que então conversa com o Vault e obtém os secrets de que precisa.

O cliente usa o token de login e faz login no Vault para obter o secret.

O Vault verifica um mapeamento entre uma vault role, service account, namespace e a política para liberar ou negar o acesso.

Vamos criar a service account vault-reviewer para isso.

https://gist.github.com/innovia/5435f2336e4dd0045dbb5842880b3334#file-vault-reviewer-yaml

link para o gist original

Atenção: se você configurou o Vault em outro namespace, atualize este arquivo conforme necessário.

kubectl apply -f vault-reviewer.yaml

Habilite o backend de auth do Kubernetes:

$ vault login
$ vault auth enable kubernetes
Success! Enabled kubernetes auth method at: kubernetes/

Configure o Vault com o token e a ca do vault-reviewer:

nota: se você configurou o Vault em outro namespace, use a flag -n após cada comando kubectl.

$ VAULT_SA_TOKEN_NAME=$(kubectl get sa vault-reviewer -o jsonpath="{.secrets[*]['name']}")
$ SA_JWT_TOKEN=$(kubectl get secret "$VAULT_SA_TOKEN_NAME" -o jsonpath="{.data.token}" | base64 --decode; echo)
$ SA_CA_CRT=$(kubectl get secret "$VAULT_SA_TOKEN_NAME" -o jsonpath="{.data['ca\.crt']}" | base64 --decode; echo)
$ vault write auth/kubernetes/config token_reviewer_jwt="$SA_JWT_TOKEN" kubernetes_host=https://kubernetes.default kubernetes_ca_cert="$SA_CA_CRT"
Success! Data written to: auth/kubernetes/config

Requisitos básicos para um pod acessar um secret:

  • O Pod precisa ter uma service account
  • O secret CA.pem do Vault precisa existir no namespace em que o Pod está rodando
  • É preciso existir uma política com permissão mínima de leitura no secret
path "secret/foo" {
capabilities = ["read"]
}
  • É preciso criar uma vault role no Vault:
vault write auth/kubernetes/role/<role_name> \
bound_service_account_names=<service_account_name> \
bound_service_account_namespaces=<service_account_namespace> \
policies=<policy_name>

Isso conclui a configuração do HashiCorp Vault no GKE. Recomendo fortemente configurar os vault secrets webhooks para consumir secrets do Vault de forma transparente, com base em apenas algumas anotações.

Como configurar a UI do Vault com Identity-Aware Proxy (IAP) via load balancer

1 dxfdyie8ymjqvpgeb6gfaw

O Identity-Aware Proxy é uma forma de autenticar um usuário sem precisar configurar uma VPN ou um Bastion SSH.

Mais informações sobre o IAP

Se quiser configurar um load balancer para o serviço com Identity-Aware Proxy, siga os passos abaixo. Caso contrário, dá para acessar a UI do Vault via kubectl port-forward vault-0 8200.

O processo a seguir não vincula um usuário Google ao Vault de forma alguma — ele serve apenas como autenticação multifator. Existe uma forma de usar JWT para autenticação no Vault, mas isso permite que qualquer usuário do seu domínio escolha uma role, o que é menos seguro…

Observação:

Você ainda precisa do certificado autoassinado para o próprio serviço do Vault. O certificado do load balancer é necessário para habilitar o IAP e o https.

Pré-requisitos:

  • É preciso criar um certificado para o load balancer via Google Managed certificate ou como um secret do Kubernetes.

https://cloud.google.com/load-balancing/docs/ssl-certificates

  • O domínio precisa ser verificado nas ferramentas para webmasters do Google
  • É preciso criar um IP estático global e uma entrada de DNS

(se você estiver usando o serviço externalDNS, isso não é necessário)

$ gcloud compute addresses create vault-ui --global

Você pode criar um certificado usando o YAML a seguir:

https://gist.github.com/innovia/71c219692b003e97bc72feeeb5bc8442

$ kubectl apply -f managed-cert.yaml

Depois de criar, aguarde de 15 a 20 minutos para que o status mude de Provisioning para Active.

Verifique o status do certificado:

$ kubectl describe ManagedCertificate vault-ui-certificate
Name: vault-ui-certificate
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"networking.gke.io/v1beta1","kind":"ManagedCertificate","metadata":{"annotations":{},"name":"vault-ui-certificate","namespac...
API Version: networking.gke.io/v1beta1
Kind: ManagedCertificate
Metadata:
Creation Timestamp: 2020-01-13T23:10:28Z
Generation: 3
Resource Version: 7120865
Self Link: /apis/networking.gke.io/v1beta1/namespaces/default/managedcertificates/vault-ui-certificate
UID: e35e7a1b-3659-11ea-ae90-42010aa80174
Spec:
Domains:
vault.ami-playground.doit-intl.com
Status:
Certificate Name: mcrt-9462e1f4-6dd6-4cf2-8769-9693ba29789e
Certificate Status: Active
Domain Status:
Domain: vault.ami-playground.doit-intl.com
Status: Active
Expire Time: 2020-04-12T15:12:29.000-07:00
Events: <none>

Configurando o IAP para o GKE:

Você pode optar por seguir as instruções completas em vez dos passos resumidos abaixo:

Configure o IAP para o seu domínio na tela de consentimento OAuth e crie as credenciais do cliente.

Depois de criar o cliente, copie o client ID e adicione-o ao campo authorized redirect URIs no seguinte formato:

https://iap.googleapis.com/v1/oauth/clientIds/<CLIENT_ID>:handleRedirect

Crie o secret que será usado pelo backend config:

kubectl create secret generic my-secret --from-literal=client_id=client_id_key \
--from-literal=client_secret=client_secret_key

Crie um backend config para o IAP:

https://gist.github.com/innovia/4485a253f15cd824d0e6d2a19230a603

Habilite a seção no fim dos arquivos vault-gke.yaml e confira se os valores do IP estático global e do DNS do host estão atualizados.

Observação:

Você precisa excluir a instalação do Vault e recriá-la com o helm, já que o ingress do GKE tem problemas para atualizar ingresses existentes.

Resumindo o arquivo de values yaml:

  • habilitamos o serviço da UI do Vault na porta 443 e o expomos via NodePort
  • configuramos o serviço do Vault com o IAP via backend config
  • habilitamos o ingress com um IP estático global e o DNS como host mapeado a ele
  • desabilitamos o HTTP no load balancer
  • configuramos a comunicação entre o load balancer e os pods do Vault para ser apenas https
  • configuramos o managed certificate para o load balancer, para que ele funcione como um listener HTTPS

Após o deploy, ao consultar a página do IAP, você verá os erros e warnings a seguir (talvez veja os dois backend services com ERROR se estiver usando uma rede VPC compartilhada; o teste real é checar a URL da UI do Vault no navegador).

1 yu5axdnsw13bo 4vi sqeg

O primeiro erro é referente ao backend padrão (aquele que serve os 404s); o erro é apenas um indicativo de que o IAP não vai estar ativo em nenhuma página 404, o que é o comportamento esperado.

O outro é só um warning. Se você clicar nele, vai ver algo como:

1 vulcp7of1dwxqb5m7p2zfq

Significa apenas que o GCP detectou que algumas regras de firewall vão contornar o IAP, como redes internas e a comunicação do load balancer com o backend do Vault.

Selecione default/vault na página do IAP e, no painel de informações à esquerda, adicione os membros que precisarão de acesso à vault-ui via load balancer.

Adicione o membro com a permissão "IAP-secured Web App User" para liberar o acesso à UI do Vault.