Encripta secretos en la capa de la aplicación

En esta página, se explica cómo encriptar secretos de Kubernetes en la capa de la aplicación mediante una clave que administras en Cloud Key Management Service (Cloud KMS). Esta característica se basa en la funcionalidad de Cloud KMS, por lo que deberías familiarizarte con la rotación de claves y la encriptación de sobre.

Descripción general

De forma predeterminada, GKE encripta el contenido del cliente almacenado en reposo, incluidos los secretos. GKE controla y administra esta encriptación predeterminada sin que debas realizar ninguna acción adicional.

La encriptación de secretos en la capa de la aplicación proporciona más seguridad para los datos sensibles, como los secretos, que se almacenan en etcd. Con esta función, puedes usar una clave administrada con Cloud KMS para encriptar datos en la capa de la aplicación. Esto protege contra atacantes que obtienen acceso a una copia sin conexión de etcd.

Para usar la encriptación de secretos de la capa de la aplicación, primero debes crear una clave de Cloud KMS y otorgarle a la cuenta de servicio de GKE acceso a la clave. La clave debe estar en la misma ubicación que el clúster para disminuir la latencia y evitar casos en los que los recursos dependen de los servicios distribuidos en varios dominios con fallas. Luego, puedes habilitar la función en un clúster nuevo o existente cuando especificas la clave que desearías usar.

Encriptación de sobre

Kubernetes ofrece encriptación de sobre de los secretos con un proveedor de KMS, lo que significa que se usa una clave local, que se suele llamar clave de encriptación de datos (DEK), para encriptar los secretos. La DEK está encriptada con otra clave llamada clave de encriptación de claves (KEK). Kubernetes no almacena la KEK.

La encriptación de sobre tiene dos beneficios principales:

  • La KEK se puede rotar sin necesidad de volver a encriptar todos los secretos. Esto significa que puedes seguir más fácilmente la práctica recomendada de la rotación normal de claves, sin tener un impacto significativo en el rendimiento.

  • Los secretos que se almacenan en Kubernetes pueden basarse en una raíz de confianza externa. Esto significa que puedes usar una raíz de confianza central para todos tus secretos, por ejemplo, un módulo de seguridad de hardware, y que un adversario que acceda a tus contenedores fuera de línea no pueda obtener tus secretos.

Con la encriptación de secretos de la capa de la aplicación en GKE, tus secretos se encriptan localmente con el proveedor AES-CBC y las DEK locales. Las DEK se encriptan con una KEK que administras en Cloud KMS.

Para obtener más información sobre la encriptación de sobre, consulta Encriptación de sobre.

¿Qué sucede cuando creas un secreto?

Cuando creas un secreto nuevo, esto es lo que sucede:

  1. El servidor de la API de Kubernetes genera una DEK única para el secreto mediante el uso de un generador de números al azar.

  2. El servidor de la API de Kubernetes usa la DEK localmente para encriptar el secreto.

  3. El complemento para KMS envía la DEK a Cloud KMS con el objetivo de que se realice la encriptación. El complemento de KMS usa la cuenta de servicio de GKE del proyecto para autenticarse en Cloud KMS.

  4. Cloud KMS encripta la DEK con la KEK y la envía de vuelta al complemento para KMS.

  5. El servidor de la API de Kubernetes guarda el secreto y la DEK encriptados. La DEK sin formato no se guarda en el disco.

  6. El servidor de la API de Kubernetes crea una entrada de caché que asigna la DEK encriptada a la DEK de texto simple. Esto le permite desencriptar el Secret sin usar Cloud KMS.

Cuando un cliente solicita un Secret del servidor de la API de Kubernetes, sucede lo siguiente:

  1. El servidor de la API de Kubernetes recupera el Secret encriptado y la DEK encriptada.

  2. El servidor de la API de Kubernetes verifica la caché de una entrada de asignación existente y desencripta el secreto sin usar Cloud KMS.

  3. Si no se encuentra una entrada de caché, el complemento KMS envía la DEK a Cloud KMS para su desencriptación con la KEK. La DEK desencriptada se usa para desencriptar el Secret.

  4. El servidor de la API de Kubernetes muestra el secreto desencriptado al cliente.

¿Qué sucede cuando borras una clave?

Cuando destruyes una KEK en Cloud KMS que se usó para encriptar un Secret en GKE, el secreto ya no está disponible, a menos que actualices el clúster para usar primero una KEK nueva.

Si planeas destruir una versión anterior de KEK después de una rotación de claves, primero usa la versión de KEK nueva para volver a encriptar el Secret.

A menos que se use una proyección de volumen de token de cuenta de servicio, las cuentas de servicio que usan tus cargas de trabajo en GKE también usan Secrets y, si se destruye una clave, no estarán disponibles. La imposibilidad de acceder a ellas significa que las cargas de trabajo fallarán.

Se aplican las siguientes excepciones:

  • Los pods con acceso existente a objetos Secrets como volúmenes activados o variables de entorno conservan el acceso.

  • El servidor de la API de Kubernetes aún puede usar entradas de asignación de DEK en caché para desencriptar un Secret después de destruir la KEK. Esto permite que los pods reiniciados o reprogramados accedan al Secret, a menos que ocurra lo siguiente:

    • Se reinicia el plano de control del clúster.
    • Se reinicia el pod del servidor de la API de Kubernetes.
    • La entrada de asignación de DEK para el Secret no está en la caché del servidor de la API de Kubernetes.

Antes de destruir una KEK, comprueba si la está usando tu clúster. También puedes crear una política de alertas para la destrucción de claves en Cloud KMS.

Antes de comenzar

  • Para realizar los ejercicios de este tema, necesitas dos proyectos de Google Cloud:

    • Proyecto clave: aquí es donde creas una KEK.

    • Proyecto de clúster: Aquí crearás un clúster que habilita la encriptación de secretos en la capa de la aplicación.

  • En tu proyecto clave, asegúrate de que habilitaste la API de Cloud KMS.

    Habilitar la API de Cloud KMS

  • En el proyecto de clave, el usuario que crea el llavero de claves y la clave necesita los siguientes permisos de IAM:

    • cloudkms.keyRings.getIamPolicy
    • cloudkms.keyRings.setIamPolicy

    Estos permisos (y muchos otros) se otorgan a la función predefinida roles/cloudkms.admin de administración de identidades y accesos. Puedes obtener más detalles en la sección Otorga permisos para administrar claves de la documentación de Cloud KMS.

  • En tu proyecto de clúster, asegúrate de que habilitaste la API de Google Kubernetes Engine.

    Habilitar la API de Google Kubernetes Engine

  • Asegúrate de que instalaste el SDK de Cloud.

  • Actualiza gcloud a la versión más reciente:

    gcloud components update

Crea una clave de Cloud KMS

Cuando crees el llavero de claves, especifica una ubicación que coincida con la ubicación de tu clúster de GKE:

  • Un clúster zonal debe usar un llavero de claves desde la ubicación de un superconjunto. Por ejemplo, un clúster ubicado en la zona us-central1-a solo puede usar una clave ubicada en la región us-central1.

  • Un clúster regional debe usar un llavero de claves de la misma ubicación. Por ejemplo, un clúster ubicado en la región asia-northeast1 debe protegerse con un llavero de claves de la región asia-northeast1.

  • La región global de Cloud KMS no es compatible con GKE.

Puedes usar la herramienta de gcloud o Google Cloud Console.

Console

Crea un llavero de claves en el proyecto de clave:

  1. Ve a la página Claves criptográficas en Cloud Console.

    Ir a la página Claves criptográficas

  2. Haz clic en Crear llavero de claves.

  3. En el campo Nombre del llavero de claves, ingresa el nombre de tu llavero de claves.

  4. En la lista desplegable Ubicación, selecciona la ubicación de tu clúster de Kubernetes.

  5. Haga clic en Crear.

A continuación, crea una clave:

  1. Ve a la página Claves criptográficas en Cloud Console.

    Ir a la página Claves criptográficas

  2. Haz clic en el nombre del llavero de claves para el cual crearás una clave.

  3. Haz clic en Crear clave.

  4. Ingresa el nombre en el campo Nombre de la clave (Key name).

  5. Acepta los valores predeterminados de Período de rotación y A partir de, o establece un período de rotación de clave y una fecha de inicio si deseas usar valores diferentes.

  6. Opcionalmente, si deseas agregar etiquetas a tu clave, haz clic en Agregar etiqueta en el campo Etiquetas.

  7. Haga clic en Crear.

gcloud

En tu proyecto clave, crea un llavero de claves:

gcloud kms keyrings create RING_NAME \
    --location LOCATION \
    --project KEY_PROJECT_ID

Reemplaza lo siguiente:

  • RING_NAME: es el nombre que eliges para el llavero de claves.
  • LOCATION: la ubicación en la que deseas crear el llavero de claves
  • KEY_PROJECT_ID: Es el ID del proyecto de claves.

Crea una clave:

gcloud kms keys create KEY_NAME \
    --location LOCATION \
    --keyring RING_NAME \
    --purpose encryption \
    --project KEY_PROJECT_ID

Reemplaza lo siguiente:

  • KEY_NAME: es el nombre que eliges para tu clave.
  • LOCATION: la ubicación de Cloud KMS donde creaste tu llavero de claves.
  • RING_NAME: Es el nombre del llavero de claves.
  • KEY_PROJECT_ID: Es el ID del proyecto de claves.

Concede permisos para usar la clave

La cuenta de servicio de GKE en tu proyecto de clúster tiene este nombre:

service-CLUSTER_PROJECT_ID@container-engine-robot.iam.gserviceaccount.com

Reemplaza CLUSTER_PROJECT_ID por el ID del proyecto del clúster.

Para otorgar acceso a la cuenta de servicio, puedes usar Google Cloud Console o el comando de gcloud.

Console

Otorga a tu cuenta de servicio de GKE la función Encriptador/Desencriptador de CryptoKeys de Cloud KMS:

  1. Abre el navegador de claves de Cloud Key Management Service en Google Cloud Console.
    Abrir el navegador de claves de Cloud KMS
  2. Haz clic en el nombre del llavero de claves que contiene la clave que desees.

  3. Selecciona la casilla de verificación de la clave que deseas.

    La pestaña Permisos en el panel de la ventana derecha estará disponible.

  4. En el cuadro de diálogo Agregar miembros, especifica la dirección de correo electrónico de la cuenta de servicio de GKE a la que le estás otorgando acceso.

  5. En el menú desplegable Seleccionar una función, selecciona Encriptador/desencriptador de clave criptográfica de Cloud KMS.

  6. Haz clic en Guardar.

gcloud

Otorga a tu cuenta de servicio de GKE la función Encriptador/Desencriptador de CryptoKeys de Cloud KMS:

gcloud kms keys add-iam-policy-binding KEY_NAME \
  --location LOCATION \
  --keyring RING_NAME \
  --member serviceAccount:SERVICE_ACCOUNT_NAME \
  --role roles/cloudkms.cryptoKeyEncrypterDecrypter \
  --project KEY_PROJECT_ID

Reemplaza lo siguiente:

  • KEY_NAME: Es el nombre de la clave.
  • LOCATION: la ubicación de Cloud KMS donde creaste tu llavero de claves.
  • RING_NAME: Es el nombre del llavero de claves.
  • SERVICE_ACCOUNT_NAME: Es el nombre de la cuenta de servicio.
  • KEY_PROJECT_ID: Es el ID del proyecto de claves.

Habilita la encriptación de secretos de la capa de la aplicación

En un clúster nuevo

Puedes crear un clúster nuevo mediante Google Cloud Console o la herramienta de gcloud.

Console

  1. Ve al menú de Google Kubernetes Engine en Cloud Console.

    Ir al menú Google Kubernetes Engine

  2. Haz clic en Crear.

  3. Configura tu clúster como desees.

  4. En el panel de navegación, en Clúster, haz clic en Seguridad.

  5. Selecciona Habilitar la encriptación de secretos en la capa de la aplicación y elige la clave de encriptación de base de datos que creaste en el paso Crea una clave de Cloud KMS.

  6. Haga clic en Crear.

gcloud

Para crear un clúster compatible con la encriptación de secretos de la capa de la aplicación, especifica un valor para el parámetro --database-encryption-key en tu comando de creación.

gcloud container clusters create CLUSTER_NAME \
  --cluster-version=latest \
  --zone ZONE \
  --database-encryption-key projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME \
  --project CLUSTER_PROJECT_ID

Reemplaza lo siguiente:

  • CLUSTER_NAME: es el nombre que eliges para el clúster.
  • ZONE: Es la zona de procesamiento en la que deseas crear el clúster.
  • KEY_PROJECT_ID: Es el ID del proyecto de claves.
  • LOCATION: la ubicación de Cloud KMS donde creaste tu llavero de claves.
  • RING_NAME: Es el nombre del llavero de claves.
  • KEY_NAME: Es el nombre de la clave.
  • CLUSTER_PROJECT_ID: El ID del proyecto de tu clúster.

En un clúster existente

Puedes usar la herramienta de gcloud o Google Cloud Console a fin de actualizar un clúster existente para usar la encriptación de secretos de la capa de la aplicación.

Console

Para actualizar un clúster a fin de admitir la encriptación de secretos de la capa de la aplicación, haz lo siguiente:

  1. Ve al menú de Google Kubernetes Engine en Cloud Console.

    Ir al menú Google Kubernetes Engine

  2. Haz clic en el nombre del clúster que deseas modificar.

  3. En Seguridad, en el campo Encriptación de secretos de la capa de la aplicación, haz clic en Editar encriptación de secretos en la capa de la aplicación.

  4. Selecciona la casilla de verificación Habilitar la encriptación de secretos en la capa de la aplicación y elige la clave de encriptación de base de datos que creaste en el paso Crea una clave de Cloud KMS.

  5. Haz clic en Guardar cambios.

gcloud

Para habilitar las encriptaciones de secretos de la capa de la aplicación en un clúster existente, ejecuta el siguiente comando:

gcloud container clusters update CLUSTER_NAME \
  --zone ZONE \
  --database-encryption-key projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME \
  --project CLUSTER_PROJECT_ID

Reemplaza lo siguiente:

  • CLUSTER_NAME: El nombre de tu clúster.
  • ZONE: Es la zona de procesamiento del clúster.
  • KEY_PROJECT_ID: Es el ID del proyecto de claves.
  • LOCATION: la ubicación de Cloud KMS donde creaste tu llavero de claves.
  • RING_NAME: Es el nombre del llavero de claves.
  • KEY_NAME: Es el nombre de la clave.
  • CLUSTER_PROJECT_ID: El ID del proyecto de tu clúster.

Actualiza una clave de Cloud KMS

Console

Para actualizar un clúster a fin de usar una clave de Cloud KMS nueva, sigue estos pasos:

  1. Dirígete al menú de Google Kubernetes Engine en Cloud Console.

    Ir al menú Google Kubernetes Engine

  2. Haz clic en el nombre del clúster que deseas modificar.

  3. En Seguridad, en el campo Encriptación de secretos de la capa de la aplicación, haz clic en Editar encriptación de secretos en la capa de la aplicación.

  4. Selecciona la clave de encriptación nueva que deseas usar.

  5. Haz clic en Guardar cambios.

gcloud

Actualiza tu clúster existente para usar una clave de Cloud KMS nueva:

gcloud container clusters update CLUSTER_NAME \
  --zone ZONE \
  --database-encryption-key projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME \
  --project CLUSTER_PROJECT_ID

Reemplaza lo siguiente:

  • CLUSTER_NAME: El nombre de tu clúster.
  • ZONE: Es la zona de procesamiento del clúster.
  • KEY_PROJECT_ID: Es el ID del proyecto de claves.
  • LOCATION: la ubicación de Cloud KMS donde creaste tu llavero de claves.
  • RING_NAME: Es el nombre del llavero de claves.
  • KEY_NAME: Es el nombre de la clave.
  • CLUSTER_PROJECT_ID: El ID del proyecto de tu clúster.

Inhabilita la encriptación de secretos de la capa de la aplicación

Puedes usar la herramienta de gcloud o Google Cloud Console.

Console

  1. Dirígete al menú de Google Kubernetes Engine en Cloud Console.

    Ir al menú Google Kubernetes Engine

  2. Haz clic en el nombre del clúster que deseas modificar.

  3. En Seguridad, en el campo Encriptación de secretos de la capa de la aplicación, haz clic en Editar encriptación de secretos en la capa de la aplicación.

  4. Desactiva la casilla de verificación Habilitar la encriptación de secretos en la capa de la aplicación.

  5. Haz clic en Guardar cambios.

gcloud

Para inhabilitar la encriptación de secretos de la capa de la aplicación, ejecuta el siguiente comando:

gcloud container clusters update CLUSTER_NAME \
  --zone ZONE \
  --disable-database-encryption \
  --project CLUSTER_PROJECT_ID

Reemplaza lo siguiente:

Verifica que la encriptación de secretos de la capa de la aplicación esté habilitada

Puedes comprobar si un clúster usa la encriptación de secretos de la capa de la aplicación mediante Google Cloud Console o el comando de gcloud.

Console

  1. Dirígete al menú de Google Kubernetes Engine en Cloud Console.

    Ir al menú Google Kubernetes Engine

  2. Haz clic en el nombre del clúster que deseas modificar.

  3. En Seguridad, verifica que el campo Encriptación de secretos de la capa de la aplicación muestre Enabled y enumere la clave correcta.

gcloud

Verifica si un clúster está utilizando la encriptación de secretos de la capa de la aplicación:

gcloud container clusters describe CLUSTER_NAME \
  --zone ZONE \
  --format 'value(databaseEncryption)' \
  --project CLUSTER_PROJECT_ID

Reemplaza lo siguiente:

Si el clúster usa la encriptación de secretos de la capa de aplicación, la respuesta contiene EncryptionConfig:

keyName=projects/project/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME;state=ENCRYPTED

Limitaciones

Cantidad de Secrets

GKE admite hasta 10,000 Secrets por clúster para la encriptación de Secrets en la capa de la aplicación. Si almacenas más de 10,000 Secrets, tu clúster puede quedar inestable al momento de la actualización, lo que podría causar una interrupción potencial para tus cargas de trabajo.

Ubicación de la clave

Debes seleccionar una clave en la misma región que el clúster en uso. Por ejemplo, un clúster zonal en us-central1-a solo puede usar una clave en la región us-central1. Para los clústeres regionales, las claves deben estar en la misma ubicación a fin de disminuir la latencia y evitar que los recursos dependan de los servicios distribuidos en varios dominios con fallas.

Rotación de claves

Cuando realizas una rotación de claves, tus Secrets existentes permanecen encriptados con la versión de clave de encriptación de claves anterior (KEK). Para garantizar que una versión KEK más nueva encapsula un Secret, vuelve a encriptar el Secret después de la rotación de claves.

Por ejemplo, crea y almacena un secreto, Secret1. Está encriptado con DEK1, que, a su vez, está unida a KEKv1.

Después de que la KEK rota, vuelve a encriptar Secret1 para que esté unido por DEK2, que, a su vez, se une con KEKv2, la KEK rotada.

Vuelve a encriptar tus Secrets

No hay forma de forzar la nueva encriptación automática de tus Secrets. Si lo deseas, puede rotar manualmente tu KEK si creas una nueva versión clave:

gcloud kms keys versions create --location LOCATION \
   --keyring RING_NAME \
   --key KEY_NAME \
   --primary \
   --project KEY_PROJECT_ID

Reemplaza lo siguiente:

  • LOCATION: la ubicación de Cloud KMS donde creaste tu llavero de claves.
  • RING_NAME: Es el nombre del llavero de claves.
  • KEY_NAME: Es el nombre de la clave.
  • KEY_PROJECT_ID: Es el ID del proyecto de claves.

Luego, obligas a GKE a volver a encriptar tocando cada secreto:

kubectl get secrets --all-namespaces -o json | kubectl annotate --overwrite -f - encryption-key-rotation-time="TIME"

Reemplaza TIME por una string que indique cuándo ocurre la rotación (por ejemplo, 20200909-090909).

EncryptionConfig

En este momento, solo las claves de Cloud KMS son compatibles con GKE. No puedes utilizar otro proveedor de KMS de Kubernetes ni otro proveedor de encriptación.

¿Qué sigue?