Reforzar la seguridad del clúster

En este documento se describe cómo reforzar la seguridad de los clústeres creados con Google Distributed Cloud (solo software) en hardware desnudo.

Protege tus contenedores mediante SELinux

Puedes proteger tus contenedores habilitando SELinux, que es compatible con Red Hat Enterprise Linux (RHEL). Si tus máquinas host ejecutan RHEL y quieres habilitar SELinux en tu clúster, debes habilitar SELinux en todas tus máquinas host. Consulta Protege tus contenedores mediante SELinux para obtener más información.

Usa seccomp para restringir contenedores

El modo de computación segura (seccomp) está disponible en la versión 1.11 y posteriores de Google Distributed Cloud. Ejecutar contenedores con un perfil seccomp mejora la seguridad de tu clúster, ya que restringe las llamadas al sistema que pueden hacer los contenedores al kernel. De esta forma, se reduce la probabilidad de que se aprovechen las vulnerabilidades del kernel.

El perfil seccomp predeterminado contiene una lista de llamadas al sistema que puede hacer un contenedor. No se permiten las llamadas al sistema que no estén en la lista. seccomp está habilitado de forma predeterminada en los clústeres con la versión 1.11 y posteriores. Esto significa que todos los contenedores del sistema y las cargas de trabajo de los clientes se ejecutan con el perfil seccomp predeterminado del tiempo 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 concretas

Solo puedes inhabilitar seccomp durante la creación o la actualización de un clúster. bmctl update no se puede usar para inhabilitar esta función. Si quieres inhabilitar seccomp en un clúster, añade 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 bloquea de forma predeterminada, no tienes que inhabilitar seccomp en todo el clúster. En su lugar, puedes seleccionar cargas de trabajo concretas para que se ejecuten en unconfined mode. Al ejecutar una carga de trabajo en unconfined mode, se libera de las restricciones que el perfil seccomp impone al resto del clúster.

Para ejecutar un contenedor en unconfined mode, añade la siguiente sección securityContext al archivo de manifiesto del pod:

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

No ejecutes contenedores como usuario root

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

En las siguientes secciones se describen dos formas de ejecutar contenedores como usuario no root.

Método 1: añadir la instrucción USER en Dockerfile

Este método usa un Dockerfile para asegurarse de que los contenedores no se ejecuten como un usuario root. En un 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 de Linux useradd -u crea un usuario llamado nonroot en el contenedor. Este usuario tiene el ID de usuario 8877.

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

Concede permisos al UID 8877 para que los procesos del contenedor se puedan ejecutar correctamente en nonroot.

Método 2: Añadir campos securityContext en el archivo de manifiesto de Kubernetes

Este método usa un archivo de manifiesto de Kubernetes para asegurarse de que los contenedores no se ejecuten como usuario root. Los ajustes de seguridad se especifican en un pod y, a su vez, se aplican a todos los contenedores del pod.

En el siguiente ejemplo se muestra un fragmento de un archivo de manifiesto de un Pod determinado:

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

El campo runAsUser especifica que, en el caso de los contenedores 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 que debes conceder los permisos necesarios y suficientes al UID 8877 para que los procesos del contenedor se puedan ejecutar correctamente.

De esta forma, los procesos de un contenedor se ejecutan como UID 8877, que tiene menos privilegios que la raíz.

Los contenedores del sistema en el software de Google Distributed Cloud ayudan a instalar y gestionar clústeres. Los UIDs y GIDs que usan estos contenedores se pueden controlar mediante el campo startUIDRangeRootlessContainers de la especificación del clúster. startUIDRangeRootlessContainers es un campo opcional que, si no se especifica, tiene el valor 2000. Los valores permitidos de startUIDRangeRootlessContainers son 1000-57000. El valor startUIDRangeRootlessContainers solo se puede cambiar durante las actualizaciones. Los contenedores del sistema usan los UIDs y GIDs del intervalo startUIDRangeRootlessContainers a startUIDRangeRootlessContainers + 2999.

En el siguiente ejemplo se muestra un fragmento de un archivo de manifiesto de un recurso Cluster:

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

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

Cómo inhabilitar el modo sin root

A partir de la versión 1.10 de Google Distributed Cloud, los contenedores del plano de control de Kubernetes y los contenedores del sistema se ejecutan como usuarios no root de forma predeterminada. Google Distributed Cloud asigna a estos usuarios UIDs y GIDs en el intervalo 2000-4999. Sin embargo, esta asignación puede causar problemas si esos UIDs y GIDs ya se han asignado a procesos que se ejecutan en tu entorno.

A partir de la versión 1.11, puedes inhabilitar el modo sin root al actualizar tu clúster. Cuando el modo sin root está inhabilitado, los contenedores del plano de control de Kubernetes y los contenedores del sistema se ejecutan como usuario root.

Para inhabilitar el modo sin root, sigue estos pasos:

  1. Añade 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 Actualizar clústeres.

Restringir la capacidad de las cargas de trabajo para modificarse a sí mismas

Algunas cargas de trabajo de Kubernetes, especialmente las cargas de trabajo del sistema, tienen permiso para modificarse a sí mismas. Por ejemplo, algunas cargas de trabajo se escalan verticalmente de forma automática. Aunque es una opción cómoda, puede permitir que un atacante que ya haya vulnerado un nodo siga escalando en el clúster. Por ejemplo, un atacante podría hacer que una carga de trabajo de un nodo se ejecute como una cuenta de servicio con más privilegios que exista en el mismo espacio de nombres.

Lo ideal es que las cargas de trabajo no tengan permiso para modificarse a sí mismas. Cuando sea necesario modificar el contenido, puedes limitar los permisos aplicando restricciones de Gatekeeper o Policy Controller, como NoUpdateServiceAccount de la biblioteca de código abierto de Gatekeeper, que proporciona varias políticas de seguridad útiles.

Cuando implementas políticas, suele ser necesario permitir que los controladores que gestionan el ciclo de vida del clúster omitan las políticas. Esto es necesario para que los controladores puedan hacer cambios en el clúster, como aplicar actualizaciones del clúster. Por ejemplo, si implementas la política NoUpdateServiceAccount en tus clústeres, debes definir los siguientes parámetros en Constraint:

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

Inhabilitar el puerto de solo lectura de kubelet

A partir de la versión 1.15.0, Google Distributed Cloud inhabilita de forma predeterminada el puerto 10255, el puerto de solo lectura de kubelet. Las cargas de trabajo de los clientes que estén configuradas para leer datos de este puerto kubelet no seguro 10255 deben migrarse para usar el puerto kubelet seguro 10250.

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

Este cambio se ha realizado porque kubelet revela información de baja sensibilidad a través del puerto 10255, que no está autenticado. La información incluye la configuración completa de todos los pods que se ejecutan en un nodo, lo que puede ser valioso para un atacante. También expone métricas e información de estado, que pueden proporcionar información valiosa para la empresa.

CIS Kubernetes Benchmark recomienda inhabilitar el puerto de solo lectura de kubelet.

Mantenimiento

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

Monitorizar los 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 Google Cloud esquema de numeración de vulnerabilidades común y se vinculan desde la página principal de Google Cloud boletines y las notas de la versión.

Usa este feed XML para suscribirte a los boletines de seguridad de Google Kubernetes Engine (GKE) y productos relacionados. Suscribirse

Cuando se requiere la intervención del cliente para solucionar estas vulnerabilidades de alta y crítica gravedad, Google se pone en contacto con él por correo electrónico. Además, Google también puede ponerse en contacto con los clientes que tengan contratos de asistencia a través de los canales de asistencia.

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

Actualizar clústeres

Kubernetes incorpora periódicamente nuevas funciones de seguridad y proporciona parches de seguridad. Las versiones de Google Distributed Cloud incorporan mejoras de seguridad de Kubernetes que solucionan vulnerabilidades de seguridad que pueden afectar a tus clústeres.

Usted es responsable de mantener sus clústeres actualizados. En cada lanzamiento, consulta las notas de la versión. Para minimizar los riesgos de seguridad de tus clústeres, planifica actualizar a las nuevas versiones de parche cada mes y a las versiones secundarias cada cuatro meses.

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

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

Usar Controles de 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 forma fiable entre tus máquinas físicas on-premise y lasGoogle Cloud redes de nube privada virtual (VPC). Para obtener más información sobre Cloud Interconnect, consulta la descripción general del aprovisionamiento de interconexión dedicada.

Cloud VPN conecta de forma segura tu red de emparejamiento 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 la información general sobre Cloud VPN.

Controles de Servicio de VPC funciona con Cloud Interconnect o Cloud VPN para proporcionar seguridad adicional a tus clústeres. Controles de Servicio de VPC ayuda a mitigar el riesgo de filtración externa de datos. Con Controles de Servicio de VPC, puedes añadir 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 de los perímetros de servicio.

Para proteger completamente los clústeres creados con Google Distributed Cloud, debes usar VIP restringida y añadir las siguientes APIs al perímetro de servicio:

  • API de Artifact Registry (artifactregistry.googleapis.com)
  • API Resource Manager (cloudresourcemanager.googleapis.com)
  • API de Compute Engine (compute.googleapis.com)
  • API Connect Gateway (connectgateway.googleapis.com)
  • API de Google Container Registry (containerregistry.googleapis.com)
  • API GKE Connect (gkeconnect.googleapis.com)
  • API de GKE Hub (gkehub.googleapis.com)
  • API de GKE On-Prem (gkeonprem.googleapis.com)
  • API de gestión de identidades y accesos (IAM) (iam.googleapis.com)
  • API de Cloud Logging (logging.googleapis.com)
  • API de Cloud Monitoring (monitoring.googleapis.com)
  • Monitorización de la configuración de la API Operations (opsconfigmonitoring.googleapis.com)
  • API Service Control (servicecontrol.googleapis.com)
  • API de Cloud Storage (storage.googleapis.com)