Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Vault en haute disponibilité sur GKE

By Ami MahloofDec 17, 201916 min read

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

1 fskpg2trcdatechlv lqzw

Gérer les secrets nativement dans Kubernetes n'est pas une option sécurisée. Les secrets Kubernetes ne sont que du texte encodé en base64, exploitable depuis un pod en cours d'exécution.

Avertissement :

Ce tutoriel a pour but de vous faire comprendre chaque composant de la configuration, étape par étape. Rien ne vous empêche d'utiliser terraform pour mettre en place cette configuration, mais se lancer aveuglément dans un déploiement aussi critique entraînera des problèmes difficiles à résoudre sans cette compréhension approfondie.

1 3th420mk8ylbebpjutjckw

Vous pouvez bien sûr chiffrer un secret dans Kubernetes, mais ce secret n'est chiffré qu'au repos. Une fois monté dans le Pod, il devient un simple fichier ou une variable d'environnement facilement accessible depuis le Pod. En cas de brèche, les données peuvent donc être compromises si quelqu'un accède au Pod, ou même au namespace dans lequel il s'exécute via kubectl.

Hashicorp Vault constitue une manière sécurisée de gérer les secrets, mais aussi d'auditer et de révoquer leur accès. Installer et utiliser Vault est une chose ; exploiter ces secrets depuis un Pod en est une autre.

Cet article porte sur l'installation de Vault sur GKE avec Terraform et Helm. Pour la consommation de ces secrets, vous pouvez consulter mon autre article sur la consommation transparente des secrets Vault depuis un Pod.

Cette approche est un peu plus simple à gérer si vous cherchez uniquement à utiliser Vault et n'avez pas besoin des fonctionnalités avancées de Consul telles que Consul template avec Vault.

Dans ce tutoriel, je vais expliquer comment installer un Vault en haute disponibilité en utilisant Google Storage GCS comme backend Vault, avec TLS de bout en bout.

Note :

Mieux vaut créer une configuration Vault par environnement, afin de mieux tester les mises à niveau et de cloisonner les environnements.

Je ne recommande pas d'exposer Vault en tant que service. Si vous devez y accéder, utilisez plutôt la commande :

$ kubectl port-forward vault-0 8200:8200

puis accédez à l'interface via https://127.0.0.1:8200 comme détaillé ci-dessous.

Si des VM doivent accéder à ce Vault, utilisez le peering VPC, puisque les services et les pods utilisent des IP natives — ce point n'est pas couvert ici.

Tutoriel :

Plan :

  • Créer les certificats TLS pour Vault
  • Créer un bucket GCS pour le backend de stockage Vault
  • Créer un keyring KMS et une clé de chiffrement pour l'auto-unseal de Vault.
  • Créer les comptes de service permettant à Vault d'accéder à KMS et au backend de stockage GCS.
  • Installer le Helm chart officiel Hashicorp Vault via helm tillerless.

Création des certificats TLS pour Vault :

0 y3nb5jrvforb rez

L'une des recommandations de durcissement pour la production est que les communications entre Vault et les clients soient chiffrées par TLS, aussi bien en entrée qu'en sortie.

Nous allons créer un certificat qui servira pour :

  • L'adresse du service Vault dans Kubernetes.
  • 127.0.0.1

Nous utiliserons le SSL toolkit de CloudFlare ( cfssl et cfssljson) pour générer ces certificats.

L'installation requiert une installation fonctionnelle de Go 1.12+ et un GOPATH correctement défini.

Important ! Assurez-vous que le bin de GOPATH se trouve dans votre PATH :

export PATH=$GOPATH/bin:$PATH

Installation du SSL ToolKit de CloudFlare :

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

Initialisation d'une autorité de certification (CA) :

$ mkdir vault-ca && cd vault-ca

Créez les fichiers CA :

Fichier de configuration CA avec une expiration de 5 ans

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

Demande de signature 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

Demande de signature de certificat VAULT à signer par la CA ci-dessus : note : changez le namespace pour Vault s'il ne s'agit pas du 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

Vous pouvez bien évidemment adapter les informations du certificat dans la section names selon vos besoins.

Exécutez la commande suivante pour initialiser la CA à partir du fichier que vous venez d'éditer :

$ 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

Créez une clé privée et signez le certificat 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

À ce stade, vous devriez avoir les fichiers suivants dans votre répertoire de travail :

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

Conservez les fichiers CA en lieu sûr : vous en aurez besoin pour re-signer le certificat à son expiration (la CA est valide 5 ans, Vault 1 an).

Créez un secret pour le TLS Vault et le CA.pem :

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

Définissez le projet GCP pour la suite de ce tutoriel :

$ export GCP_PROJECT=<your_project_id>

Activation des API GCP requises pour ce tutoriel :

$ 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 stockage Vault

0 kgo4ymq8e12mvigcGoogle Cloud Storage

En mode HA, les serveurs Vault disposent de deux états supplémentaires : standby et active. Au sein d'un cluster Vault, une seule instance est active et traite l'ensemble des requêtes (lectures et écritures) ; les nœuds standby redirigent les requêtes vers le nœud active.

Créons le bucket sur GCS via la commande gsutil. Les noms de bucket doivent être uniques à l'échelle de Google Cloud, choisissez donc un nom unique :

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

Même si les données sont chiffrées en transit et au repos, veillez à définir des permissions adéquates sur le bucket pour limiter l'exposition. Vous pouvez créer un compte de service qui restreint, via les permissions IAM, les interactions de Vault avec Google Cloud aux seuls objets du bucket de stockage.

Auto-unseal de Vault

0 29ts5sy8qvx7cern

Lorsque Vault redémarre, il démarre dans un état scellé et chiffré. Pour pouvoir l'utiliser, vous devez le déverrouiller. Une nouvelle fonctionnalité, l'auto-unseal, permet de récupérer automatiquement les clés maîtres et le token root depuis CloudKMS.

Création du keyring KMS et de la clé cryptographique :

Dans cette section, nous allons créer le keyring KMS et la clé qui serviront à chiffrer et déchiffrer les clés maîtres Vault et le token root :

Créez le keyring KMS vault-helm-unseal-kr :

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

Créez la clé de chiffrement :

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

Création des comptes de service GCP et des permissions IAM pour Vault

Définition des variables :

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

Créez le compte de service du serveur Vault :

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

Créez la clé du compte de service du serveur Vault (fichier JSON d'identifiants) :

$ 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]]
Créez le secret pour stocker le compte de service Google de Vault
$ kubectl create secret generic vault-gcs \
--from-file=/tmp/vault_gcs_key.json
secret/vault-gcs created

Accordez l'accès au bucket GCS de stockage Vault :

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

Accordez l'accès à la clé KMS 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
Note :
Si pour une raison ou une autre vous avez supprimé puis recréé le compte de service, vous devez supprimer la stratégie IAM sur la clé. Sinon, passez directement à l'étape de récupération du chart officiel Hashicorp Vault.
$ gcloud kms keys get-iam-policy vault-helm-unseal-key --location global --keyring vault-helm-unseal-kr > kms-policy.yaml
éditez le fichier de stratégie, supprimez les membres sous binding, puis sauvegardez le fichier
bindings:
etag: BwWXQz4HjuI=
version: 1

Réappliquez la stratégie :

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

Récupération du chart officiel Hashicorp Vault :

1 phvmhmqvoj6awvkgmrnhbg

note :

À partir de la version 0.3.0, il existe une intégration Vault pour Kubernetes qui injecte automatiquement les secrets dans le Pod en les exposant sous forme de fichier sur un volume. Je recommande vivement d'utiliser mon vault secrets webhook, qui constitue une manière plus sécurisée d'injecter un secret dans un Pod tout en automatisant la consommation des secrets.

export CHART_VERSION=0.3.0

Téléchargez le chart et décompressez-le :

$ 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

Configuration du fichier values.yaml du chart :

Le gist suivant contient des espaces réservés pour la substitution de 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"
}

Utilisez la commande ci-dessous pour créer un nouveau fichier de values nommé 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

Inspectez le fichier généré pour vérifier que le projet et le bucket GCS sont corrects :

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

Avec helm 2.x :

Si tiller n'est pas installé sur le cluster, vous pouvez vous passer de sa configuration en installant un plugin tillerless pour helm, qui démarre un tiller local sur votre machine et y oriente helm. Sinon, passez directement à la section d'installation du chart Vault ci-dessous.

Installation du plugin tillerless helm :

Si vous n'avez pas helm, installez-le via :

$ brew install helm@2

Initialisez uniquement le client afin de ne pas installer le serveur tiller :

helm init --client-only
installer le plugin helm-tillerless
helm plugin install https://github.com/rimusz/helm-tiller
démarrer 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

Avec helm 3

$ brew install helm

Installation du chart Vault :

note : avec helm 3, la sortie ne listera pas les ressources.

$ 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 devrait démarrer et se trouver dans un état non initialisé.

Les avertissements suivants sont normaux tant que Vault n'est pas initialisé :

=> 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

Initialiser Vault avec l'auto-unseal KMS

Ouvrez un port-forward vers Vault avec la commande :

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

Connectez-vous à Vault avec le certificat CA.pem :

$ export VAULT_ADDR=https://127.0.0.1:8200;
export VAULT_CACERT=$PWD/ca.pem
mon ca.pem Vault par exemple se trouve à :
VAULT_CACERT: /Users/ami/vault-gke-medium/ca.pem

Installez le client Vault (assurez-vous qu'il soit dans la même version que le serveur) :

$ brew install vault

Vérifiez le statut :

$ 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

Initialisez maintenant 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.

Conservez ces clés en lieu sûr.

Faire confiance à l'autorité de certification auto-signée :

Comme nous avons généré le ca.pem nous-mêmes, il ne sera pas approuvé puisqu'il ne fait pas partie du bundle CA livré avec votre ordinateur.

On peut l'ajouter aux autorités de confiance en suivant les instructions correspondant à votre système d'exploitation.

Mac OS :

Définir always trust pour la CA vous permettra d'ouvrir l'interface Vault dans le navigateur sans erreur :

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

Windows 10 :

Suivez les instructions ci-dessous pour ajouter le certificat aux éditeurs approuvés :

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

Configuration de l'authentification backend Kubernetes avec Vault

Maintenant que Vault est opérationnel et hautement disponible, nous pouvons le connecter à Kubernetes.

Nous utiliserons un compte de service pour effectuer la connexion initiale de Vault à Kubernetes.

Le token de ce compte de service sera configuré dans Vault à l'aide de la CLI Vault.

Ce compte de service dispose d'une permission spéciale appelée system:auth-delegator qui permettra à Vault de transmettre le compte de service du pod à Kubernetes pour authentification. Une fois authentifié, Vault renvoie un token de connexion Vault au client, qui dialoguera ensuite avec Vault pour obtenir les secrets dont il a besoin.

Le client utilisera ce token pour se connecter à Vault et récupérer le secret.

Vault vérifiera la correspondance entre un rôle Vault, un compte de service, un namespace et la stratégie autorisant ou refusant l'accès.

Créons le compte de service vault-reviewer dédié à cela :

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

lien vers le gist d'origine

À noter : si vous avez configuré Vault dans un autre namespace, mettez ce fichier à jour en conséquence.

kubectl apply -f vault-reviewer.yaml

Activez le backend d'authentification Kubernetes :

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

Configurez Vault avec le token et la CA de vault-reviewer :

note : si vous avez configuré Vault dans un autre namespace, ajoutez le flag -n après chaque commande 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

Prérequis de base pour qu'un pod puisse accéder à un secret :

  • le Pod doit avoir un compte de service
  • le secret CA.pem de Vault doit exister dans le namespace où s'exécute le Pod
  • une stratégie permettant au minimum la lecture du secret doit exister
path "secret/foo" {
capabilities = ["read"]
}
  • un rôle Vault doit être créé dans 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>

Voilà qui conclut la configuration de Hashicorp Vault sur GKE. Je recommande vivement de mettre en place les vault secrets webhooks pour exploiter les secrets Vault de manière transparente, à partir de quelques annotations seulement.

Configurer l'interface Vault avec Identity-Aware Proxy (IAP) via un load-balancer

1 dxfdyie8ymjqvpgeb6gfaw

Identity-aware proxy permet d'authentifier un utilisateur sans avoir à mettre en place un VPN ou un bastion SSH.

Plus d'informations sur IAP

Si vous souhaitez configurer un load balancer pour le service avec identity-aware proxy, suivez les étapes ci-dessous. Sinon, vous pouvez accéder à l'interface Vault via kubectl port-forward vault-0 8200.

Le processus suivant ne lie en aucune manière un utilisateur Google à Vault — il sert uniquement d'authentification multifacteur. Il existe une manière d'utiliser JWT pour l'authentification Vault, mais cela permet à n'importe quel utilisateur de votre domaine de choisir un rôle, ce qui est moins sécurisé…

Note :

Vous avez toujours besoin du certificat auto-signé pour le service Vault lui-même ; le certificat du load balancer est requis pour activer IAP et HTTPS.

Prérequis :

  • Un certificat pour le load balancer doit être créé via Google Managed certificate, ou en tant que secret Kubernetes.

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

  • Le domaine doit être vérifié via les outils webmaster Google
  • Une IP statique globale doit être créée et une entrée DNS doit être ajoutée

(si vous utilisez le service externalDNS, ce n'est pas nécessaire)

$ gcloud compute addresses create vault-ui --global

Vous pouvez créer un certificat avec le YAML suivant :

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

$ kubectl apply -f managed-cert.yaml

Une fois créé, comptez 15 à 20 minutes pour que le statut passe de Provisioning à Active.

Vérifiez le statut du certificat :

$ 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>

Configurer IAP pour GKE :

Vous pouvez choisir de suivre les instructions complètes plutôt que les étapes résumées ci-dessous :

Configurez l'IAP pour votre domaine via l'écran de consentement OAuth et créez les identifiants client.

Une fois le client créé, copiez l'ID client et ajoutez-le au champ authorized redirect URIs au format suivant :

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

Créez le secret qui sera utilisé par la backend config :

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

Créez une backend config pour l'IAP :

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

Activez la section au bas des fichiers vault-gke.yaml et vérifiez que les valeurs de l'IP statique globale ainsi que du DNS de l'hôte sont à jour.

Note :

Vous devez supprimer l'installation de Vault et la recréer avec helm, car l'ingress GKE rencontre des problèmes pour mettre à jour les ingresses existantes.

Pour résumer le fichier values.yaml :

  • nous activons le service de l'interface Vault sur le port 443 et l'exposons via un NodePort
  • nous configurons le service Vault avec l'IAP via une backend config
  • nous activons l'ingress avec une IP statique globale et le DNS comme hôte qui lui est associé
  • nous désactivons HTTP sur le load balancer
  • nous configurons la communication entre le load balancer et les pods Vault pour qu'elle se fasse uniquement en HTTPS
  • nous configurons le certificat managé pour le load balancer afin qu'il fasse office de listener HTTPS

Une fois déployé, si vous consultez la page IAP, vous verrez les erreurs et avertissements suivants (les deux backend services peuvent apparaître en ERREUR si vous utilisez un réseau VPC partagé. Le vrai test consiste à vérifier l'URL de l'interface Vault dans le navigateur)

1 yu5axdnsw13bo 4vi sqeg

La première erreur concerne le backend par défaut (celui qui sert les 404). Elle indique simplement qu'IAP ne sera pas actif sur les pages 404, ce qui est le comportement attendu.

L'autre n'est qu'un avertissement. En cliquant dessus, vous verrez quelque chose comme ceci :

1 vulcp7of1dwxqb5m7p2zfq

Cela signifie simplement que GCP a détecté que certaines règles de pare-feu contournent l'IAP, comme les réseaux internes ou la communication entre le load balancer et le backend Vault.

Sélectionnez default/vault sur la page IAP, puis depuis le panneau d'information à gauche, ajoutez les membres qui auront besoin d'accéder à vault-ui via le load balancer.

Ajoutez le membre avec la permission IAP-secured Web App User pour autoriser cet utilisateur à accéder à l'interface Vault.