Endurece la seguridad del clúster

En este documento, se describe cómo endurecer la seguridad de tus clústeres de GKE en Bare Metal.

Proteger tus contenedores con SELinux

Para proteger tus contenedores, habilita SELinux, que es compatible con Red Hat Enterprise Linux (RHEL). Si tus máquinas anfitrión ejecutan RHEL y deseas habilitar SELinux en tu clúster, debes habilitar SELinux en todas tus máquinas host. Para obtener más información, consulta cómo proteger tus contenedores con SELinux.

Usa seccomp para restringir contenedores

El modo de procesamiento seguro (seccomp) está disponible en la versión 1.11 de GKE en Bare Metal y versiones posteriores. Ejecutar contenedores con un perfil seccomp mejora la seguridad de tu clúster porque restringe las llamadas al sistema que los contenedores pueden hacer en el kernel. Esto reduce la posibilidad de que se aprovechen las vulnerabilidades del kernel.

El perfil seccomp predeterminado contiene una lista de llamadas al sistema que un contenedor puede realizar. No se permiten llamadas al sistema que no estén en la lista. seccomp está habilitado de forma predeterminada en la versión 1.11 de GKE en Bare Metal. Esto significa que todos los contenedores del sistema y las cargas de trabajo del cliente se ejecutan con el perfil seccomp predeterminado del entorno de ejecución del contenedor. Incluso los contenedores y las cargas de trabajo que no especifican un perfil seccomp en sus archivos de configuración están sujetos a restricciones seccomp.

Cómo inhabilitar seccomp en todo el clúster o en cargas de trabajo particulares

Solo puedes inhabilitar seccomp durante la creación o actualización del clúster. No se puede usar bmctl update para inhabilitar esta función. Si deseas inhabilitar seccomp dentro de un clúster, agrega la siguiente sección clusterSecurity al archivo de configuración del clúster:

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

En el improbable caso de que algunas de tus cargas de trabajo necesiten ejecutar llamadas al sistema que seccomp bloquee de forma predeterminada, no tienes que inhabilitar seccomp en todo el clúster. En su lugar, puedes separar cargas de trabajo particulares para que se ejecuten en unconfined mode. La ejecución de una carga de trabajo en unconfined mode libera esa carga de trabajo de las restricciones que impone el perfil seccomp en el resto del clúster.

Para ejecutar un contenedor en unconfined mode, agrega la siguiente sección securityContext al manifiesto del Pod:

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

No ejecutes contenedores como usuario root

De forma predeterminada, los procesos en contenedores se ejecutan como root. Esto plantea un posible problema de seguridad, ya que si un proceso se sale del contenedor, ese proceso se ejecuta como root en la máquina anfitrión. Por lo tanto, es recomendable ejecutar todas tus cargas de trabajo como un usuario no raíz.

En las siguientes secciones, se describen dos formas de ejecutar contenedores como un usuario no raíz.

Método n.º 1: agrega instrucción USER en Dockerfile

En este método, se usa un Dockerfile para garantizar que los contenedores no se ejecuten como un usuario root. En Dockerfile, puedes especificar con qué usuario se debe ejecutar el proceso dentro de un contenedor. En el siguiente fragmento de un Dockerfile, se muestra cómo hacerlo:

....

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

#Run Container as nonroot
USER nonroot
....

En este ejemplo, el comando useradd -u de Linux crea un usuario llamado nonroot dentro del contenedor. Este usuario tiene un ID de usuario (UID) de 8877.

La siguiente línea en Dockerfile ejecuta el comando USER nonroot. Este comando especifica que, a partir de este momento, en la imagen, los comandos se ejecutan como el usuario nonroot.

Otorga permisos al UID 8877 a fin de que los procesos del contenedor se puedan ejecutar de forma correcta para nonroot.

Método n.º 2: agrega campos securityContext a los archivos de manifiesto de Kubernetes

En este método, se usa un archivo de manifiesto de Kubernetes para garantizar que los contenedores no se ejecuten como usuarios root. La configuración de seguridad se especifica para un Pod, y esta se aplica a todos los contenedores dentro del Pod.

En el siguiente ejemplo, se muestra un extracto de un archivo de manifiesto para un Pod determinado:

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

En el campo runAsUser, se especifica que, para cualquier contenedor del Pod, todos los procesos se ejecutan con el ID de usuario 8877. El campo runAsGroup especifica que estos procesos tienen un ID de grupo principal (GID) de 8877. Recuerda otorgar los permisos necesarios y suficientes al UID 8877 para que los procesos del contenedor puedan ejecutarse de forma correcta.

Esto garantiza que los procesos dentro de un contenedor se ejecuten como UID 8877, que tiene menos privilegios que raíz.

Los contenedores de sistema en GKE en Bare Metal ayudan a instalar y administrar clústeres. El campo startUIDRangeRootlessContainers de la especificación del clúster puede controlar los UID y GID que usan estos contenedores. startUIDRangeRootlessContainers es un campo opcional que, si no se especifica, tiene el valor 2000. Los valores permitidos para startUIDRangeRootlessContainers son de 1000 a 57000. El valor de startUIDRangeRootlessContainers solo se puede cambiar durante las actualizaciones. Los contenedores del sistema usan los UID y GID en el rango de startUIDRangeRootlessContainers a startUIDRangeRootlessContainers + 2,999.

En el siguiente ejemplo, se muestra un extracto de un archivo de manifiesto para un recurso de clúster:

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

Elige el valor de startUIDRangeRootlessContainers para que los espacios de UID y GID que usan los contenedores del sistema no se superpongan con los asignados a las cargas de trabajo del usuario.

Cómo inhabilitar el modo sin raíz

A partir de la versión 1.10 de GKE en Bare Metal, los contenedores del plano de control de Kubernetes y los contenedores del sistema se ejecutan como usuarios no raíz de forma predeterminada. GKE en Bare Metal asigna UIDs y GID de estos usuarios en el rango 2000-4999. Sin embargo, esta asignación puede causar problemas si esos UIDs y GID ya se asignaron a procesos que se ejecutan dentro de tu entorno.

A partir de la versión 1.11 de GKE en Bare Metal, puedes inhabilitar el modo sin raíz cuando actualices el clúster. Cuando el modo sin raíz está inhabilitado, los contenedores del plano de control y los contenedores del sistema de Kubernetes se ejecutan como el usuario raíz.

Para inhabilitar el modo sin raíz, sigue estos pasos:

  1. Agrega la siguiente sección clusterSecurity al archivo de configuración del clúster:

    apiVersion: baremetal.cluster.gke.io/v1
    kind: Cluster
    metadata:
      name: example
      namespace: cluster-example
    spec:
    ...
      clusterSecurity:
        enableRootlessContainers: false
    ...
    
  2. Actualiza tu clúster. Para obtener más información, consulta Actualiza clústeres.

Restringe la capacidad de las cargas de trabajo de realizar modificaciones automáticas

Algunas cargas de trabajo de Kubernetes, en especial las del sistema, tienen permiso para realizar modificaciones automáticas. Por ejemplo, algunas cargas de trabajo se escalan automáticamente. Si bien es conveniente, esto puede permitir que un atacante que ya haya vulnerado un nodo pueda escalar más a fondo en el clúster. Por ejemplo, un atacante podría hacer que una carga de trabajo en el nodo se modifique a sí misma para ejecutarse como una cuenta de servicio con más privilegios que exista en el mismo espacio de nombres.

Idealmente, a las cargas de trabajo no se les debería otorgar permiso para modificarse a sí mismas. Cuando la modificación automática es necesaria, puedes limitar los permisos mediante la aplicación de restricciones de Gatekeeper o del controlador de políticas, como NoUpdateServiceAccount de la biblioteca de Gatekeeper de código abierto, que proporciona varias políticas de seguridad útiles.

Cuando implementas políticas, por lo general, es necesario permitir que los controladores que administran el ciclo de vida del clúster las omitan. Esto es necesario para que los controladores puedan realizar cambios en el clúster, como aplicar actualizaciones del clúster. Por ejemplo, si implementas la política NoUpdateServiceAccount en GKE en Bare Metal, debes establecer los siguientes parámetros en Constraint:

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

Inhabilita el puerto de solo lectura de kubelet

A partir de la versión 1.15.0, GKE en Bare Metal inhabilita el puerto 10255 de forma predeterminada, el puerto de solo lectura de kubelet. Cualquier carga de trabajo del cliente que esté configurada para leer datos de este puerto de kubelet no seguro 10255 debe migrarse a fin de usar el puerto seguro de kubelet 10250.

Solo los clústeres creados con la versión 1.15.0 o posterior tienen inhabilitado este puerto de forma predeterminada. El puerto de solo lectura 10255 de kubelet permanece accesible para los clústeres creados con una versión anterior a la 1.15.0, incluso después de una actualización del clúster a la versión 1.15.0 o posterior.

Este cambio se realizó porque el kubelet filtra información de baja sensibilidad a través del puerto 10255, que no está autenticado. La información incluye la información de configuración completa de todos los Pods que se ejecutan en un nodo, lo que puede ser valiosa para un atacante. También expone información de estado y métricas, lo que puede proporcionar estadísticas sensibles para la empresa.

La comparativa de CIS para Kubernetes recomienda inhabilitar el puerto de solo lectura de kubelet.

Mantenimiento

Supervisar los boletines de seguridad y actualizar los clústeres son medidas de seguridad importantes que se deben tomar una vez que los clústeres estén en funcionamiento.

Supervisa boletines de seguridad

El equipo de seguridad de GKE publica boletines de seguridad sobre vulnerabilidades de gravedad alta y crítica.

Estos boletines siguen un esquema de numeración común de vulnerabilidades de Google Cloud y están vinculados desde la página principal de boletines de Google Cloud y las notas de la versión de GKE on Bare Metal.

Usa este feed XML para suscribirte a los boletines de seguridad de GKE en Bare Metal y en productos relacionados. Suscribirse

Cuando se requiere una acción del cliente para abordar estas vulnerabilidades altas y críticas, Google se comunica con los clientes por correo electrónico. Además, Google también puede comunicarse con los clientes con contratos de asistencia a través de canales de asistencia.

Para obtener más información sobre cómo Google administra las vulnerabilidades y los parches de seguridad de GKE y GKE Enterprise, consulta Parches de seguridad.

Actualiza los clústeres

Kubernetes suele agregar nuevas funciones de seguridad y proporcionar parches de seguridad con frecuencia. Las versiones de GKE en Bare Metal incorporan mejoras de seguridad de Kubernetes que abordan las vulnerabilidades de seguridad que pueden afectar los clústeres.

Eres responsable de mantener actualizados tus clústeres de GKE en Bare Metal. Revisa las notas de la versión de cada versión. Para minimizar los riesgos de seguridad en los clústeres, planea realizar actualizaciones a nuevas versiones de parche cada mes y versiones secundarias cada cuatro meses.

Una de las muchas ventajas de actualizar un clúster es que actualiza de forma automática el archivo kubeconfig del clúster. El archivo kubeconfig autentica a un usuario en un clúster. El archivo kubeconfig se agrega al directorio del clúster cuando creas un clúster con bmctl. El nombre y la ruta de acceso predeterminados son bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig. Cuando actualizas un clúster, el archivo kubeconfig de ese clúster se renueva de forma automática. De lo contrario, el archivo kubeconfig vence un año después de su creación.

Para obtener información sobre cómo actualizar los clústeres, consulta Actualiza tus clústeres.

Usa los Controles del servicio de VPC con Cloud Interconnect o Cloud VPN

Cloud Interconnect proporciona conexiones de baja latencia y alta disponibilidad que te permiten transferir datos de manera confiable entre tus máquinas locales de equipos físicos y las redes de nube privada virtual (VPC) de Google Cloud. Para obtener más información sobre Cloud Interconnect, consulta Descripción general del aprovisionamiento de la interconexión dedicada.

Cloud VPN conecta de manera segura tu red de intercambio de tráfico a tu red de nube privada virtual (VPC) a través de una conexión IPsec VPN. Para obtener más información sobre Cloud VPN, consulta Descripción general de Cloud VPN.

Los Controles del servicio de VPC funcionan con Cloud Interconnect o Cloud VPN para proporcionar seguridad adicional a los clústeres. Los Controles del servicio de VPC ayudan a mitigar el riesgo de robo de datos. Con los Controles del servicio de VPC, puedes agregar proyectos a perímetros de servicio que protejan los recursos y servicios de las solicitudes que se originan fuera del perímetro. Para obtener más información sobre los perímetros de servicio, consulta Detalles y configuración del perímetro de servicio.

Para proteger por completo GKE en Bare Metal, debes usar la VIP restringida y agregar las siguientes APIs al perímetro de servicio:

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

Cuando uses bmctl para crear o actualizar un clúster, usa la marca --skip-api-check para omitir las llamadas a la API de Service Usage (serviceusage.googleapis.com). La API de Service Usage no es compatible con los Controles del servicio de VPC.