Accueil > Le chiffrement dans Azure Kubernetes Service (AKS)
David Frappart
6 juin 2023

Le chiffrement dans Azure Kubernetes Service (AKS)

Le chiffrement dans Azure Kubernetes Service (AKS)

Azure Kubernetes Service (AKS) est un service managé permettant de gérer et déployer facilement des applications basées sur des conteneurs.

Dans cet article, nous vous proposons une plongée dans les options de chiffrements disponibles pour Azure Kubernetes Service.

Au programme :

  • Un rappel des options de chiffrements at rest sur Azure
  • Gérer le chiffrement du control plane AKS
  • Gérer le chiffrement du worker plane AKS
  • Conclusion

 

Revue des options de chiffrements sur la plateforme Azure

 

Avant de plonger dans les spécificités du chiffrement d’AKS, commençons par une revue du chiffrement qu’il est possible d’implémenter dans Azure.

La première option considérée lorsque l’on évoque le chiffrement est, comme expliqué dans la documentation Azure, le chiffrement au repos.

Cette méthode de chiffrement est utilisée pour la protection de la donnée stockée. De fait, dans Azure, le chiffrement au repos consiste à chiffrer la couche de stockage de la plateforme, à savoir Azure Storage.

Les solutions PaaS ou les disques managés Azure s’appuient tous sur la technologie Azure Storage. On trouve dans la documentation des références à Server Side Encryption, ou SSE, pour cette couche de stockage.

Le comportement par défaut consiste en un chiffrement géré par la plateforme Azure. La clé de chiffrement est gérée de bout en bout, rotation incluse, par le Cloud provider.

Pour les scénarios qui requièrent davantage de contrôle, il est possible d’implémenter des scénarios dits Bring Your Own Key (BYOK) avec des Customer Managed Keys (CMK). Dans ce cas, on utilise notre propre clé pour les opérations de chiffrement / déchiffrement.

Toutefois, la clé doit être stockée dans Azure dans le service de coffre-fort de la plateforme, c’est-à-dire une instance de Key Vault.

Dans certains cas, on pourra également envisager un Cloud HSM, managé ou dédié, avec un niveau de compliance plus élevé d’un point de vue règlementation, et également un coût plus élevé et potentiellement une moins bonne intégration à la plateforme Azure au-delà des services purement IaaS.

un Cloud HSM, managé ou dédié, avec un niveau de compliance plus élevé d’un point de vue règlementation

 

On notera qu’à l’heure actuelle, il n’est pas possible de chiffrer avec une clé située en dehors d’Azure ce qu’on appelle couramment un scénario de Hold Your Own Key (HYOK).

Si l’on regarde le stockage des machines, le scénario BYOK requiert un objet supplémentaire pour le chiffrement des Azure Managed Disks. En effet, par son aspect managé, le Managed Disk ne nous donne plus accès à la couche de stockage directement (pour le meilleur, en fait, car on se souvient des difficultés à gérer les VHD dans des comptes de stockage Azure il y a quelques années…).

l’objet Disk Encryption Set

 

La réponse technique à cette abstraction est donc l’objet Disk Encryption Set, qui agit comme un intermédiaire entre le disque managé et l’instance de Key Vault qui stocke la clé de chiffrement.

À noter : il existe, toujours pour les disques managés, une autre technologie de chiffrement appelée Azure Disk Encryption (ADE) qui s’appuie, pour les machines Windows et Linux, respectivement sur BitLocker et dm-crypt. Bien que cette technologie permette également des scénarios BYOK, cela peut sembler un peu redondant avec le scénario BYOK SSE. Il est de ce fait assez intéressant de voir qu’Azure Defender indique dans ses recommandations de sécurité de mettre en œuvre ADE, même avec SSE configuré par défaut.

Une possible explication peut être le fait que SSE ne fournit pas un chiffrement “End-to-End” entre l’hôte de virtualisation et la couche de stockage. Sur ce point, on voit à présent le développement de scénario de chiffrement de l’hôte. Ce principe de chiffrement, comme son nom le suggère, chiffre la donnée entre la couche de compute et la couche de stockage. Il n’est cependant pas toujours possible de mettre en œuvre ce chiffrement de l’hôte avec une CMK.

Après cette introduction sur le chiffrement dans Azure, intéressons-nous à présent au chiffrement spécifiquement pour AKS.

 

Gérer le chiffrement d’AKS –Control plane

 

Concepts de chiffrement du control plane dans AKS

 

Commençons par le chiffrement du control plane de Kubernetes. Comme on le voit sur le schéma ci-dessous, l’architecture de Kubernetes (et donc d’AKS) est constituée d’un control plane et d’un worker plane :

control plmane managé par la plateforme Azure

 

D’un point de vue AKS, le control plane est largement managé par la plateforme Azure, comme la plupart des solutions PaaS, tandis que le worker plane est plus proche du IaaS, mais géré globalement par le control plane AKS.

Tenant compte de ce fait, les options de chiffrements pour le control plane sont limitées par cet accès restreint à la plateforme, caractéristique des solutions PaaS.

Prenons toutefois quelques instants pour regarder les composants du control plane :

Les composants du control plane

 

On peut noter que seul ETCD accède à du stockage Azure en raison de sa nature stateful. D’un point de vue chiffrement au repos, il s’agit donc du seul composant qui nous intéresse.

Si l’on se réfère à la documentation Azure sur ce sujet, nous pouvons trouver une section à propos du chiffrement de ETCD, notamment pour les Kubernetes Secrets. Le concept de Key Management Service pour ETCD n’est pas propre à AKS mais bien un sujet global Kubernetes, puisque l’on trouve également une section dédiée dans la documentation.

Le concept est de fournir un moyen de chiffrement externe pour les secrets dans Kubernetes.

Sans grande surprise, comme pour la plupart des solutions de chiffrements dans Azure, on s’appuie sur une instance de Key Vault pour permettre le chiffrement et le déchiffrement des secrets dans l’instance managée de ETCD.

Cluster AKS

 

Prenons un peu de temps pour comprendre de quoi nous parlons ici. Un cluster AKS a besoin d’accéder au coffre-fort hébergeant la Key Encryption Key (KEK). Pour cela, on s’appuie sur une identité managée qui aura l’autorisation d’accéder à notre coffre-fort, c’est-à-dire une instance de Key Vault.

D’un point de vue control plane AKS (souvenez-vous, nous parlons d’ETCD, donc il s’agit bien du control plane), il est possible d’avoir soit une identité managée de type System Assigned (SAI), ou une identité de type User Assigned (UAI).

Dans le premier cas, l’identité est disponible après le provisioning du cluster, et il est nécessaire d’assigner le bon niveau d’autorisation à cette identité. Dans le second cas, il est requis de créer d’abord une identité, et de la spécifier au moment du provisioning, ainsi que de lui attribuer les autorisations appropriées.

Dans la mesure où la SAI n’est connue qu’à la fin de l’étape de provisioning, il n’est pas possible de lui donner les droits requis sur l’instance de Key Vault cible pour la partie kms ETCD. On utilise donc une identité de type User Assigned sur le control plane dans ce cas. D’un point de vue séparation des rôles, cela a plutôt du sens.

Si l’on peut imaginer une configuration en deux temps (cluster provisioning puis kms configuration), cela parait loin d’être idéal, et c’est très probablement pour cela que l’on voit uniquement le scénario avec une UAI (User Assigned Identity) dans la documentation.

À présent, observons comment configurer cette fonctionnalité.

 

Configuration de KMS etcd dans AKS

 

Le plus simple pour la configuration de cette fonctionnalité est l’usage de la ligne de commande az cli en utilisant les paramètres « –enable-azure-keyvault-km » et « –azure-keyvault-kms-key-id » qui sont assez explicites. On notera également le paramètre « –azure-keyvault-kms-key-vault-network-access » qui peut être utilisé pour spécifier si l’instance de Key Vault est exposée publiquement ou à travers un Private Endpoint.

En fonction du modèle d’autorisation utilisé sur l’instance de Key Vault, l’UAI utilisée doit être associée à une Acces Policy avec les opérations « decrypt » et « encrypt » pour les clés, ou au rôle « Key Vault Crypto User ».

À la création du cluster, on aura une commande comme ci-après :

az aks create --name myAKSCluster --resource-group MyResourceGroup --assign-identity $IDENTITY_RESOURCE_ID --enable-azure-keyvault-kms --azure-keyvault-kms-key-vault-network-access "Public" --azure-keyvault-kms-key-id $KEY_ID

 

 

Pour un cluster existant, on aura la commande suivante :

az aks update --name myAKSCluster --resource-group MyResourceGroup --enable-azure-keyvault-kms --azure-keyvault-kms-key-vault-network-access "Public" --azure-keyvault-kms-key-id $KEY_ID

 

 

On notera la disponibilité de la feature dans le Terraform AzureRM provider, à partir de la version 3.40.0 du 19 janvier 2023 :

 

Et pour le cas où la version tarderait à être mise en place, il est toujours possible d’utiliser le provider AzAPI :

 

Pour vérifier le statut de la fonctionnalité, un coup d’œil à la description json du cluster et le tour est joué :

 

Quand l’argument « enabled » est configuré sur « true », tout est ok.

 

Gestion des secrets Kubernetes avec KMS etcd

 

Une fois la fonctionnalité est activée, il nous reste une action : mettre à jour les secrets Kubernetes existant. À défaut, ils ne seront pas chiffrés avec notre système KMS.

Cette mise à jour est relativement simple à réaliser, à travers une commande « kubectl » :

 

kubectl get secrets --all-namespaces -o json | kubectl replace -f -

 

 

Dans un environnement self-managed, il nous serait possible d’utiliser « etcdctl » afin de vérifier qu’un secret est chiffré avec le KMS provider. Ce n’est pas le cas d’AKS, nous devrons donc nous contenter de faire confiance à notre feature.

Cette mise à jour réalisée, nous avons donc des secrets chiffrés avec notre CMK, et tout nouveau secret utilisera également cette clé. Maintenant, que se passe-t-il dans le cas d’une rotation de clé ?

En effet, utiliser une CMK sans prévoir de rotation de clé n’est pas tellement utile d’un point de vue sécurité. D’autre part, dans le cas d’un provisioning via Terraform, il est toujours préférable de ne pas garder d’information sensible dans le state. De fait, la clé initialement utilisée devrait être changée juste après l’activation de la feature KMS. Pour sortir la gestion du cycle de vie de la clé de Terraform, on utilisera alors le meta-argument « ignore_changes » dans le bloc lifecycle.

Concernant la rotation à proprement parler, une commande az cli est disponible. On commence par récupérer l’ID de la clé de chiffrement :

spike@azure:~$ export keyid=$(az keyvault key show --name <key_name> --vault-name <key_vault_name> --query key.kid -o tsv)

 

 

Puis, on utilise la commande « update » sur le cluster cible :

 

spike@azure:~$ az aks update -n <aks_cluster_name> -g <resourceGroup_name> --enable-azure-keyvault-kms --azure-keyvault-kms-key-vault-network-access "Public" --azure-keyvault-kms-key-id $keyid

 

 

Une fois la mise à jour réalisée, on peut vérifier la version de la clé avec une commande az cli :

 

Il reste ensuite à remettre à jour les secrets avec la commande « kubectl replace » comme vu précédemment.

Voilà pour le chiffrement du control plane, passons maintenant au worker plane.

 

Gérer le chiffrement d’AKS – Worker plane

 

Considérant à présent les options de chiffrement du worker plane, nous avons mentionné précédemment :

  • Le chiffrement des managed disks avec la technologie SSE et une CMK
  • Le chiffrement de l’hôte pour chiffrer les échanges entre les workloads hébergés sur l’hôte et la couche de stockage.

 

Le schéma ci-dessous illustre ces 2 options :

Chiffrement des managed disks avec une CMK

 

 

Regardons tout cela d’un peu plus près.

 

Chiffrement des managed disks avec une CMK

 

Nous avons (ré-)introduit l’objet Disk Encryption Set, qui agit comme un intermédiaire entre le managed disk, l’instance de key vault et la couche de stockage.

AKS peut utiliser un Disk Encryption Set afin de mettre en œuvre le chiffrement avec une CMK. Il y a un unique paramètre à spécifier lors de la création du cluster, que nous allons voir juste après.

Avant cela, voici la liste des prérequis :

  • Une instance de Key Vault, avec soft delete, purge protection, ainsi que la capacité à utiliser le chiffrement de disque :

Ressources Access des managed disks avec une CMK

 

  • Un Disk Encryption Set, avec une User Assigned Identity ayant les accès sur l’instance de key vault
  • Une clé dans le key vault qui chiffre et déchiffre la donnée sur le stockage

 

Vous trouverez ci-après un extrait de configuration Terraform pour la création de ces objets :

 

À l’aide de ces prérequis, l’usage dans AKS est plutôt simple puisqu’il “suffit” de spécifier l’argument « disk_encryption_set_id » via Terraform ou « –node-os-dis-diskencryptionset-id » via az cli et la commande az aks create.

On peut par la suite vérifier le statut de chiffrement dans la définition json du cluster :

 

spike@azure:~$ az aks show -n <aks_cluster_name> -g <rgname> | jq .diskEncryptionSetId
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/<rgname>/providers/Microsoft.Compute/diskEncryptionSets/<disk_encrytionset_name>"

 

 

Ce qui nous valide le chiffrement des OS Disks avec notre CMK.

En ce qui concerne les workloads hébergés sur le cluster, ils ne devraient pas utiliser les OS disks, et ne sont donc pas chiffrés via le Disk Encryption Set.

En fait, lorsque l’on utilise du stockage dans AKS, on va s’appuyer sur les classes de stockages Kubernetes disponibles, et notamment celle basée sur les managed disks. Cette classe de stockage s’appuie sur le provisionner CSI driver pour les managed disks, et l’on peut trouver dans sa documentation un paramètre spécifique pour mettre en œuvre le chiffrement :

 

Name Meaning Available Value
diskEncryptionSetID ResourceId of the disk encryption set to use for enabling encryption at rest format: /subscriptions/{subs-id}/resourceGroups/{rg-name}/providers/Microsoft.Compute/diskEncryptionSets/{diskEncryptionSet-name}

 

 

Prenant en compte cette information, on peut créer une nouvelle classe de stockage qui, par défaut, utilise un Disk Encryption Set, et ainsi une CMK :

 

Puis un Persistent Volume Claim, faisant référence à cette classe de stockage :

 

Et finalement un pod utilisant ce volume :

 

Petit avertissement : si l’on utilise le même Disk Encryption Set que pour les OS Disks, dans la mesure où celui-ci ne vit pas dans le Resource Group managé par AKS, il sera nécessaire de donner à l’identité du control plane AKS un accès sur la ressource. Dans le cas contraire, on obtient le message suivant :

 

Lorsque l’accès est configuré, en cherchant la représentation Azure du PVC (c’est-à-dire un managed disk), nous devrions voir une référence à notre Disk Encryption Set :

Une référence à notre Disk Encryption Set

 

Pour finir, on pourrait se poser la question de la mise en œuvre du chiffrement sur un autre provisionner CSI comme Azure File. Sans rentrer dans les détails, on se rappellera que le chiffrement d’un Azure File ne dépend pas d’un Disk Encryption Set. Ensuite, en regardant la documentation du CSI provider, on pourra voir qu’à l’heure actuelle, il n’y a pas de référence à une configuration avec une CMK. Il est possible d’extrapoler en imaginant un provisioning statique du volume avec un compte de stockage chiffré avec une CMK. Toutefois, ce scénario n’ayant pas été testé, il reste pour l’heure à l’état hypothétique.

Nous avons à présent fini nos discussions autour du chiffrement au repos sur le worker plane. Regardons pour finir le chiffrement de l’hôte.

 

Chiffrement End-To-End avec le chiffrement de l’hôte

 

L’usage du Disk Encryption Set nous permet des scénarios CMK avec SSE et les disques managés. Comme évoqué plus en amont, le chiffrement de l’hôte permet de nous assurer du chiffrement End-To-End entre l’hôte (et les workloads hébergés) et la couche de stockage. En conclusion, toute donnée qui entre dans nos workloads est chiffrée depuis le point de vue de la plateforme Azure.

Pour mettre en œuvre le chiffrement de l’hôte d’un point de vue AKS, nous avons un prérequis coté fonctionnalité des providers de ressources. Le chiffrement des hôtes est en effet une feature des providers de compute (et c’est bien ce que nous utilisons dans le cadre d’AKS, avec des scale sets qui représentent le pendant Azure de nos nodes Kubernetes).

Pour vérifier le statut de la feature du provider, on utilise la commande suivante :

 

Si le statut est bien « registered », aucune action n’est requise. Si ce n’est pas le cas, il faut l’activer avec la commande « az feature register ».

Ensuite, il nous suffit de spécifier pour notre cluster ou nos node pools l’argument « –enable-encryption-at-host » avec les commandes « az aks create » et « az aks nodepool add ».

On notera que le chiffrement de l’hôte n’est activable qu’à la création du cluster pour le default node pool ou à la création d’un node pool.

Lorsque le chiffrement est activé, on peut encore une fois le voir dans la définition json de l’objet :

spike@azure:~$ az aks show -n <aks_cluster_name> -g <aks_rg> | grep -i enableEncryptionAtHost
      "enableEncryptionAtHost": true,

 

 

L’essentiel à retenir sur le chiffrement dans AKS

 

Sans surprise, AKS s’appuie sur les fonctionnalités de la plateforme Azure pour les questions relatives au chiffrement :

  • Chiffrement au repos pour la couche de stockage
  • Chiffrement de l’hôte pour assurer un chiffrement end-to-end

 

Nous avons le choix d’utiliser la clé managée par la plateforme, ce qui constitue notre option par défaut.

Nous pouvons également préférer un scénario basé sur l’usage de Customer Managed Key. Dans ce cas, il faut bien entendu considérer l’impact opérationnel inhérent à la gestion des clés, leurs rotations et surtout le stockage de ces clés… dans une instance de Key Vault.

Vous souhaitez être accompagnés dans vos projets de transformation numérique ? Contactez-nous !

 

 

 

Nos autres articles
Commentaires
Laisser un commentaire

Restez au courant des dernières actualités !
Le meilleur de l’actualité sur le Cloud, le DevOps, l’IT directement dans votre boîte mail.