Restringe el tráfico de salida del servidor de la API

Puedes mejorar la seguridad de tu plano de control de Google Kubernetes Engine (GKE) inhabilitando las direcciones IP externas de las instancias de máquina virtual (VM) del plano de control. En este documento, se muestra a los ingenieros de seguridad cómo controlar el tráfico de salida del servidor de la API de Kubernetes y cómo evitar posibles interrupciones en los webhooks de admisión.

Ya deberías estar familiarizado con lo siguiente:

Niveles de restricción

Puedes especificar uno de los siguientes niveles de restricción cuando creas o actualizas un clúster:

  • Sin tráfico (NONE): Inhabilita la dirección IP externa de cada instancia de VM del plano de control y enruta todo el tráfico de salida del servidor de la API a un agujero negro. Este nivel de restricción tiene los siguientes efectos:
    • GKE bloquea el tráfico de salida directo desde el servidor de la API a los servidores de webhook de admisión que se ejecutan fuera del clúster. Se ven afectados todos los webhooks de admisión que usan una URL o una dirección IP para comunicarse con el servidor de webhook.
    • GKE bloquea cualquier tráfico de salida directo desde el servidor de la API a servicios externos, incluidos Internet y Google Cloud servicios. El tráfico para la autenticación de GKE y para los componentes del sistema, como el servidor de metadatos, no se ve afectado.
    • No se ven afectados otros tipos de tráfico de salida, como el tráfico crítico del sistema o el tráfico de tus nodos.
    • GKE usa una ValidatingAdmissionPolicy para rechazar la creación o las actualizaciones de ValidatingWebhookConfigurations o MutatingWebhookConfigurations que usan el campo clientConfig.url.
  • Todo el tráfico (VIA_CONTROL_PLANE): Conserva la dirección IP externa de cada instancia del plano de control y permite que el servidor de la API use la dirección IP para el tráfico de salida. Esta opción es la predeterminada en GKE.

Limitaciones

Si inhabilitas el tráfico de salida configurando el nivel de restricción en NONE, el clúster no puede usar direcciones IP públicas que se usan de forma privada (PUPI).

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta el comando gcloud components update para obtener la versión más reciente. Es posible que las versiones anteriores de gcloud CLI no admitan la ejecución de los comandos de este documento.
  • Asegúrate de tener un clúster de GKE Autopilot o Standard que ejecute la versión 1.35.1-gke.1396000 o posterior. También puedes crear un clúster de Autopilot.
  • Si tienes servidores de webhook externos, verifica que uses una referencia de servicio para comunicarte con esos servidores. Cuando inhabilitas el tráfico de salida del servidor de la API, falla cualquiera de tus webhooks que use una URL para comunicarse con el servidor de webhook. Los webhooks administrados por GKE no se ven afectados.

Personaliza el tráfico de salida del servidor de la API

Puedes personalizar el nivel de restricción para el tráfico de salida del servidor de la API cuando creas o actualizas un clúster. Para actualizar un clúster existente, usa la marca --control-plane-egress:

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

Reemplaza lo siguiente:

  • CLUSTER_NAME: El nombre de tu clúster.
  • CONTROL_PLANE_LOCATION: La región o zona de tu plano de control del clúster, como us-central1 o us-central1-a.
  • CONTROL_PLANE_EGRESS_MODE: El nivel de restricción para el tráfico de salida de tu servidor de la API. Usa uno de los siguientes valores:
    • NONE: Inhabilita la dirección IP externa de tus instancias de VM del plano de control y bloquea todo el tráfico de salida no crítico del servidor de la API. GKE impide la creación de configuraciones de webhook nuevas que usan el campo clientConfig.url.
    • VIA_CONTROL_PLANE: Conserva la dirección IP externa de las instancias de VM del plano de control y permite el tráfico de salida del servidor de la API. Este es el valor predeterminado.

Verifica la restricción del tráfico de salida

Para verificar si GKE bloquea el tráfico de salida de tu servidor de la API, usa cualquiera de los siguientes métodos:

  • Verifica la configuración del clúster:

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

    El resultado es uno de los siguientes:

    • NONE: El tráfico de salida está restringido.
    • VIA_CONTROL_PLANE: El tráfico de salida no está restringido.
  • Para verificar el efecto de los cambios en los webhooks nuevos, intenta crear una configuración de webhook que use el campo 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"
    

    El resultado es similar a este:

    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.
    

    Este resultado indica que una ValidatingAdmissionPolicy de GKE te impide crear o actualizar configuraciones de webhook con el campo clientConfig.url. Si borras la ValidatingAdmissionPolicy, puedes crear o actualizar la configuración, pero las solicitudes de admisión no llegarán al servidor de webhook.

  • Para verificar el efecto de los cambios en los webhooks existentes en el clúster, intenta enviar una solicitud directa a una dirección IP fuera del clúster:

    1. Habilita API_SERVER registros para tu clúster.
    2. Borra la ValidatingAdmissionPolicy gke-restrict-webhook-url:

      kubectl delete validatingadmissionpolicy gke-restrict-webhook-url
      

      Cuando borras la ValidatingAdmissionPolicy, puedes crear o actualizar configuraciones de webhook con el campo clientConfig.url. El clúster vuelve a crear automáticamente la ValidatingAdmissionPolicy, por lo que esta omisión es temporal.

    3. En el campo clientConfig.url de una ValidatingWebhookConfiguration o MutatingWebhookConfiguration, especifica una dirección IP o URL para enviar solicitudes. Puedes usar un valor de ejemplo, como http://example.com o 203.0.113.100.

    4. Consulta los registros del servidor de la API para ver un mensaje de error como el siguiente:

      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
      

      Este resultado indica que, aunque se borre la ValidatingAdmissionPolicy, las solicitudes de admisión no pueden llegar a un servidor de webhook mediante la dirección IP o la URL del servidor.

Después de inhabilitar las direcciones IP externas de las instancias de VM del plano de control, GKE bloquea el tráfico a cualquier webhook que use una URL para comunicarse con servidores de webhook externos. Debes usar el campo clientConfig.service en la configuración de webhook para configurar una ruta alternativa que use tu servidor de la API. Para obtener más información, consulta Configuración de webhook externo.

¿Qué sigue?