Verifica l'identità della VM


Prima che un'applicazione invii informazioni sensibili a una macchina virtuale (VM) istanza, l'applicazione può verificare l'identità dell'istanza utilizzando di identità dell'istanza firmati da Google. Ogni istanza ha un JSON Web Token (JWT) univoco che include dettagli sull'istanza nonché la firma RS256 di Google. Le tue applicazioni possono verificare la firma in base alla firma certificati Oauth2 pubblici per confermare l'identità dell'istanza con cui hanno stabilito una connessione.

Compute Engine genera token di istanza firmati solo quando l'istanza le richiede dai metadati dell'istanza. Le istanze possono accedere solo al proprio token univoco e non ai token di altre istanze.

Ti consigliamo di verificare le identità delle tue istanze nei seguenti scenari:

  • Quando avvii un'istanza per la prima volta, le tue applicazioni potrebbero dover verificare che l'istanza a cui si sono collegate abbia un'identità valida prima di trasmettere informazioni sensibili all'istanza.
  • Quando i tuoi criteri richiedono di archiviare le credenziali all'esterno dell'ambiente Compute Engine e le invii regolarmente alle tue istanze per uso temporaneo. Le tue applicazioni possono confermare le identità delle istanze ogni volta che devono trasmettere e credenziali.

I metodi di autenticazione delle istanze di Google offrono i seguenti vantaggi:

  • Compute Engine crea un token univoco ogni volta che un'istanza lo richiede e ogni token scade entro un'ora. Puoi configurare di accettare il token di identità di un'istanza una sola volta, il che riduce il rischio che il token possa essere riutilizzato da un sistema non autorizzato.
  • I token dei metadati firmati utilizzano lo standard di settore aperto RFC 7519 e il livello di identità OpenID Connect 1.0, pertanto gli strumenti e le librerie esistenti funzioneranno perfettamente con i token di identità.

Prima di iniziare

  • Scopri come recupera istanza dei metadati.
  • Comprendi le nozioni di base sui token web JSON in modo da sapere come utilizzarli nelle tue applicazioni.
  • Scopri come creare e abilitare gli account di servizio nelle tue istanze. Alle istanze deve essere associato un account di servizio con loro in modo che possano recuperare i loro token di identità. Account di servizio non richiede autorizzazioni IAM per recuperare questi token di identità.
  • Se non l'hai già fatto, configura l'autenticazione. Autenticazione è Il processo di verifica dell'identità per l'accesso ai servizi e alle API di Google Cloud. Per eseguire codice o esempi da un ambiente di sviluppo locale, puoi eseguire l'autenticazione Compute Engine come segue.

    Per utilizzare gli Python esempi in questa pagina in un ambiente di sviluppo locale, installa e inizializza l'interfaccia a riga di comando gcloud, quindi configura le credenziali predefinite dell'applicazione con le tue credenziali utente.

    1. Install the Google Cloud CLI.
    2. To initialize the gcloud CLI, run the following command:

      gcloud init
    3. 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.

    Per ulteriori informazioni, vedi Set up authentication for a local development environment.

Verificare l'identità di un'istanza

In alcuni scenari le applicazioni devono verificare l'identità di un'istanza in esecuzione su Compute Engine prima di trasmettere dati sensibili in esecuzione in un'istanza Compute Engine. In un esempio tipico, è presente un sistema in esecuzione al di fuori di Compute Engine denominato "Host1" e un'istanza Compute Engine denominata "VM1". La VM1 può connettersi all'host1 e convalidare l'identità di quell'istanza con la seguente procedura:

  1. La VM1 stabilisce una connessione sicura con l'host1 tramite un protocollo di connessione sicura di tua scelta, ad esempio HTTPS.

  2. La VM1 richiede il proprio token di identità univoco dalla server di metadati e specifica il pubblico del token. In questo esempio, il valore del segmento di pubblico è l'URI di Host1. La richiesta al server dei metadati include l'URI del segmento di pubblico in modo che Host1 possa controllare il valore in un secondo momento durante la procedura di verifica del token.

  3. Google genera un nuovo token di identità istanza univoco in formato JWT e lo fornisce alla VM1. Il payload del token include diversi dettagli sull'istanza e include anche l'URI del segmento di pubblico. Letto Contenuti del token per una descrizione completa del token contenuti.

  4. La VM1 invia il token di identità all'host1 tramite la connessione sicura esistente.

  5. Host1 decodifica il token di identità per ottenere l'intestazione del token e e i valori del payload.

  6. Host1 verifica che il token sia firmato da Google da Il controllo del valore del pubblico e la verifica della firma del certificato. rispetto a certificato pubblico di Google.

  7. Se il token è valido, Host1 procede con la trasmissione e chiude quando termina la connessione. L'host1 e tutti gli altri sistemi devono richiedere un nuovo token per eventuali connessioni successive alla VM1.

Ottenere il token di identità dell'istanza

Quando l'istanza di una macchina virtuale riceve una richiesta per fornire la propria identità. il token, l'istanza richiede il token al server dei metadati utilizzando la normale procedura ottenere i metadati dell'istanza. Ad esempio, potresti utilizzare uno dei seguenti metodi:

cURL

Crea una richiesta curl e includi un valore nel parametro audience. Se vuoi, puoi includere il parametro format per specificare se includere o meno i dettagli del progetto e dell'istanza nel payload. Se utilizzi il formato full, puoi includere il parametro licenses per specificare se includere o meno i codici di licenza nel payload.

curl -H "Metadata-Flavor: Google" \
'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=AUDIENCE&format=FORMAT&licenses=LICENSES'

Sostituisci quanto segue:

  • AUDIENCE: l'URI univoco concordato da entrambe le parti dell'istanza e il sistema ne verifica l'identità. Ad esempio, il segmento di pubblico potrebbe essere un URL per la connessione tra i due sistemi.
  • FORMAT: il parametro facoltativo che specifica se i dettagli del progetto e dell'istanza sono inclusi nel payload. Specifica full per includere queste informazioni nel payload o standard per omettere il le informazioni dal payload. Il valore predefinito è standard. Per maggiori informazioni, consulta Formato del token di identità.
  • LICENSES: un parametro facoltativo che specifica se i codici di licenza per le immagini associate a questa istanza sono inclusi nel payload. Specifica TRUE per includere queste informazioni o FALSE per omettere queste informazioni dal payload. Il valore predefinito è FALSE. Non ha effetto, a meno che format non sia full

Il server dei metadati risponde a questa richiesta con un token web JSON firmato utilizzando l'algoritmo RS256. Il token include una firma di Google e informazioni aggiuntive nel payload. Puoi inviare questo token ad altri sistemi e applicazioni in modo che possano verificarlo e confermare l'identità della tua istanza.

Python

Puoi inviare una semplice richiesta dalla tua istanza al server dei metadati utilizzando i metodi della libreria requests di Python. Nell'esempio che segue e poi stampa un token di identità dell'istanza. Il token è univoco all'istanza che effettua la richiesta.

import requests

AUDIENCE_URL = "http://www.example.com"
METADATA_HEADERS = {"Metadata-Flavor": "Google"}
METADATA_VM_IDENTITY_URL = (
    "http://metadata.google.internal/computeMetadata/v1/"
    "instance/service-accounts/default/identity?"
    "audience={audience}&format={format}&licenses={licenses}"
)
FORMAT = "full"
LICENSES = "TRUE"


def acquire_token(
    audience: str = AUDIENCE_URL, format: str = "standard", licenses: bool = True
) -> str:
    """
    Requests identity information from the metadata server.

    Args:
        audience: the unique URI agreed upon by both the instance and the
            system verifying the instance's identity. For example, the audience
            could be a URL for the connection between the two systems.
        format: the optional parameter that specifies whether the project and
            instance details are included in the payload. Specify `full` to
            include this information in the payload or standard to omit the
            information from the payload. The default value is `standard`.
        licenses: an optional parameter that specifies whether license
            codes for images associated with this instance are included in the
            payload. Specify TRUE to include this information or FALSE to omit
            this information from the payload. The default value is FALSE.
            Has no effect unless format is `full`.

    Returns:
        A JSON Web Token signed using the RS256 algorithm. The token includes a
        Google signature and additional information in the payload. You can send
        this token to other systems and applications so that they can verify the
        token and confirm that the identity of your instance.
    """
    # Construct a URL with the audience and format.
    url = METADATA_VM_IDENTITY_URL.format(
        audience=audience, format=format, licenses=licenses
    )

    # Request a token from the metadata server.
    r = requests.get(url, headers=METADATA_HEADERS)
    # Extract and return the token from the response.
    r.raise_for_status()
    return r.text

Il server dei metadati risponde a questa richiesta con un token web JSON firmato utilizzando l'algoritmo RS256. Il token include una firma di Google e informazioni aggiuntive nel il payload. Puoi inviare questo token ad altri sistemi e applicazioni in modo che di poter verificare il token e confermare che l'identità della tua istanza.

Verifica del token

Dopo che l'applicazione riceve un token di identità istanza da un'istanza Compute Engine, può verificarlo utilizzando la procedura riportata di seguito.

  1. Ricevi il token dall'istanza della macchina virtuale, decodificalo utilizzando un decodificatore JWT RS256 e leggi i contenuti dell'intestazione per ottenere il valore kid.

  2. Verifica che il token sia firmato controllandolo con il certificato pubblico di Google. Ogni certificato pubblico ha un valore kid che corrisponde al kid nell'intestazione del token.

  3. Se il token è valido, confronta i contenuti del payload con i e i relativi valori. Se il payload del token include dettagli sull'istanza e sul progetto, la tua applicazione può controllare instance_id, project_id e zone valori. Questi valori sono una tupla unica a livello globale che conferma la tua applicazione comunica con l'istanza corretta nel progetto desiderato.

Puoi decodificare e verificare il token utilizzando qualsiasi strumento che preferisci, ma un metodo comune è utilizzare le librerie per il linguaggio che preferisci. Ad esempio, puoi utilizzare il metodo verify_token della libreria Google OAuth 2.0 per Python. Il metodo verify_token associa il valore kid al certificato appropriato, verifica la firma, controlla la rivendicazione del segmento di pubblico e restituisce i contenuti del payload dal token.

import google.auth.transport.requests
from google.oauth2 import id_token



def verify_token(token: str, audience: str) -> dict:
    """
    Verify token signature and return the token payload.

    Args:
        token: the JSON Web Token received from the metadata server to
            be verified.
        audience: the unique URI agreed upon by both the instance and the
            system verifying the instance's identity.

    Returns:
        Dictionary containing the token payload.
    """
    request = google.auth.transport.requests.Request()
    payload = id_token.verify_token(token, request=request, audience=audience)
    return payload

Dopo che l'applicazione ha verificato il token e i relativi contenuti, può procedere a comunicare con l'istanza tramite una connessione sicura e poi chiudere la connessione al termine. Per le connessioni successive, richiedi un nuovo token dall'istanza e verifica di nuovo la sua identità.

Contenuti del token

Il token di identità dell'istanza è composto da tre parti principali:

L'intestazione include il valore kid per identificare i certificati pubblici OAuth2 da utilizzare per verificare la firma. L'intestazione include anche il valore alg per confermare che la firma viene generata utilizzando l'algoritmo RS256.

{
  "alg": "RS256",
  "kid": "511a3e85d2452aee960ed557e2666a8c5cedd8ae",
}

Payload

Il payload contiene la dichiarazione del pubblico aud. Se l'istanza specificato format=full quando ha richiesto il token, anche il payload include attestazioni sull'istanza di macchina virtuale e sul relativo progetto. Quando richiedi un token di formato completo, la specifica di licenses=TRUE includerà anche rivendicazioni relative alle licenze associate all'istanza.

{
   "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]"
      ]
    }
  }
}

Dove:

  • [TOKEN_ISSUER]: un URL che identifica chi ha emesso il token. Per questo valore è https://accounts.google.com.
  • [ISSUED_TIME]: un timestamp unix che indica quando è stato emesso il token. Questo valore viene aggiornato ogni volta che l'istanza richiede un token dai metadati server web.
  • [EXPIRED_TIME]: un timestamp unix che indica la scadenza del token.
  • [AUDIENCE]: l'URI univoco concordato sia dall'istanza che il sistema verifica l'identità dell'istanza. Ad esempio, il segmento di pubblico potrebbe essere un URL per la connessione tra i due sistemi.
  • [SUBJECT]: l'oggetto del token, ovvero l'ID univoco ID per l'account di servizio associato all'istanza.
  • [AUTHORIZED_PARTY]: la parte a cui è stato emesso il token ID, ovvero l'ID univoco dell'account di servizio associato all'istanza.
  • [PROJECT_ID]: l'ID del progetto in cui hai creato l'istanza.
  • [PROJECT_NUMBER]: il numero univoco del progetto in cui hai creato l'istanza.
  • [ZONE]: la zona in cui si trova l'istanza.
  • [INSTANCE_ID]: l'ID univoco dell'istanza a cui il token . Questo ID è univoco all'interno del progetto e della zona.
  • [INSTANCE_NAME]: il nome dell'istanza a cui il token . Se il tuo progetto utilizza il DNS di zona, questo nome può essere riutilizzato in più zone, quindi usa una combinazione Valori project_id, zone e instance_id per identificare un indirizzo l'ID istanza. I progetti con il DNS globale abilitato hanno un nome istanza univoco nel progetto.
  • [CREATION_TIMESTAMP]: un timestamp Unix che indica quando è stata creata l'istanza.
  • [INSTANCE_CONFIDENTIALITY]: 1 se l'istanza è una VM con accesso riservato.
  • [LICENSE_1] fino a [LICENSE_N]: i codici licenza per le immagini associate a questa istanza.

Il tuo payload potrebbe essere simile al seguente esempio:

{
  "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 la codifica base64url dell'intestazione e il payload e concatenando i due valori. Puoi controllare questo valore in base ai certificati pubblici OAuth2 per verificare il token.

Passaggi successivi