Renforcer la sécurité de votre cluster

Ce document explique comment renforcer la sécurité de vos clusters Google Distributed Cloud.

Sécuriser vos conteneurs à l'aide de SELinux

Vous pouvez sécuriser vos conteneurs en activant SELinux, compatible avec Red Hat Enterprise Linux (RHEL). Si vos machines hôtes exécutent RHEL et que vous souhaitez activer SELinux pour votre cluster, vous devez l'activer sur toutes vos machines hôtes. Pour plus d'informations, consultez la section Sécuriser vos conteneurs à l'aide de SELinux.

Utiliser seccomp pour restreindre les conteneurs

Le mode de calcul sécurisé (seccomp) est disponible dans les versions 1.11 et ultérieures de Google Distributed Cloud. L'exécution de conteneurs avec un profil seccomp améliore la sécurité de votre cluster, car elle limite les appels système que les conteneurs sont autorisés à effectuer au noyau. Cela réduit le risque d'exploitation des failles du noyau.

Le profil seccomp par défaut contient la liste des appels système qu'un conteneur est autorisé à effectuer. Les appels système ne figurant pas sur la liste ne sont pas autorisés. seccomp est activé par défaut dans la version 1.11 de Google Distributed Cloud. Cela signifie que tous les conteneurs système et toutes les charges de travail client sont exécutés avec le profil seccomp par défaut de l'environnement d'exécution des conteneurs. Même les conteneurs et les charges de travail qui ne spécifient pas de profil seccomp dans leurs fichiers de configuration sont soumis aux restrictions de seccomp.

Comment désactiver seccomp à l'échelle du cluster ou sur des charges de travail particulières

Vous ne pouvez désactiver seccomp que lors de la création ou de la mise à niveau du cluster. Vous ne pouvez pas utiliser bmctl update pour désactiver cette fonctionnalité. Si vous souhaitez désactiver seccomp dans un cluster, ajoutez la section clusterSecurity suivante au fichier de configuration du cluster:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: example
  namespace: cluster-example
spec:
...
  clusterSecurity:
    enableSeccomp: false
...

Dans le cas peu probable où certaines de vos charges de travail doivent exécuter des appels système que seccomp bloque par défaut, vous n'avez pas besoin de désactiver seccomp sur l'ensemble du cluster. À la place, vous pouvez désigner des charges de travail particulières à exécuter dans unconfined mode. L'exécution d'une charge de travail dans unconfined mode libère cette charge de travail des restrictions que le profil seccomp impose sur le reste du cluster.

Pour exécuter un conteneur dans unconfined mode, ajoutez la section securityContext suivante au fichier manifeste du pod :

apiVersion: v1
kind: Pod
....
spec:
  securityContext:
    seccompProfile:
      type: Unconfined
....

Ne pas exécuter de conteneurs en tant qu'utilisateur root

Par défaut, les processus des conteneurs s'exécutent en tant que root. Cela pose un problème de sécurité potentiel, car si un processus sort du conteneur, il s'exécute en tant que root sur la machine hôte. Il est donc conseillé d'exécuter toutes vos charges de travail en tant qu'utilisateur non racine.

Les sections suivantes décrivent deux manières d'exécuter des conteneurs en tant qu'utilisateur non racine.

Méthode 1 : ajouter une instruction USER dans Dockerfile

Cette méthode utilise un Dockerfile pour garantir que les conteneurs ne s'exécutent pas en tant qu'utilisateur root. Dans un Dockerfile, vous pouvez spécifier en tant que quel utilisateur le processus à l'intérieur d'un conteneur doit être exécuté. L'extrait suivant d'un Dockerfile montre comment procéder :

....

#Add a user with userid 8877 and name nonroot
RUN useradd −u 8877 nonroot

#Run Container as nonroot
USER nonroot
....

Dans cet exemple, la commande Linux useradd -u crée un utilisateur nommé nonroot dans le conteneur. Cet utilisateur possède l'ID utilisateur (UID) 8877.

La ligne suivante du Dockerfile exécute la commande USER nonroot. Cette commande spécifie qu'à partir de ce point de l'image, les commandes sont exécutées en tant qu'utilisateur nonroot.

Attribuez des autorisations à l'UID 8877 de sorte que les processus du conteneur puissent s'exécuter correctement pour nonroot.

Méthode 2 : ajouter des champs securityContext dans le fichier manifeste Kubernetes

Cette méthode utilise un fichier manifeste Kubernetes pour s'assurer que les conteneurs ne s'exécutent pas en tant qu'utilisateur root. Les paramètres de sécurité sont spécifiés pour un pod, et ces paramètres de sécurité sont à leur tour appliqués à tous les conteneurs du pod.

L'exemple suivant montre un extrait d'un fichier manifeste pour un pod donné :

apiVersion: v1
kind: Pod
metadata:
  name: name-of-pod
spec:
  securityContext:
    runAsUser: 8877
    runAsGroup: 8877
....

Le champ runAsUser spécifie que pour tous les conteneurs du pod, tous les processus s'exécutent avec l'ID utilisateur 8877. Le champ runAsGroup spécifie que ces processus ont l'ID de groupe (GID) principal 8877. N'oubliez pas d'accorder les autorisations nécessaires et suffisantes à l'UID 8877 afin que les processus de conteneur puissent s'exécuter correctement.

Cela garantit que les processus d'un conteneur sont exécutés en tant qu'UID 8877, qui dispose de privilèges moindres que l'utilisateur racine.

Les conteneurs système de Google Distributed Cloud facilitent l'installation et la gestion des clusters. Les UID et GID utilisés par ces conteneurs peuvent être contrôlés par le champ startUIDRangeRootlessContainers dans la spécification du cluster. Le champ startUIDRangeRootlessContainers est facultatif. S'il n'est pas spécifié, il présente la valeur 2000. Les valeurs autorisées pour startUIDRangeRootlessContainers vont de 1000 à 57000. La valeur de startUIDRangeRootlessContainers ne peut être modifiée que pendant les mises à niveau. Les conteneurs système utilisent les UID et GID compris dans la plage startUIDRangeRootlessContainers à startUIDRangeRootlessContainers + 2 999.

L'exemple suivant présente un extrait d'un fichier manifeste pour une ressource Cluster:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: name-of-cluster
spec:
 clusterSecurity:
    startUIDRangeRootlessContainers: 5000
...

Choisissez la valeur pour startUIDRangeRootlessContainers afin que les espaces UID et GID utilisés par les conteneurs système ne chevauchent pas ceux attribués aux charges de travail des utilisateurs.

Comment désactiver le mode sans racine

À partir de la version 1.10 de Google Distributed Cloud, les conteneurs du plan de contrôle et les conteneurs système Kubernetes s'exécutent par défaut en tant qu'utilisateurs non racines. Google Distributed Cloud attribue à ces utilisateurs des identifiants uniques et des GID compris dans la plage 2000-4999. Toutefois, cette attribution peut poser des problèmes si ces UID et GID ont déjà été alloués à des processus exécutés dans votre environnement.

À partir de la version 1.11 de Google Distributed Cloud, vous pouvez désactiver le mode sans racine lorsque vous mettez à niveau votre cluster. Lorsque le mode sans racine est désactivé, les conteneurs du plan de contrôle Kubernetes et les conteneurs système s'exécutent en tant qu'utilisateur racine.

Pour désactiver le mode sans racine, procédez comme suit :

  1. Ajoutez la section clusterSecurity suivante au fichier de configuration du cluster:

    apiVersion: baremetal.cluster.gke.io/v1
    kind: Cluster
    metadata:
      name: example
      namespace: cluster-example
    spec:
    ...
      clusterSecurity:
        enableRootlessContainers: false
    ...
    
  2. Mettez à niveau votre cluster. Pour en savoir plus, consultez la page Mettre à niveau les clusters.

Restreindre les capacités d'automodification des charges de travail

Certaines charges de travail Kubernetes, en particulier les charges de travail système, sont autorisées à s'automodifier. Par exemple, certaines charges de travail effectuent des autoscaling verticaux sur elle-mêmes. Bien que cette capacité soit pratique, elle peut permettre à un pirate informatique ayant déjà compromis un nœud de passer au niveau supérieur dans le cluster. Par exemple, un pirate informatique peut faire en sorte qu'une charge de travail sur le nœud se modifie pour s'exécuter en tant que compte de service plus privilégié qui existe dans le même espace de noms.

Idéalement, les charges de travail ne doivent pas avoir l'autorisation de se modifier elles-mêmes. Lorsque l'automodification est nécessaire, vous pouvez limiter les autorisations en appliquant des contraintes Gatekeeper ou Policy Controller, telles que NoUpdateServiceAccount de la bibliothèque Open Source Gatekeeper, qui offre plusieurs règles de sécurité utiles.

Lorsque vous déployez des stratégies, il est généralement nécessaire d'autoriser les contrôleurs qui gèrent le cycle de vie du cluster à les contourner. Cela est nécessaire pour que les contrôleurs puissent apporter des modifications au cluster, telles que l'application de mises à niveau de cluster. Par exemple, si vous déployez la règle NoUpdateServiceAccount sur Google Distributed Cloud, vous devez définir les paramètres suivants dans Constraint:

parameters:
  allowedGroups:
  - system:masters
  allowedUsers: []

Désactiver le port en lecture seule du kubelet

À partir de la version 1.15.0, Google Distributed Cloud désactive par défaut le port 10255, le port en lecture seule du kubelet. Toutes les charges de travail des clients configurées pour lire les données à partir de ce port de kubelet non sécurisé 10255 doivent migrer pour utiliser le port de kubelet sécurisé 10250.

Ce port n'est désactivé par défaut que pour les clusters créés avec la version 1.15.0 ou une version ultérieure. Le port en lecture seule 10255 du kubelet reste accessible aux clusters créés avec une version antérieure à 1.15.0, même après une mise à niveau du cluster vers la version 1.15.0 ou une version ultérieure.

Cette modification a été effectuée, car le kubelet divulgue des informations de faible sensibilité sur le port 10255, qui n'est pas authentifié. Ces informations incluent les informations de configuration complètes pour tous les pods s'exécutant sur un nœud, ce qui peut être utile à un pirate informatique. Il expose également des métriques et des informations sur l'état, qui peuvent fournir des insights sensibles pour l'entreprise.

La désactivation du port en lecture seule du kubelet est recommandée par le benchmark CIS de Kubernetes.

Maintenance

La surveillance des bulletins de sécurité et la mise à niveau de vos clusters sont des mesures de sécurité importantes à prendre en compte une fois que vos clusters sont opérationnels.

Surveiller les bulletins de sécurité

L'équipe de sécurité GKE publie des bulletins de sécurité pour les failles de gravité élevée et critique.

Ces bulletins suivent un schéma de numérotation des failles Google Cloud courant. Ils sont accessibles depuis la page principale des bulletins Google Cloud et les notes de version de Google Distributed Cloud.

Utilisez ce flux XML pour vous abonner aux bulletins de sécurité de Google Distributed Cloud et des produits associés. S'abonner

Lorsque la réaction du client est requise pour remédier à ces failles critiques, Google contacte les clients par e-mail. Google peut également contacter les clients par le biais de contrats d'assistance via des canaux d'assistance.

Pour en savoir plus sur la manière dont Google gère les failles et les correctifs de sécurité pour GKE et GKE Enterprise, consultez la page Appliquer des correctifs de sécurité.

Mettre à niveau les clusters

Kubernetes introduit régulièrement de nouvelles fonctionnalités de sécurité et fournit des correctifs de sécurité. Les versions de Google Distributed Cloud intègrent des améliorations de la sécurité Kubernetes qui corrigent les failles de sécurité susceptibles d'affecter vos clusters.

Vous êtes responsable de la mise à jour de vos clusters GKE sur Bare Metal. Pour chaque version, consultez les notes de version. Pour minimiser les risques de sécurité pour vos clusters, prévoyez de passer à de nouvelles versions de correctif tous les mois et à des versions mineures tous les quatre mois.

L'un des nombreux avantages de la mise à niveau d'un cluster est l'actualisation automatique du fichier kubeconfig du cluster. Le fichier kubeconfig authentifie un utilisateur auprès d'un cluster. Le fichier kubeconfig est ajouté au répertoire du cluster lorsque vous le créez avec bmctl. Le nom et le chemin d'accès par défaut sont bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig. Lorsque vous mettez à niveau un cluster, le fichier kubeconfig de ce cluster est automatiquement renouvelé. Sinon, le fichier kubeconfig expire un an après sa création.

Pour en savoir plus sur la mise à niveau de vos clusters, consultez la page Mettre à niveau vos clusters.

Utiliser VPC Service Controls avec Cloud Interconnect ou Cloud VPN

Cloud Interconnect fournit des connexions à faible latence et à haute disponibilité qui vous permettent de transférer des données de manière fiable entre vos machines Bare Metal sur site et les réseaux de cloud privé virtuel (VPC) Google Cloud. Pour en savoir plus sur Cloud Interconnect, consultez la page Présentation du provisionnement de Dedicated Interconnect.

Cloud VPN connecte de manière sécurisée votre réseau pair à votre réseau cloud privé virtuel (VPC) via une connexion VPN IPsec. Pour en savoir plus sur Cloud VPN, consultez la page Présentation de Cloud VPN.

VPC Service Controls fonctionne avec Cloud Interconnect ou Cloud VPN pour renforcer la sécurité de vos clusters. VPC Service Controls permet de limiter le risque d'exfiltration de données. À l'aide de VPC Service Controls, vous pouvez ajouter des projets aux périmètres de service afin de protéger les ressources et les services des requêtes provenant de l'extérieur du périmètre. Pour en savoir plus sur les périmètres de service, consultez la section Détails et configuration du périmètre de service.

Pour protéger entièrement Google Distributed Cloud, vous devez utiliser une adresse IP virtuelle restreinte et ajouter les API suivantes au périmètre de service:

  • API Artifact Registry (artifactregistry.googleapis.com)
  • API Resource Manager (cloudresourcemanager.googleapis.com)
  • API Compute Engine (compute.googleapis.com)
  • API Connect Gateway (connectgateway.googleapis.com)
  • API Google Container Registry (containerregistry.googleapis.com)
  • API GKE Connect (gkeconnect.googleapis.com)
  • API GKE Hub (gkehub.googleapis.com)
  • API GKE On-Prem (gkeonprem.googleapis.com)
  • API Identity and Access Management (iam.googleapis.com)
  • API Cloud Logging (logging.googleapis.com)
  • API Cloud Monitoring (monitoring.googleapis.com)
  • API Config Monitoring pour Ops (opsconfigmonitoring.googleapis.com)
  • API Service Control (servicecontrol.googleapis.com)
  • API Cloud Storage (storage.googleapis.com)

Lorsque vous utilisez bmctl pour créer ou mettre à niveau un cluster, utilisez l'option --skip-api-check pour contourner l'appel de l'API Service Usage (serviceusage.googleapis.com). L'API Service Usage n'est pas compatible avec VPC Service Controls.