Antes de que una aplicación envíe información sensible a una instancia de máquina virtual (VM), la aplicación puede verificar la identidad de la instancia mediante tokens de identidad de instancia que firma Google. Cada instancia tiene un JSON Web Token (JWT) único que incluye detalles sobre la instancia y la firma RS256 de Google. Tus aplicaciones pueden verificar la firma con los certificados públicos de Oauth2 de Google para confirmar la identidad de la instancia con la que establecieron una conexión.
Compute Engine genera tokens de instancia firmados solo cuando una instancia los solicita a los metadatos de la instancia. Las instancias solo pueden acceder a su propio token único y no a los tokens para ninguna otra instancia.
Es posible que desees verificar las identidades de tus instancias en las siguientes situaciones:
- Cuando inicias una instancia por primera vez, es posible que tus aplicaciones necesiten asegurarse de que la instancia a la que se conectaron tenga una identidad válida antes de transmitir información sensible a la instancia.
- Cuando tus políticas requieren que almacenes credenciales fuera del entorno de Compute Engine y envías esas credenciales regularmente a tus instancias para uso temporal. Tus aplicaciones pueden confirmar las identidades de las instancias cada vez que necesitan transmitir credenciales.
Los métodos de autenticación de instancias de Google tienen los siguientes beneficios:
- Compute Engine crea un token único cada vez que una instancia lo solicita, y cada token vence en una hora. Puedes configurar tus aplicaciones para que acepten el token de identidad de una instancia solo una vez, lo que reduce el riesgo de que el token pueda ser reutilizado por un sistema no autorizado.
- Los tokens de metadatos firmados usan el estándar abierto de la industria RFC 7519 y la capa de identidad OpenID Connect 1.0, por lo que las herramientas y bibliotecas existentes funcionarán a la perfección con los tokens de identidad.
Antes de comenzar
- Comprende cómo recuperar los valores de metadatos de la instancia.
- Comprende los conceptos básicos de JSON Web Tokens para saber cómo usarlos en tus aplicaciones.
- Comprende cómo crear y habilitar cuentas de servicio en tus instancias. Tus instancias deben tener una cuenta de servicio asociada a ellas para que puedan recuperar sus tokens de identidad. La cuenta de servicio no requiere ningún permiso de IAM para recuperar estos tokens de identidad.
-
Si aún no lo hiciste, configura la autenticación.
La autenticación es el proceso mediante el cual se verifica tu identidad para acceder a los servicios y las API de Google Cloud.
Para ejecutar código o muestras desde un entorno de desarrollo local, puedes autenticarte en Compute Engine seleccionando una de las siguientes opciones:
Para usar las muestras de Python de esta página en un entorno de desarrollo local, instala e inicializa gcloud CLI y, luego, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
If you're using a local shell, then create local authentication credentials for your user account:
gcloud auth application-default login
You don't need to do this if you're using Cloud Shell.
Para obtener más información, consulta Set up authentication for a local development environment.
Verifica la identidad de una instancia
En algunas situaciones, tus aplicaciones deben verificar la identidad de una instancia que se ejecuta en Compute Engine antes de transmitir datos sensibles a esa instancia. En un ejemplo común, hay un sistema que se ejecuta fuera de Compute Engine denominado “Host1” y una instancia de Compute Engine denominada “VM1”. VM1 puede conectarse a Host1 y validar la identidad de esa instancia con el siguiente proceso:
VM1 establece una conexión segura con Host1 a través de un protocolo de conexión segura de tu elección, como HTTPS.
VM1 solicita el token único de identidad al servidor de metadatos y especifica el público del token. En este ejemplo, el valor del público es el URI para Host1. La solicitud al servidor de metadatos incluye el URI del público para que Host1 pueda verificar el valor más adelante durante el paso de verificación del token.
Google genera un nuevo token único de identidad de instancia en formato JWT y se lo proporciona a VM1. La carga útil del token incluye varios detalles sobre la instancia y también incluye el URI del público. Consulta Contenido del token para obtener una descripción completa del contenido del token.
VM1 envía el token de identidad a Host1 a través de la conexión segura existente.
Host1 decodifica el token de identidad para obtener el encabezado del token y los valores de carga útil.
Host1 verifica que Google haya firmado el token mediante la revisión del valor de la audiencia y la verificación de la firma del certificado con el certificado público de Google.
Si el token es válido, Host1 continúa con la transmisión y finaliza la conexión cuando haya terminado. Host1 y cualquier otro sistema deben solicitar un token nuevo para cualquier conexión posterior a VM1.
Obtén el token de identidad de instancia
Cuando tu instancia de máquina virtual recibe una solicitud para proporcionar su token de identidad, la instancia solicita ese token al servidor de metadatos mediante el proceso normal para obtener metadatos de instancia. Por ejemplo, puedes usar uno de los siguientes métodos:
cURL
Crea una solicitud curl
que incluya un valor en el parámetro audience
.
Si lo deseas, puedes incluir el parámetro format
para especificar si quieres incluir o no los detalles del proyecto y la instancia en la carga útil. Si usas el formato full
, puedes incluir el parámetro licenses
para especificar si deseas o no incluir códigos de licencia en la carga útil.
curl -H "Metadata-Flavor: Google" \ 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=AUDIENCE&format=FORMAT&licenses=LICENSES'
Reemplaza lo siguiente:
AUDIENCE
: el URI único acordado por la instancia y por el sistema que verifica la identidad de la instancia. Por ejemplo, el público podría ser una URL para la conexión entre los dos sistemas.FORMAT
: el parámetro opcional que especifica si los detalles del proyecto y la instancia se incluyen en la carga útil. Especificafull
para incluir esta información en la carga útil ostandard
si deseas omitir la información de la carga útil. El valor predeterminado esstandard
. Para obtener más información, consulta la sección sobre el formato de token de identidad.LICENSES
: un parámetro opcional que especifica si los códigos de licencia de las imágenes asociadas con esta instancia se incluyen en la carga útil. EspecificaTRUE
con el fin de incluir esta información en la carga útil oFALSE
para omitirla. El valor predeterminado esFALSE
. No tiene efecto, a menos queformat
estéfull
El servidor de metadatos responde a esta solicitud con un JSON Web Token firmado con el algoritmo RS256. El token incluye una firma de Google y, también, información adicional en la carga útil. Puedes enviar este token a otros sistemas y aplicaciones para que puedan verificar el token y confirmar la identidad de tu instancia.
Python
Puedes enviar una solicitud simple desde tu instancia al servidor de metadatos mediante los métodos en la biblioteca requests
de Python. El siguiente ejemplo solicita y, luego, imprime un token de identidad de instancia. El token es exclusivo de la instancia que realiza esta solicitud.
El servidor de metadatos responde a esta solicitud con un JSON Web Token firmado con el algoritmo RS256. El token incluye una firma de Google y, también, información adicional en la carga útil. Puedes enviar este token a otros sistemas y aplicaciones para que puedan verificar el token y confirmar la identidad de tu instancia.
Verifica el token
Una vez que tu aplicación reciba un token de identidad de instancia de una instancia de Compute Engine, puedes verificar el token mediante el siguiente proceso:
Recibe el token de la instancia de la máquina virtual, decodifica el token con un decodificador RS256 JWT y lee el contenido del encabezado para obtener el valor
kid
.Verifica que el token esté firmado mediante la comparación del token con el certificado público de Google. Cada certificado público tiene un valor
.kid
que corresponde al valorkid
en el encabezado del token.Si el token es válido, compara el contenido de la carga útil con los valores esperados. Si la carga útil del token incluye detalles sobre la instancia y el proyecto, tu aplicación puede verificar los valores de
instance_id
,project_id
yzone
. Esos valores son una tupla global única que confirma que tu aplicación se está comunicando con la instancia correcta en el proyecto deseado.
Puedes decodificar y verificar el token con cualquier herramienta que desees, pero un método común es utilizar las bibliotecas para el lenguaje que elijas. Por ejemplo, puedes usar el método verify_token
desde la biblioteca OAuth 2.0 de Google para Python. El método verify_token
hace que el valor kid
coincida con el certificado apropiado, verifica la firma, comprueba la reclamación del público y muestra el contenido de la carga útil del token.
Después de que tu aplicación verifica el token y su contenido, puede comunicarse con esa instancia a través de una conexión segura y, luego, finalizar la conexión cuando haya terminado. Para conexiones posteriores, solicita un nuevo token a la instancia y vuelve a verificar su identidad.
Contenido del token
El token de identidad de instancia contiene tres partes principales:
Encabezado
El encabezado incluye el valor kid
para identificar qué certificados públicos de Oauth2 debes usar con el fin de verificar la firma. El encabezado también incluye el valor alg
para confirmar que la firma se genera con el algoritmo RS256.
{
"alg": "RS256",
"kid": "511a3e85d2452aee960ed557e2666a8c5cedd8ae",
}
Carga útil
La carga útil contiene la reclamación de aud
. Si la instancia especificó format=full
cuando solicitó el token, la carga útil también incluye reclamaciones sobre la instancia de máquina virtual y su proyecto.
Cuando se solicita un token de formato completo, también se incluyen reclamaciones sobre las licencias asociadas con la instancia mediante la especificación de licenses=TRUE
.
{
"iss": "[TOKEN_ISSUER]",
"iat": [ISSUED_TIME],
"exp": [EXPIRED_TIME],
"aud": "[AUDIENCE]",
"sub": "[SUBJECT]",
"azp": "[AUTHORIZED_PARTY]",
"google": {
"compute_engine": {
"project_id": "[PROJECT_ID]",
"project_number": [PROJECT_NUMBER],
"zone": "[ZONE]",
"instance_id": "[INSTANCE_ID]",
"instance_name": "[INSTANCE_NAME]",
"instance_creation_timestamp": [CREATION_TIMESTAMP],
"instance_confidentiality": [INSTANCE_CONFIDENTIALITY],
"license_id": [
"[LICENSE_1]",
...
"[LICENSE_N]"
]
}
}
}
Donde:
[TOKEN_ISSUER]
: una URL que identifica quién emitió el token. Para Compute Engine, este valor eshttps://accounts.google.com
.[ISSUED_TIME]
: una marca de tiempo de UNIX que indica cuándo se emitió el token. Este valor se actualiza cada vez que la instancia solicita un token al servidor de metadatos.[EXPIRED_TIME]
: una marca de tiempo de UNIX que indica cuándo vence el token.[AUDIENCE]
: el URI único acordado por la instancia y por el sistema que verifica la identidad de la instancia. Por ejemplo, el público podría ser una URL para la conexión entre los dos sistemas.[SUBJECT]
: el asunto del token, que es el ID único de la cuenta de servicio que asociaste a tu instancia.[AUTHORIZED_PARTY]
: la parte a la que se emitió el token de ID, que es el ID único de la cuenta de servicio que asociaste a tu instancia.[PROJECT_ID]
: el ID del proyecto en el que creaste la instancia.[PROJECT_NUMBER]
: el número único del proyecto en el que creaste la instancia.[ZONE]
: Es la zona en la que se encuentra la instancia.[INSTANCE_ID]
: el ID único para la instancia a la que pertenece este token. Este ID es único dentro del proyecto y la zona.[INSTANCE_NAME]
: el nombre de la instancia a la que pertenece este token. Si tu proyecto usa un DNS zonal, este nombre se puede volver a usar en las zonas, así que usa una combinación con los valoresproject_id
,zone
yinstance_id
para identificar un ID de instancia único. Los proyectos con DNS global habilitado tienen un nombre de instancia único en todo el proyecto.[CREATION_TIMESTAMP]
: una marca de tiempo de UNIX que indica cuándo creaste la instancia.[INSTANCE_CONFIDENTIALITY]
:1
si la instancia es una VM confidencial.- De
[LICENSE_1]
a[LICENSE_N]
: los códigos de licencia para las imágenes asociadas con esta instancia.
Tu carga útil puede ser similar al siguiente ejemplo:
{
"iss": "https://accounts.google.com",
"iat": 1496953245,
"exp": 1496956845,
"aud": "https://www.example.com",
"sub": "107517467455664443765",
"azp": "107517467455664443765",
"google": {
"compute_engine": {
"project_id": "my-project",
"project_number": 739419398126,
"zone": "us-west1-a",
"instance_id": "152986662232938449",
"instance_name": "example",
"instance_creation_timestamp": 1496952205,
"instance_confidentiality": 1,
"license_id": [
"1000204"
]
}
}
}
Firma
Google genera la firma mediante base64url, lo que codifica el encabezado y la carga útil, y concatena los dos valores. Puedes verificar este valor con los certificados públicos de Oauth2 para comprobar el token.
¿Qué sigue?
- Revisa el framework de arquitectura de Google Cloud.