Este lab expone algunas de las preocupaciones de seguridad de la configuración predeterminada de un clúster de GKE y las medidas de endurecimiento correspondientes para prevenir las múltiples rutas de escape de Pods y la elevación de privilegios del clúster. Estas rutas de ataque son importantes en las siguientes situaciones:
Una falla de la aplicación en un Pod externo que permite ataques de falsificación de solicitudes del servidor (SSRF)
Un contenedor completamente vulnerado dentro de un Pod que permite la ejecución remota de comandos (RCE)
Un usuario interno malicioso o un atacante con un conjunto de credenciales de usuario interno vulneradas que tiene la capacidad de crear/actualizar un Pod en un espacio de nombres determinado
Los ingenieros de GKE Helmsman crearon este lab para ayudarte a comprender mejor el endurecimiento de los parámetros de configuración predeterminados de los clústeres de GKE.
El código de ejemplo para este lab se proporciona sin modificaciones ni garantías
Objetivos
Cuando finalices el lab, comprenderás la necesidad de proteger los metadatos de las instancias de GKE y definir políticas de PodSecurityPolicy en tu entorno.
Realizarás lo siguiente:
Crearás un clúster de GKE pequeño con la configuración predeterminada.
Validarás las rutas de escape de Pods más comunes y la elevación de privilegios del clúster desde la perspectiva de un usuario interno malicioso.
Endurecerás el clúster de GKE para prevenir estos problemas.
Validarás el clúster para que ya no se permitan esas acciones.
Configuración y requisitos
Antes de hacer clic en el botón Comenzar lab
Lee estas instrucciones. Los labs cuentan con un temporizador que no se puede pausar. El temporizador, que comienza a funcionar cuando haces clic en Comenzar lab, indica por cuánto tiempo tendrás a tu disposición los recursos de Google Cloud.
Este lab práctico te permitirá realizar las actividades correspondientes en un entorno de nube real, no en uno de simulación o demostración. Para ello, se te proporcionan credenciales temporales nuevas que utilizarás para acceder a Google Cloud durante todo el lab.
Para completar este lab, necesitarás lo siguiente:
Acceso a un navegador de Internet estándar. Se recomienda el navegador Chrome.
Nota: Usa una ventana del navegador privada o de incógnito (opción recomendada) para ejecutar el lab. Así evitarás conflictos entre tu cuenta personal y la cuenta de estudiante, lo que podría generar cargos adicionales en tu cuenta personal.
Tiempo para completar el lab (recuerda que, una vez que comienzas un lab, no puedes pausarlo).
Nota: Usa solo la cuenta de estudiante para este lab. Si usas otra cuenta de Google Cloud, es posible que se apliquen cargos a esa cuenta.
Cómo iniciar tu lab y acceder a la consola de Google Cloud
Haz clic en el botón Comenzar lab. Si debes pagar por el lab, se abrirá un diálogo para que selecciones la forma de pago.
A la izquierda, se encuentra el panel Detalles del lab, que tiene estos elementos:
El botón para abrir la consola de Google Cloud
El tiempo restante
Las credenciales temporales que debes usar para el lab
Otra información para completar el lab, si es necesaria
Haz clic en Abrir la consola de Google Cloud (o haz clic con el botón derecho y selecciona Abrir el vínculo en una ventana de incógnito si ejecutas el navegador Chrome).
El lab inicia recursos y abre otra pestaña en la que se muestra la página de acceso.
Sugerencia: Ordena las pestañas en ventanas separadas, una junto a la otra.
Nota: Si ves el diálogo Elegir una cuenta, haz clic en Usar otra cuenta.
De ser necesario, copia el nombre de usuario a continuación y pégalo en el diálogo Acceder.
{{{user_0.username | "Username"}}}
También puedes encontrar el nombre de usuario en el panel Detalles del lab.
Haz clic en Siguiente.
Copia la contraseña que aparece a continuación y pégala en el diálogo Te damos la bienvenida.
{{{user_0.password | "Password"}}}
También puedes encontrar la contraseña en el panel Detalles del lab.
Haz clic en Siguiente.
Importante: Debes usar las credenciales que te proporciona el lab. No uses las credenciales de tu cuenta de Google Cloud.
Nota: Usar tu propia cuenta de Google Cloud para este lab podría generar cargos adicionales.
Haz clic para avanzar por las páginas siguientes:
Acepta los Términos y Condiciones.
No agregues opciones de recuperación o autenticación de dos factores (esta es una cuenta temporal).
No te registres para obtener pruebas gratuitas.
Después de un momento, se abrirá la consola de Google Cloud en esta pestaña.
Nota: Para acceder a los productos y servicios de Google Cloud, haz clic en el menú de navegación o escribe el nombre del servicio o producto en el campo Buscar.
Activa Cloud Shell
Cloud Shell es una máquina virtual que cuenta con herramientas para desarrolladores. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud. Cloud Shell proporciona acceso de línea de comandos a tus recursos de Google Cloud.
Haz clic en Activar Cloud Shell en la parte superior de la consola de Google Cloud.
Haz clic para avanzar por las siguientes ventanas:
Continúa en la ventana de información de Cloud Shell.
Autoriza a Cloud Shell para que use tus credenciales para realizar llamadas a la API de Google Cloud.
Cuando te conectes, habrás completado la autenticación, y el proyecto estará configurado con tu Project_ID, . El resultado contiene una línea que declara el Project_ID para esta sesión:
Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}
gcloud es la herramienta de línea de comandos de Google Cloud. Viene preinstalada en Cloud Shell y es compatible con la función de autocompletado con tabulador.
Puedes solicitar el nombre de la cuenta activa con este comando (opcional):
gcloud auth list
Haz clic en Autorizar.
Resultado:
ACTIVE: *
ACCOUNT: {{{user_0.username | "ACCOUNT"}}}
To set the active account, run:
$ gcloud config set account `ACCOUNT`
Puedes solicitar el ID del proyecto con este comando (opcional):
gcloud config list project
Resultado:
[core]
project = {{{project_0.project_id | "PROJECT_ID"}}}
Nota: Para obtener toda la documentación de gcloud, en Google Cloud, consulta la guía con la descripción general de gcloud CLI.
Tarea 1. Crea un clúster de GKE simple
Configura una zona en una variable de entorno llamada MY_ZONE. Este lab usa “”, por lo que puedes seleccionar una zona si así lo prefieres:
export MY_ZONE={{{project_0.default_zone|ZONE}}}
Ejecuta este comando para iniciar un clúster de Kubernetes administrado por Kubernetes Engine que se llama simplecluster y configúralo para ejecutar 2 nodos:
La creación de un clúster tarda varios minutos, ya que Kubernetes Engine aprovisiona las máquinas virtuales. A los fines de este lab, puedes ignorar de forma segura las advertencias sobre las funciones disponibles en las versiones nuevas.
Una vez que se haya creado el clúster, verifica tu versión instalada de Kubernetes con el comando kubectl version:
kubectl version
El comando gcloud container clusters create autenticó kubectl automáticamente.
Mira tus nodos en ejecución en la consola de Cloud. En el menú de navegación, haz clic en Compute Engine > Instancias de VM.
Ya puedes usar tu clúster de Kubernetes.
Haz clic en Revisar mi progreso para verificar el objetivo. Crear un clúster de GKE simple
Tarea 2: Ejecuta un Pod del SDK de Google Cloud
En el símbolo del sistema de Cloud Shell, inicia una sola instancia del contenedor de SDK de Google Cloud.
kubectl run -it --rm gcloud --image=google/cloud-sdk:latest --restart=Never -- bash
Este proceso tardará unos minutos en completarse.
Nota: Si ves un error que indique agotamiento del tiempo de espera, ejecuta el comando otra vez.
Ahora, deberías tener una shell Bash dentro del contenedor del Pod:
root@gcloud:/#
Es posible que el contenedor demore unos segundos en iniciarse y el símbolo del sistema, en aparecer. Si no ves el símbolo del sistema, presiona Intro.
Explora el extremo de metadatos de Compute
Ejecuta el siguiente comando para acceder al extremo de metadatos de Compute v1:
…snip…
Tu cliente no tiene permiso para obtener la dirección URL /computeMetadata/v1/instance/name de este servidor. Missing Metadata-Flavor:Google header.
…snip…
Observa que devuelve un mensaje de error que indica la necesidad de la presencia del encabezado HTTP personalizado.
Agrega el encabezado personalizado en la próxima ejecución y recupera el nombre de la instancia de Compute Engine que se ejecuta en este Pod:
gke-simplecluster-default-pool-b57a043a-6z5v
Nota: Si un encabezado HTTP personalizado no es necesario para acceder al extremo de metadatos de la instancia de Compute Engine, un atacante solo necesitaría una falla en la aplicación para engañar a una URL web y obtener las credenciales de usuario. Un ataque se hace más difícil cuando un encabezado HTTP personalizado es obligatorio, ya que el atacante necesitaría de una falla en la aplicación y, además, de un encabezado personalizado para lograr su objetivo.
Mantén disponible esta shell dentro del Pod para el próximo paso.
Si saliste del Pod por accidente, simplemente vuelve a ejecutar el siguiente comando:
kubectl run -it --rm gcloud --image=google/cloud-sdk:latest --restart=Never -- bash
Explora las credenciales de inicio del nodo de GKE
Desde el interior de la misma shell del Pod, ejecuta el siguiente comando para enumerar los atributos asociados con las instancias de Compute Engine subyacentes. Asegúrate de incluir la barra diagonal final:
Quizás, los datos más sensibles de la lista se encuentren en kube-env. Este elemento contiene distintas variables que kubelet usa como credenciales de inicio cuando se conecta con el nodo al clúster de GKE. Las variables CA_CERT, KUBELET_CERT y KUBELET_KEY contienen esta información y, por lo tanto, se consideran datos sensibles para quienes no son administradores del clúster.
Para ver los datos y variables potencialmente sensibles, ejecuta el siguiente comando:
Por lo tanto, en cualquiera de las siguientes situaciones:
Una falla que permita la SSRF en la aplicación de un Pod
Una falla en la aplicación o biblioteca que permita la RCE en un Pod
Un usuario interno con la capacidad de crear o ejecutar dentro de un Pod
Existe una alta probabilidad de que los datos sensibles de las credenciales de inicio de kubelet se vulneren y se roben a través del extremo de metadatos de Compute. En determinadas circunstancias, es posible aprovechar las credenciales de kubelet para derivar los privilegios a los de cluster-admin y, por lo tanto, tener control total sobre el clúster de GKE, incluso sobre todos los datos, las aplicaciones y el acceso a los nodos subyacentes.
Aprovecha los permisos asignados a la cuenta de servicio de este grupo de nodos
De forma predeterminada, los proyectos de Google Cloud que tienen la API de Compute habilitada tienen una cuenta de servicio predeterminada con el formato NNNNNNNNNN-compute@developer.gserviceaccount.com en el proyecto, además del rol de Editor asignado a ella. También, de forma predeterminada, los clústeres de GKE que se crearon sin especificar una cuenta de servicio utilizarán la cuenta de servicio predeterminada de Compute y la vincularán a todos los nodos trabajadores.
Ejecuta el siguiente comando curl para enumerar los permisos de OAuth asociados con la cuenta de servicio vinculada a la instancia de Compute Engine subyacente:
La combinación de los permisos de autenticación y de la cuenta de servicio determina a qué pueden acceder las aplicaciones de este nodo. La lista anterior enumera los permisos mínimos necesarios para la mayoría de los clústeres de GKE; no obstante, algunos casos de uso requieren permisos más amplios.
Advertencia: Si configuraste el alcance de la autenticación durante la creación del clúster para que incluya `https://www.googleapis.com/auth/cloud-platform`, cualquier API de Google Cloud tendría el permiso y solo los permisos de IAM asignados a la cuenta de servicio determinarían el acceso.
Además, si la cuenta de servicio predeterminada con el rol de IAM predeterminado de Editor está en uso, ningún Pod de este grupo de nodos tiene permisos de Editor para acceder al proyecto de Google Cloud donde se implementa el clúster de GKE. Como el rol de Editor de IAM tiene una gran variedad de permisos de lectura/escritura para interactuar con los recursos del proyecto (por ejemplo, las instancias de procesamiento, los buckets de Cloud Storage y los registros de GCR, entre otros), esto representa un riesgo importante para la seguridad.
Escribe el siguiente comando para salir de este Pod:
exit
Nota: Si no volviste a Cloud Shell, presiona ctrl + c
Tarea 3. Implementa un Pod que active el sistema de archivos del host
Una de las rutas más simples para "escapar" al host subyacente es activar el sistema de archivos del host en el sistema de archivos del Pod a través del uso de volumes y volumeMounts estándares de Kubernetes en la especificación de un Pod.
Como demostración, ejecuta el siguiente comando para crear un Pod que active el sistema de archivos del host subyacente / en la carpeta llamada /rootfs, que se encuentra dentro del contenedor:
Ejecuta kubectl get pod y vuelve a ejecutarlo hasta que esté en el estado “Running”:
kubectl get pod
(Resultado)
NAME READY STATUS RESTARTS AGE
hostpath 1/1 Running 0 30s
Haz clic en Revisar mi progreso para verificar el objetivo. Implementar un Pod que active el sistema de archivos del host
Tarea 4: Explora y vulnera el host subyacente
Ejecuta el siguiente comando para obtener una shell dentro del Pod que acabas de crear:
kubectl exec -it hostpath -- bash
Cambia el sistema de archivos raíz de la shell del Pod para que apunte al del host subyacente:
chroot /rootfs /bin/bash
Con esos comandos simples, el Pod es eficazmente una shell root en el nodo. Ahora puedes hacer lo siguiente:
ejecutar el comando estándar de Docker con los permisos completos
docker ps
enumerar imágenes de Docker
docker images
ejecutar un contenedor con privilegios de tu elección a través de docker run
docker run --privileged <imagename>:<imageversion>
examinar los Secrets de Kubernetes activados
mount | grep volumes | awk '{print $3}' | xargs ls
ejecutar a través de exec en cualquier contenedor activo (incluso en otro Pod ubicado en otro espacio de nombres)
docker exec -it <docker container ID> sh
Casi todas las operaciones que puede realizar el usuario root están disponibles para esta shell del Pod. Esto incluye mecanismos de persistencia, como agregar usuarios/claves SSH, ejecutar contenedores de Docker con privilegios en el host sin que se vea en Kubernetes y mucho más.
Si quieres salir de la shell del Pod, ejecuta exit dos veces: una vez para abandonar el chroot y otra vez para abandonar la shell del Pod.
exit
exit
Nota: Si no volviste a Cloud Shell, presiona ctrl + c.
Ahora, puedes borrar el Pod hostpath:
kubectl delete pod hostpath
Comprende los controles disponibles
Los próximos pasos de esta demostración incluirán las siguientes acciones:
Inhabilitar el extremo de la API de metadatos de Compute Engine heredado: cuando se especifique una clave y un valor de metadatos personalizados, el extremo de metadatos v1beta1 ya no estará disponible desde la instancia.
Habilitar el ocultamiento de metadatos: Cuando se realice una configuración adicional durante la creación de un clúster o un grupo de nodos, se instalará un proxy ligero en cada nodo que enrutará todas las solicitudes a la API de metadatos y prohibirá el acceso a los extremos sensibles.
Habilitar y usar la admisión de seguridad de Pods: Habilita el controlador de admisión de seguridad de Pods (PSA) en tu clúster de GKE. Esto te permite aplicar estándares de seguridad de pods que mejoran la postura de seguridad de tu clúster.
Tarea 5: Implementa un segundo grupo de nodos
Ahora, crearás un segundo grupo de nodos que incluya dos parámetros de configuración adicionales para que puedas experimentar los extremos de metadatos con las protecciones vigentes y sin ellas. Los Pods programados en el grupo de nodos genérico no tendrán protección, mientras que los Pods programados en el segundo grupo de nodos tendrán la protección habilitada.
Nota: Los extremos heredados quedaron obsoletos el 30 de septiembre de 2020. En las versiones de GKE 1.12 y posteriores, la configuración `--metadata=disable-legacy-endpoints=true` estará habilitada automáticamente. El siguiente comando lo define de manera explícita para mayor claridad.
Haz clic en Revisar mi progreso para verificar el objetivo. Implementar un segundo grupo de nodos
Tarea 6: Ejecuta un Pod del SDK de Google Cloud
En Cloud Shell, inicia una sola instancia del contenedor del SDK de Google Cloud que se ejecutará solo en el segundo grupo de nodos con las protecciones habilitadas y no lo hará como el usuario raíz:
kubectl run -it --rm gcloud --image=google/cloud-sdk:latest --restart=Never --overrides='{ "apiVersion": "v1", "spec": { "securityContext": { "runAsUser": 65534, "fsGroup": 65534 }, "nodeSelector": { "cloud.google.com/gke-nodepool": "second-pool" } } }' -- bash
Nota: Si se produce un error de tiempo de espera agotado, ejecuta el comando otra vez.
Ahora, deberías tener una shell Bash dentro del contenedor del Pod que se ejecuta en el segundo grupo de nodos llamado second-pool. Deberías ver lo siguiente:
nobody@gcloud:/$
El contenedor puede tardar algunos segundos en iniciar y el símbolo del sistema, en abrir.
Si no ves un símbolo del sistema, presiona Intro.
Explora los distintos extremos bloqueados
Cuando la configuración del segundo grupo de nodos está establecida como --workload-metadata-from-node=SECURE, el siguiente comando destinado a recuperar el archivo con datos sensibles, kube-env, fallará:
clusterrolebinding.rbac.authorization.k8s.io/clusteradmin created
Ahora, aplicarás un estándar de seguridad de pod. Elige el estándar de seguridad más adecuado para tu espacio de nombres "Predeterminado". El perfil "Restringido" ofrece una mayor seguridad:
A continuación, crearás un ClusterRole. Si deseas controlar quién puede modificar los niveles de admisión de seguridad de Pods en los espacios de nombres, crea un ClusterRole llamado pod-security-manager:
A continuación, crearás un RoleBinding. Para restringir quién puede cambiar las etiquetas de espacio de nombres relacionadas con la Admisión de seguridad de Pods, crea un objeto RoleBinding en el espacio de nombres "Predeterminado":
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-security-modifier
namespace: default
subjects:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:authenticated
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pod-security-manager
EOF
Nota: Para la aplicación de seguridad de pods altamente personalizada y dinámica, considera herramientas como OPA Gatekeeper o Kyverno.
Haz clic en Revisar mi progreso para verificar el objetivo. Implementar los objetos de PodSecurityPolicy
Tarea 8: Implementa un Pod bloqueado que active el sistema de archivos del host
Debido a que se le otorgó permisos de administrador de clúster a la cuenta que implementó el clúster de GKE en el paso anterior, se debe crear otra cuenta de "usuario" para que interactúe con el clúster y valide la aplicación de la PodSecurityPolicy.
Para ello, ejecuta el siguiente comando:
gcloud iam service-accounts create demo-developer
(Resultado)
Cuenta de servicio creada [demo-developer].
Luego, ejecuta los siguientes comandos para otorgar estos permisos a la cuenta de servicio (la capacidad de interactuar con el clúster y crear Pods):
Ahora, intenta crear otro Pod que active el sistema de archivos del host subyacente / en la carpeta llamada /rootfs, que se encuentra dentro del contenedor:
Este resultado valida que está bloqueado por el estándar de seguridad del Pod:
Error from server (Forbidden): error when creating "STDIN": pods "hostpath" is forbidden: violates PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "hostpath" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "hostpath" must set securityContext.capabilities.drop=["ALL"]), restricted volume types (volume "rootfs" uses restricted volume type "hostPath"), runAsNonRoot != true (pod or container "hostpath" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "hostpath" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
Implementa otro Pod que cumpla con los criterios de restrictive-psp:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: hostpath
spec:
securityContext:
runAsNonRoot: true # Asegura que se utilice un usuario que no sea root
runAsUser: 1000
fsGroup: 2000
seccompProfile: # Agrega un perfil seccomp
type: RuntimeDefault
containers:
- name: hostpath
image: google/cloud-sdk:latest
command: ["/bin/bash"]
args: ["-c", "tail -f /dev/null"]
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
EOF
(Resultado)
pod/hostpath created
Haz clic en Revisar mi progreso para verificar el objetivo. Implementar un Pod bloqueado que active el sistema de archivos del host
¡Felicitaciones!
En este lab, configuraste un clúster de Kubernetes predeterminado en Google Kubernetes Engine. Después, sondeaste y aprovechaste los accesos disponibles a tu Pod, endureciste el clúster y validaste que esas acciones maliciosas ya no pudieran realizarse.
Próximos pasos y más información
IMPORTANTE: Si bien este lab explica varios problemas de seguridad de forma detallada, debes considerar otras áreas en tu entorno. Consulta la guía para el endurecimiento de la seguridad de clúster para obtener más información.
Recibe la formación que necesitas para aprovechar al máximo las tecnologías de Google Cloud. Nuestras clases incluyen habilidades técnicas y recomendaciones para ayudarte a avanzar rápidamente y a seguir aprendiendo. Para que puedas realizar nuestros cursos cuando más te convenga, ofrecemos distintos tipos de capacitación de nivel básico a avanzado: a pedido, presenciales y virtuales. Las certificaciones te ayudan a validar y demostrar tus habilidades y tu conocimiento técnico respecto a las tecnologías de Google Cloud.
Última actualización del manual: 14 de febrero de 2024
Prueba más reciente del lab: 14 de febrero de 2024
Copyright 2025 Google LLC. All rights reserved. Google y el logotipo de Google son marcas de Google LLC. Los demás nombres de productos y empresas pueden ser marcas de las respectivas empresas a las que estén asociados.
Los labs crean un proyecto de Google Cloud y recursos por un tiempo determinado
.
Los labs tienen un límite de tiempo y no tienen la función de pausa. Si finalizas el lab, deberás reiniciarlo desde el principio.
En la parte superior izquierda de la pantalla, haz clic en Comenzar lab para empezar
Usa la navegación privada
Copia el nombre de usuario y la contraseña proporcionados para el lab
Haz clic en Abrir la consola en modo privado
Accede a la consola
Accede con tus credenciales del lab. Si usas otras credenciales, se generarán errores o se incurrirá en cargos.
Acepta las condiciones y omite la página de recursos de recuperación
No hagas clic en Finalizar lab, a menos que lo hayas terminado o quieras reiniciarlo, ya que se borrará tu trabajo y se quitará el proyecto
Este contenido no está disponible en este momento
Te enviaremos una notificación por correo electrónico cuando esté disponible
¡Genial!
Nos comunicaremos contigo por correo electrónico si está disponible
Un lab a la vez
Confirma para finalizar todos los labs existentes y comenzar este
Usa la navegación privada para ejecutar el lab
Usa una ventana de navegación privada o de Incógnito para ejecutar el lab. Así
evitarás cualquier conflicto entre tu cuenta personal y la cuenta
de estudiante, lo que podría generar cargos adicionales en tu cuenta personal.
Este lab expone algunas de las preocupaciones de seguridad de la configuración predeterminada de un clúster de GKE y las medidas de endurecimiento correspondientes para prevenir las múltiples rutas de escape de Pods y la elevación de privilegios del clúster.
Duración:
0 min de configuración
·
Acceso por 90 min
·
90 min para completar