Restreindre le trafic sortant du serveur d'API

Vous pouvez améliorer la sécurité de votre plan de contrôle Google Kubernetes Engine (GKE) en désactivant les adresses IP externes des instances de machines virtuelles (VM) du plan de contrôle. Ce document explique aux ingénieurs en sécurité comment contrôler le trafic de sortie du serveur d'API Kubernetes et comment éviter les éventuelles perturbations des webhooks d'admission.

Vous devez déjà connaître les éléments suivants :

Niveaux de restriction

Lorsque vous créez ou mettez à jour un cluster, vous pouvez spécifier l'un des niveaux de restriction suivants :

  • Aucun trafic (NONE) : désactivez l'adresse IP externe de chaque instance de VM du plan de contrôle et routez tout le trafic sortant du serveur d'API vers un trou noir. Ce niveau de restriction a les effets suivants :
    • GKE bloque le trafic de sortie direct du serveur d'API vers les serveurs de webhook d'admission qui s'exécutent en dehors du cluster. Tous les webhooks d'admission qui utilisent une URL ou une adresse IP pour contacter le serveur de webhook sont concernés.
    • GKE bloque tout trafic de sortie direct du serveur d'API vers les services externes, y compris Internet et les servicesGoogle Cloud . Le trafic pour l'authentification GKE et vers les composants système tels que le serveur de métadonnées n'est pas affecté.
    • Les autres types de trafic de sortie, tels que le trafic système critique ou le trafic provenant de vos nœuds, ne sont pas concernés.
    • GKE utilise une ValidatingAdmissionPolicy pour refuser la création ou la mise à jour de ValidatingWebhookConfigurations ou de MutatingWebhookConfigurations qui utilisent le champ clientConfig.url.
  • Tout le trafic (VIA_CONTROL_PLANE) : conservez l'adresse IP externe de chaque instance de plan de contrôle et laissez le serveur d'API utiliser l'adresse IP pour le trafic sortant. Cette option est celle par défaut dans GKE.

Limites

Si vous désactivez le trafic de sortie en définissant le niveau de restriction sur NONE, le cluster ne peut pas utiliser d'adresses IP publiques utilisées en mode privé (PUPI).

Avant de commencer

Avant de commencer, effectuez les tâches suivantes :

  • Activez l'API Google Kubernetes Engine.
  • Activer l'API Google Kubernetes Engine
  • Si vous souhaitez utiliser la Google Cloud CLI pour cette tâche, installez et initialisez la gcloud CLI. Si vous avez déjà installé la gcloud CLI, obtenez la dernière version en exécutant la commande gcloud components update. Il est possible que les versions antérieures de la gcloud CLI ne permettent pas d'exécuter les commandes de ce document.
  • Assurez-vous de disposer d'un cluster GKE Autopilot ou Standard exécutant la version 1.35.1-gke.1396000 ou ultérieure. Vous pouvez également créer un cluster Autopilot.
  • Si vous disposez de serveurs de webhook externes, vérifiez que vous utilisez une référence de service pour contacter ces serveurs. Lorsque vous désactivez le trafic sortant du serveur d'API, tous vos webhooks qui utilisent une URL pour contacter le serveur de webhook échouent. Les Webhooks gérés par GKE ne sont pas concernés.

Personnaliser le trafic sortant du serveur d'API

Vous pouvez personnaliser le niveau de restriction du trafic sortant du serveur d'API lorsque vous créez ou mettez à jour un cluster. Pour mettre à jour un cluster existant, utilisez l'option --control-plane-egress :

gcloud container clusters update CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --control-plane-egress=CONTROL_PLANE_EGRESS_MODE

Remplacez les éléments suivants :

  • CLUSTER_NAME : nom du cluster
  • CONTROL_PLANE_LOCATION : région ou zone du plan de contrôle de votre cluster, par exemple us-central1 ou us-central1-a.
  • CONTROL_PLANE_EGRESS_MODE : niveau de restriction pour le trafic sortant de votre serveur d'API. Utilisez l'une des valeurs suivantes :
    • NONE : désactivez l'adresse IP externe de vos instances de VM de plan de contrôle et bloquez tout le trafic sortant non critique du serveur d'API. GKE empêche la création de configurations de webhook utilisant le champ clientConfig.url.
    • VIA_CONTROL_PLANE : conservez l'adresse IP externe des instances de VM du plan de contrôle et autorisez le trafic sortant du serveur d'API. Il s'agit de la valeur par défaut.

Vérifier la restriction du trafic de sortie

Pour vérifier si GKE bloque le trafic de sortie de votre serveur d'API, utilisez l'une des méthodes suivantes :

  • Vérifiez la configuration de votre cluster :

    gcloud container clusters describe CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --format='value(controlPlaneEgress)'
    

    Le résultat est l'un des suivants :

    • NONE : le trafic de sortie est limité.
    • VIA_CONTROL_PLANE : le trafic sortant n'est pas limité.
  • Pour vérifier l'effet de vos modifications sur les nouveaux webhooks, essayez de créer une configuration de webhook qui utilise le champ clientConfig.url :

    cat <<EOF | kubectl apply -f -
    apiVersion: admissionregistration.k8s.io/v1
    kind: MutatingWebhookConfiguration
    metadata:
      name: test-webhook-config
    webhooks:
    - name: my-webhook.example.com
      clientConfig:
        url: "https://my-webhook.example.com:9443/my-webhook-path"
    

    Le résultat ressemble à ce qui suit :

    ValidatingAdmissionPolicy 'gke-restrict-webhook-url' denied request: Egress
    traffic from the API server through the control plane is disabled. As a
    result, direct API server calls to external webhook servers are blocked.
    To connect to external webhooks, update any webhook configurations that use
    clientConfig.url to use clientConfig.service instead.
    

    Ce résultat indique qu'une stratégie ValidatingAdmissionPolicy GKE vous empêche de créer ou de mettre à jour des configurations de webhook avec le champ clientConfig.url. Si vous supprimez ValidatingAdmissionPolicy, vous pouvez créer ou mettre à jour la configuration, mais les requêtes d'admission n'atteindront pas le serveur de webhook.

  • Pour vérifier l'effet de vos modifications sur les webhook existants dans le cluster, essayez d'envoyer une requête directe à une adresse IP en dehors du cluster :

    1. Activez les journaux API_SERVER pour votre cluster.
    2. Supprimez la gke-restrict-webhook-url ValidatingAdmissionPolicy :

      kubectl delete validatingadmissionpolicy gke-restrict-webhook-url
      

      Lorsque vous supprimez ValidatingAdmissionPolicy, vous pouvez créer ou mettre à jour des configurations de webhook avec le champ clientConfig.url. Le cluster recrée automatiquement la ValidatingAdmissionPolicy. Ce contournement est donc temporaire.

    3. Dans le champ clientConfig.url d'une configuration ValidatingWebhookConfiguration ou MutatingWebhookConfiguration, spécifiez une adresse IP ou une URL vers laquelle envoyer les requêtes. Vous pouvez utiliser une valeur d'exemple, telle que http://example.com ou 203.0.113.100.

    4. Recherchez dans les journaux du serveur d'API un message d'erreur semblable à celui-ci :

      Error from server (InternalError): error when creating "STDIN":
        Internal error occurred: failed calling webhook
        WEBHOOK_NAME": failed to call
        webhook: Post "WEBHOOK_URL":
        proxyconnect tcp: dial tcp: lookup master-internet-access-unavailable.localhost
        on 169.254.169.254:53: no such host
      

      Ce résultat indique que même si la ValidatingAdmissionPolicy est supprimée, les requêtes d'admission ne peuvent pas atteindre un serveur de webhook à l'aide de l'adresse IP ou de l'URL du serveur.

Une fois que vous avez désactivé les adresses IP externes de vos instances de VM du plan de contrôle, GKE bloque le trafic vers tous les Webhooks qui utilisent une URL pour contacter des serveurs Webhook externes. Vous devez utiliser le champ clientConfig.service dans la configuration de votre webhook pour configurer un autre itinéraire que votre serveur d'API pourra utiliser. Pour en savoir plus, consultez Configuration des Webhooks externes.

Étapes suivantes