Prima che un'applicazione invii informazioni sensibili a un'istanza di macchina virtuale (VM), può verificarne l'identità utilizzando i token di identità dell'istanza firmati da Google. Ogni istanza ha un token JWT (JSON Web Token) univoco che include dettagli sull'istanza e la firma RS256 di Google. Le tue applicazioni possono verificare la firma rispetto ai certificati Oauth2 pubblici di Google per confermare l'identità dell'istanza con cui hanno stabilito una connessione.
Compute Engine genera token di istanza firmati solo quando un'istanza li richiede dai metadati dell'istanza. Le istanze possono accedere solo al proprio token univoco e non ai token di altre istanze.
Potresti voler verificare l'identità delle tue istanze nei seguenti scenari:
- Quando avvii un'istanza per la prima volta, le tue applicazioni potrebbero dover assicurarsi che l'istanza a cui si sono connesse abbia un'identità valida prima di trasmettere informazioni sensibili all'istanza.
- Quando le tue norme richiedono di archiviare le credenziali al di fuori dell'ambiente Compute Engine e le invii regolarmente alle tue istanze per un utilizzo temporaneo. Le tue applicazioni possono confermare l'identità delle istanze ogni volta che devono trasmettere le credenziali.
I metodi di autenticazione delle istanze di Google presentano 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 le tue applicazioni in modo che accettino 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 di metadati firmati utilizzano lo standard di settore aperto RFC 7519 e il livello di identità, OpenID Connect 1.0, quindi gli strumenti e le librerie esistenti funzioneranno senza problemi con i token di identità.
Prima di iniziare
- Scopri come recuperare i valori dei metadati dell'istanza.
- Comprendi le nozioni di base dei token JWT (JSON Web Token) in modo da sapere come utilizzarli nelle tue applicazioni.
- Scopri come creare e abilitare i service account sulle tue istanze. Le tue istanze devono avere un account di servizio associato in modo che possano recuperare i relativi token di identità. Il account di servizio non richiede autorizzazioni IAM per recuperare questi token di identità.
-
Se non l'hai ancora fatto, configura l'autenticazione.
L'autenticazione verifica la tua identità per l'accesso ad API e servizi Google Cloud . Per eseguire
codice o esempi da un ambiente di sviluppo locale, puoi autenticarti su
Compute Engine selezionando una delle seguenti opzioni:
Per utilizzare gli esempi di Python in questa pagina in un ambiente di sviluppo locale, installa e inizializza gcloud CLI, quindi configura Credenziali predefinite dell'applicazione con le tue credenziali utente.
-
Installa Google Cloud CLI.
-
Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.
-
Se utilizzi una shell locale, crea le credenziali di autenticazione locali per il tuo account utente:
gcloud auth application-default login
Non devi eseguire questa operazione se utilizzi Cloud Shell.
Se viene restituito un errore di autenticazione e utilizzi un provider di identità (IdP) esterno, verifica di aver acceduto a gcloud CLI con la tua identità federata.
Per saperne di più, consulta Configura l'autenticazione per un ambiente di sviluppo locale.
-
Verificare l'identità di un'istanza
In alcuni scenari, le tue applicazioni devono verificare l'identità di un'istanza in esecuzione su Compute Engine prima di trasmettere dati sensibili a quell'istanza. In un tipico esempio, esiste un sistema in esecuzione al di fuori di Compute Engine chiamato "Host1" e un'istanza Compute Engine chiamata "VM1". VM1 può connettersi a Host1 e convalidare l'identità di questa istanza con la seguente procedura:
VM1 stabilisce una connessione sicura a Host1 tramite un protocollo di connessione sicura a tua scelta, ad esempio HTTPS.
VM1 richiede il suo token di identità univoco dal server di metadati e specifica il pubblico del token. In questo esempio, il valore del pubblico è l'URI di Host1. La richiesta al server di metadati include l'URI del pubblico in modo che Host1 possa controllare il valore in un secondo momento durante il passaggio di verifica del token.
Google genera un nuovo token di identità dell'istanza univoco in formato JWT e lo fornisce a VM1. Il payload del token include diversi dettagli sull'istanza e anche l'URI del pubblico. Per una descrizione completa dei contenuti del token, consulta Contenuti del token.
VM1 invia il token di identità a Host1 tramite la connessione sicura esistente.
Host1 decodifica il token di identità per ottenere i valori dell'intestazione e del payload del token.
Host1 verifica che il token sia firmato da Google controllando il valore del pubblico e verificando la firma del certificato rispetto al certificato pubblico di Google.
Se il token è valido, Host1 procede con la trasmissione e chiude la connessione al termine. Host1 e tutti gli altri sistemi devono richiedere un nuovo token per le connessioni successive a VM1.
Ottenere il token di identità dell'istanza
Quando l'istanza di macchina virtuale riceve una richiesta di fornire il suo token di identità, l'istanza richiede il token dal server di metadati utilizzando la procedura normale per ottenere i metadati dell'istanza. Ad esempio, puoi 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 sia dall'istanza sia dal sistema che verifica l'identità dell'istanza. Ad esempio, il 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. Specificafullper includere queste informazioni nel payload ostandardper ometterle dal payload. Il valore predefinito èstandard. Per ulteriori informazioni, vedi 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. SpecificaTRUEper includere queste informazioni oFALSEper ometterle dal payload. Il valore predefinito èFALSE. Non ha effetto a meno cheformatnon siafull
Il server di metadati risponde a questa richiesta con un token JWT 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 verificare il token e confermare che l'identità della tua istanza.
Python
Puoi inviare una semplice richiesta dalla tua istanza al server di metadati utilizzando i metodi della libreria requests di Python. L'esempio seguente richiede e poi stampa un token di identità dell'istanza. Il token è univoco per l'istanza che effettua questa richiesta.
Il server di metadati risponde a questa richiesta con un token JWT 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 verificare il token e confermare che l'identità della tua istanza.
Verificare il token
Dopo che l'applicazione riceve un token di identità dell'istanza da un'istanza Compute Engine, può verificarlo utilizzando la seguente procedura.
Ricevi il token dall'istanza di macchina virtuale, decodificalo utilizzando un decodificatore JWT RS256 e leggi i contenuti dell'intestazione per ottenere il valore
kid.Verifica che il token sia firmato controllandolo rispetto al certificato pubblico di Google. Ogni certificato pubblico ha un valore
kidche corrisponde al valorekidnell'intestazione del token.Se il token è valido, confronta i contenuti del payload con i valori previsti. Se il payload del token include dettagli sull'istanza e sul progetto, l'applicazione può controllare i valori
instance_id,project_idezone. Questi valori sono una tupla univoca a livello globale che conferma che l'applicazione sta comunicando con l'istanza corretta nel progetto desiderato.
Puoi decodificare e verificare il token utilizzando qualsiasi strumento, ma un metodo comune è utilizzare le librerie per la lingua 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 pubblico e restituisce i contenuti del payload dal token.
Dopo che l'applicazione ha verificato il token e i relativi contenuti, può procedere a comunicare con l'istanza tramite una connessione sicura e quindi chiudere la connessione al termine. Per le connessioni successive, richiedi un nuovo token dall'istanza e verifica di nuovo l'identità dell'istanza.
Contenuti del token
Il token di identità dell'istanza contiene tre parti principali:
Intestazione
L'intestazione include il valore kid per identificare quali
certificati Oauth2 pubblici
utilizzare per verificare la firma. L'intestazione include anche il alg
valore per confermare che la firma è generata utilizzando l'
algoritmo RS256.
{
"alg": "RS256",
"kid": "511a3e85d2452aee960ed557e2666a8c5cedd8ae",
}
Payload
Il payload contiene la rivendicazione del pubblico aud. Se l'istanza ha specificato format=full quando ha richiesto il token, il payload include anche rivendicazioni sull'istanza di macchina virtuale e sul relativo progetto.
Quando richiedi un token in formato completo, se specifichi licenses=TRUE verranno incluse anche le rivendicazioni relative alle licenze associate all'istanza.
{
"iss": "[TOKEN_ISSUER]",
"iat": [ISSUED_TIME],
"exp": [EXPIRED_TIME],
"aud": "[AUDIENCE]",
"sub": "[SUBJECT]",
"azp": "[AUTHORIZED_PARTY]",
"email": "[EMAIL]",
"email_verified": "[EMAIL_VERIFIED]",
"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 Compute Engine, 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 dal server di metadati.[EXPIRED_TIME]: un timestamp Unix che indica quando scade il token.[AUDIENCE]: l'URI univoco concordato sia dall'istanza sia dal sistema che verifica l'identità dell'istanza. Ad esempio, il pubblico potrebbe essere un URL per la connessione tra i due sistemi.[SUBJECT]: il soggetto del token, ovvero l'ID univoco del account di servizio associato all'istanza.[AUTHORIZED_PARTY]: la parte a cui è stato emesso il token ID, ovvero l'ID univoco del account di servizio associato all'istanza.[EMAIL]: l'indirizzo email del account di servizio associato all'istanza.[EMAIL_VERIFIED]:truese l'indirizzo email del account di servizio è stato verificato.[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 appartiene questo token. Questo ID è univoco all'interno del progetto e della zona.[INSTANCE_NAME]: il nome dell'istanza a cui appartiene questo token. Se il tuo progetto utilizza il DNS di zona, questo nome può essere riutilizzato tra le zone, quindi utilizza una combinazione dei valoriproject_id,zoneeinstance_idper identificare un ID istanza univoco. I progetti con il DNS globale abilitato hanno un nome istanza univoco all'interno del progetto.[CREATION_TIMESTAMP]: un timestamp Unix che indica quando hai creato l'istanza.[INSTANCE_CONFIDENTIALITY]:1se l'istanza è una VM riservata.[LICENSE_1]fino a[LICENSE_N]: i codici di licenza per le immagini associate a questa istanza.
Il 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",
"email": "739419398126-compute@developer.gserviceaccount.com",
"email_verified": true,
"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 codificando l'intestazione e il payload in base64url e concatenando i due valori. Puoi controllare questo valore rispetto ai certificati Oauth2 pubblici per verificare il token.
Passaggi successivi
- Consulta il Google Cloud Well-Architected Framework.
- Autentica i workload con altri workload tramite mTLS.