Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Vault de alta disponibilidad en GKE

By Ami MahloofDec 17, 201916 min read

Esta página también está disponible en English, Deutsch, Français, Italiano, 日本語 y Português.

1 fskpg2trcdatechlv lqzw

Gestionar secretos de forma nativa en Kubernetes no es una opción segura. Los secretos en Kubernetes son solo texto plano codificado en base64 que puede consumirse desde un pod en ejecución.

Aviso:

Este tutorial está pensado para que entiendas cada componente de la configuración paso a paso. Nada te impide usar terraform para montarlo, pero meterte a ciegas con algo tan crítico te puede traer problemas que sin ese conocimiento de fondo cuestan mucho más de resolver.

1 3th420mk8ylbebpjutjckw

Sí, puedes cifrar un secreto en Kubernetes, pero ese secreto solo se cifra en reposo y, al montarse dentro del Pod, queda como un archivo o variable de entorno al que se accede sin problema desde el propio Pod. Por eso, ante una brecha, los datos se pueden ver comprometidos si alguien tiene acceso al Pod o incluso al namespace donde corre vía kubectl.

Hashicorp Vault es una forma segura de gestionar secretos, además de auditar y revocar el acceso a ellos. Una cosa es instalar y usar vault, y otra muy distinta consumir esos secretos desde un Pod.

Este post explica cómo instalar Vault en GKE con Terraform y Helm. Para consumir esos secretos, te recomiendo leer mi otro post sobre cómo consumir secretos de Vault de forma transparente en un Pod.

Este enfoque es algo más sencillo de manejar si solo te interesa Vault y no necesitas las funciones avanzadas de Consul, como C onsul template con Vault.

En este tutorial te voy a mostrar cómo instalar un vault de alta disponibilidad usando Google Storage GCS como backend de Vault, con TLS de extremo a extremo.

Nota:

Conviene crear la configuración de Vault por entorno, así pruebas mejor las actualizaciones y mantienes los entornos aislados entre sí.

No recomiendo exponer el vault como servicio. Si necesitas acceder, puedes hacerlo con el comando:

$ kubectl port-forward vault-0 8200:8200

y entrar a la UI desde https://127.0.0.1:8200, como se detalla más abajo.

Si tienes VMs que necesitan acceder a ese vault, deberías usar VPC peering, ya que los servicios y pods son IPs nativas. Eso no se cubre acá.

Tutorial:

Resumen:

  • Crear certificados TLS para vault
  • Crear un Bucket de GCS como backend de almacenamiento de Vault
  • Crear un keyring de KMS y una clave de cifrado para el auto-unseal de Vault.
  • Crear cuentas de servicio para que Vault acceda a KMS y al backend de almacenamiento GCS.
  • Instalar el chart oficial de Helm de Hashicorp vault con helm tillerless.

Crear certificados TLS para Vault:

0 y3nb5jrvforb rez

Una de las recomendaciones de hardening para producción es que las comunicaciones entre vault y los clientes vayan cifradas con TLS, tanto en el tráfico entrante como en el saliente.

Vamos a crear un certificado que se usará para:

  • La dirección del servicio vault de Kubernetes.
  • 127.0.0.1

Vamos a usar el SSL Toolkit de CloudFlare ( cfssl y cfssljson) para generar estos certificados.

La instalación requiere una instalación funcional de Go 1.12+ y un GOPATH bien configurado.

¡Importante!: asegúrate de que el bin de GOPATH esté en tu path:

export PATH=$GOPATH/bin:$PATH

Instalando el SSL ToolKit de CloudFlare:

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

Inicializar una Autoridad de Certificación (CA):

$ mkdir vault-ca && cd vault-ca

Crea los archivos de la CA:

Archivo de configuración de la CA con vencimiento a 5 años

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

Solicitud de Firma de la 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

Solicitud de Firma del Certificado de VAULT, que firmará la CA anterior: nota: cambia el namespace de vault si no es el 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

Obviamente, puedes ajustar la información del cert en la sección "names" de abajo a tu gusto.

Ejecuta el siguiente comando para inicializar la CA con el archivo que acabas 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

Crea una clave privada y firma el 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

En este punto deberías tener los siguientes archivos en el directorio de trabajo actual:

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

guarda los archivos de la CA en un lugar seguro, los vas a necesitar para volver a firmar el cert cuando expire (la CA dura 5 años, Vault dura 1 año)

Crea un secreto para el TLS de Vault y el CA.pem

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

Define el proyecto de GCP para el resto del tutorial:

$ export GCP_PROJECT=<your_project_id>

Habilitando las APIs de GCP necesarias 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 almacenamiento de Vault

0 kgo4ymq8e12mvigcGoogle Cloud Storage

En modo HA, los servidores de Vault tienen dos estados adicionales: standby y active. Dentro de un cluster de Vault, solo una instancia estará active y atenderá todas las solicitudes (lecturas y escrituras), mientras que los nodos en standby redirigen las solicitudes al nodo active.

Vamos a crear el bucket en gcs con el comando gsutil. Los nombres de bucket deben ser únicos a nivel global en toda Google Cloud, así que elige un nombre único.

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

Aunque los datos están cifrados en tránsito y en reposo, asegúrate de configurar los permisos adecuados en el bucket para limitar la exposición. Quizá te interese crear una cuenta de servicio que limite las interacciones de Vault con Google Cloud a los objetos del bucket de almacenamiento mediante permisos IAM.

Auto unseal de Vault

0 29ts5sy8qvx7cern

cuando se reinicia Vault, arranca sellado y cifrado. Para usarlo hay que abrirlo (unseal). Existe una nueva función llamada auto unseal que lee las master keys y el root token desde CloudKMS automáticamente.

Crear el Keyring de KMS y la Crypto Key:

En esta sección crearemos el keyring de KMS y la clave para cifrar y descifrar las master keys y el root token de vault:

Crea el keyring de kms vault-helm-unseal-kr:

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

Crea la clave de cifrado:

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

Crear las cuentas de servicio de GCP y los permisos IAM para vault

Configura las variables:

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

Crea la cuenta de servicio del servidor vault:

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

Crea la clave de la cuenta de servicio del servidor Vault (archivo JSON de credenciales):

$ 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]]
Crea el secreto para almacenar la cuenta de servicio de google de vault
$ kubectl create secret generic vault-gcs \
--from-file=/tmp/vault_gcs_key.json
secret/vault-gcs created

Otorga acceso al Bucket GCS de almacenamiento de vault:

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

Otorga acceso a la kms key de 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:
Si por algún motivo eliminaste la cuenta de servicio y la volviste a crear, tienes que eliminar la política IAM de la clave; si no, salta a la sección Obtener el chart oficial de Hashicorp para vault
$ gcloud kms keys get-iam-policy vault-helm-unseal-key --location global --keyring vault-helm-unseal-kr > kms-policy.yaml
edita el archivo de política, elimina los members dentro de binding y guarda el archivo
bindings:
etag: BwWXQz4HjuI=
version: 1

vuelve a aplicar la política:

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

Obtener el chart oficial de Hashicorp para Vault:

1 phvmhmqvoj6awvkgmrnhbg

nota:

desde la versión 0.3.0 hay una integración de vault con Kubernetes que inyecta automáticamente los secretos al Pod renderizándolos como un archivo en un volumen. Te recomiendo usar mi vault secrets webhook, porque es una forma más segura de inyectar un secreto al Pod y además automatiza el consumo de los secretos.

export CHART_VERSION=0.3.0

Descarga el chart y descomprímelo:

$ 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 el values.yaml del chart:

El siguiente gist tiene placeholders para sustituir variables

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"
}

usa el comando de abajo para crear un nuevo archivo de values llamado 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

Revisa el archivo generado para confirmar que el proyecto y el bucket de GCS son los correctos.

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

usando helm 2.x:

Si no tienes tiller instalado en el cluster, puedes saltarte la configuración de tiller instalando un plugin tillerless para helm, que levanta un tiller local en tu computadora y le indica a helm que lo use. Si no, salta a la sección de instalar el chart de vault más abajo.

Instalar el plugin tillerless de helm:

si aún no tienes helm, instálalo con

$ brew install helm@2

Inicializa solo el cliente para que no se instale el servidor tiller

helm init --client-only
instala el plugin helm-tillerless
helm plugin install https://github.com/rimusz/helm-tiller
arranca tiller con 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

Instalar el chart de Vault:

nota: si usas helm 3, la salida no listará los 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
Vault debería arrancar y quedar en estado no inicializado.

Las siguientes advertencias son normales, ya que vault aún no está 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 vault con auto unseal de KMS

abre un port-forward a Vault con el comando:

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

Conéctate a Vault usando el cert CA.pem

$ export VAULT_ADDR=https://127.0.0.1:8200;
export VAULT_CACERT=$PWD/ca.pem
my vault ca.pem for example is at:
VAULT_CACERT: /Users/ami/vault-gke-medium/ca.pem

Instala el cliente de vault (asegúrate de que sea de la misma versión que el servidor)

$ brew install vault

Verifica el estado:

$ 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

ahora inicializa 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.

Guarda estas claves en un lugar seguro.

Confiar en la autoridad de certificación autofirmada:

Como creamos el ca.pem nosotros mismos, no será de confianza, ya que no forma parte del bundle de CAs que viene con tu computadora.

podemos marcarla como confiable siguiendo las instrucciones de abajo según tu sistema operativo.

Mac OS:

Marcar "always trust" para la CA te permitirá abrir la UI de Vault en el navegador sin errores:

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

Windows 10:

Sigue las instrucciones de aquí para añadir el cert a los publishers de confianza:

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

Configurar la autenticación del backend de Kubernetes con Vault

Ahora que Vault está activo y en alta disponibilidad, podemos seguir y conectar Vault con Kubernetes.

Vamos a usar una cuenta de servicio para hacer el login inicial de Vault con Kubernetes.

Este token de cuenta de servicio se configura dentro del vault con la CLI de vault.

Esta cuenta de servicio tiene un permiso especial llamado "system:auth-delegator" que le permite a vault pasar la cuenta de servicio del pod a Kubernetes para autenticarla. Una vez autenticada, vault devuelve un token de login al cliente, que hablará con Vault para obtener los secretos que necesite.

El cliente usará el token de login para iniciar sesión en Vault y obtener el secreto.

Vault verificará un mapeo entre un rol de vault, la cuenta de servicio, el namespace y la política para permitir o denegar el acceso.

creemos la cuenta de servicio para vault-reviewer

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

enlace al gist original

Toma en cuenta que, si configuraste Vault en cualquier otro namespace, debes actualizar este archivo en consecuencia.

kubectl apply -f vault-reviewer.yaml

habilita el backend de auth de Kubernetes:

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

Configura Vault con el token y la ca de vault-reviewer:

nota: si configuraste vault en cualquier otro namespace, agrega el flag -n después de 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 que un pod acceda a un secreto:

  • el Pod debe tener una cuenta de servicio
  • el secreto Vault CA.pem debe existir en el namespace donde corre el Pod
  • debe existir una política con permiso mínimo de lectura sobre el secreto
path "secret/foo" {
capabilities = ["read"]
}
  • se debe crear un rol de Vault en 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>

Con esto concluye la configuración de Hashicorp vault en GKE. Te recomiendo configurar los vault secrets webhooks para consumir secretos de Vault sin fricción, basándote solo en unas pocas anotaciones.

Cómo configurar la UI de Vault con Identity-Aware Proxy (IAP) mediante un load-balancer

1 dxfdyie8ymjqvpgeb6gfaw

Identity-aware proxy es una forma de autenticar a un usuario sin necesidad de configurar una VPN o un Bastion SSH.

Más información sobre IAP

Si quieres configurar un load balancer para el servicio con identity-aware proxy, puedes hacerlo siguiendo los pasos de abajo. Si no, puedes acceder a la UI de vault con kubectl port-forward vault-0 8200

El siguiente proceso no vincula a un usuario de google con Vault de ninguna forma; sirve solo como autenticación multi-factor. Existe una forma de usar JWT para autenticarse en vault, pero eso permite que cualquier usuario de tu dominio elija un rol, lo que es menos seguro…

Nota:

Sigues necesitando el certificado autofirmado para el propio servicio de Vault. El certificado del load balancer es necesario para habilitar IAP y https.

Requisitos previos:

  • Se debe crear un certificado para el load balancer mediante un Google Managed certificate, o crearlo como un secreto de Kubernetes.

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

  • El dominio debe estar verificado mediante las webmaster tools de Google
  • Se debe crear una IP estática global y una entrada de DNS

(si usas el servicio externalDNS, no lo necesitas)

$ gcloud compute addresses create vault-ui --global

Puedes crear un certificado con el siguiente YAML

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

$ kubectl apply -f managed-cert.yaml

Una vez creado, dale 15-20 minutos para que el estado pase de Provisioning a Active

Verifica el estado del cert:

$ 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 IAP para GKE:

Puedes optar por seguir las instrucciones completas en lugar de los pasos resumidos abajo:

Configura el IAP para tu dominio mediante la pantalla de consentimiento de Oauth y crea las credenciales del cliente.

Una vez creado el cliente, copia el client ID y agrégalo al campo authorized redirect URIs en el siguiente formato:

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

Crea el secreto que usará el backend config:

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

Crea un backend config para el IAP:

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

habilita la sección al final del archivo vault-gke.yaml y asegúrate de que los valores de la IP estática global y del DNS para el host estén actualizados

Nota:

tienes que eliminar la instalación de vault y volver a crearla con helm, ya que el ingress de GKE tiene problemas para actualizar ingresses existentes.

resumen del archivo values.yaml:

  • habilitamos el servicio de UI de vault en el puerto 443 y lo exponemos por un NodePort
  • configuramos el servicio de vault con el IAP mediante un backend config
  • habilitamos el ingress con una IP estática global y el DNS como host mapeado a ella
  • deshabilitamos HTTP en el load balancer
  • configuramos la comunicación entre el load balancer y los pods de vault para que sea solo https
  • configuramos el certificado gestionado para el load balancer, de modo que el load balancer sea un listener HTTPS

Una vez desplegado, si revisas la página de IAP verás los siguientes errores y advertencias (puede que veas ambos backend services con un ERROR si usas una red VPC compartida; la verdadera prueba es revisar la URL de la UI de vault en el navegador)

1 yu5axdnsw13bo 4vi sqeg

El primer error corresponde al backend por defecto (el que sirve los 404); el error solo indica que IAP no estará activo para ninguna página 404, que es el comportamiento esperado.

El otro es solo una advertencia. Si haces clic en ella, verás algo así:

1 vulcp7of1dwxqb5m7p2zfq

Lo único que significa es que GCP detectó que algunas reglas de firewall se saltarán el IAP, como las redes internas y la comunicación del load balancer con el backend de vault.

selecciona default/vault en la página de IAP y, desde el panel de información de la izquierda, agrega los miembros que necesiten acceso a la vault-ui mediante el load balancer

agrega al miembro con el permiso "IAP-secured Web App User" para que ese usuario pueda acceder a la ui de vault.