Identität von Instanzen prüfen

Bevor eine Anwendung vertrauliche Informationen an eine VM-Instanz sendet, kann sie mit von Google signierten Instanzidentitätstokens die Identität der virtuellen Maschine überprüfen. Jede Instanz hat ein eindeutiges JSON Web Token (JWT), das Details über die Instanz sowie die RSA256-Signatur von Google enthält. Die Anwendungen können die Signatur mit den öffentlichen OAuth2-Zertifikaten von Google abgleichen. Auf diese Weise wird die Identität der Instanz überprüft, zu der eine Verbindung hergestellt wurde.

Compute Engine generiert signierte Instanztokens nur, wenn eine Instanz diese von den Instanzmetadaten anfordert. Instanzen können jeweils nur auf ihre eigenen eindeutigen Tokens zugreifen und nicht auf Tokens anderer Instanzen.

In folgenden Fällen ist eventuell eine Überprüfung der Identität der Instanzen erforderlich:

  • Wenn Sie eine Instanz zum ersten Mal starten, muss für Anwendungen möglicherweise erst sichergestellt werden, dass die Instanz, zu der sie eine Verbindung herstellen, eine gültige Identität hat, bevor die Anwendungen sensible Informationen an die Instanz senden.
  • Wenn Ihre Richtlinien verlangen, dass Anmeldedaten außerhalb der Compute Engine-Umgebung gespeichert werden und Sie diese Anmeldedaten regelmäßig zur temporären Nutzung an Ihre Instanzen senden. Ihre Anwendungen können die Identität von Instanzen dann jedes Mal prüfen, wenn sie die Anmeldedaten senden müssen.

Die Methoden zur Authentifizierung von Instanzen von Google bieten folgende Vorteile:

  • Compute Engine erstellt jedes Mal ein eindeutiges Token, wenn eine Instanz es anfordert. Jedes Token läuft nach einer Stunde ab. Sie können Ihre Anwendungen so konfigurieren, dass sie Identitätstokens von Instanzen jeweils nur einmal akzeptieren. Damit verringert sich das Risiko, dass ein Token von einem nicht autorisierten System noch einmal verwendet wird.
  • Die privaten Schlüssel und die öffentlichen OAuth2-Zertifikate von Google werden täglich rotiert. Dies reduziert die Gefahr von Angriffen für diese Signaturen.
  • Signierte Metadatentokens verwenden den offenen Branchenstandard RFC 7519 und die Identitätsschicht OpenID Connect 1.0, sodass vorhandene Tools und Bibliotheken mit den Identitätstokens kompatibel sind.

Vorbereitung

Identität einer Instanz überprüfen

In einigen Szenarien müssen Anwendungen die Identität einer Instanz prüfen, bevor sie vertrauliche Daten an diese Instanz übertragen. Ein typisches Beispiel hierfür ist ein System namens "Host1", das außerhalb von Compute Engine ausgeführt wird, und eine Compute Engine-Instanz namens "VM1". VM1 kann eine Verbindung zu Host1 herstellen und mit dem folgenden Vorgang die Identität dieser Instanz überprüfen:

  1. VM1 stellt über ein sicheres Verbindungsprotokoll Ihrer Wahl wie z. B. HTTPS eine sichere Verbindung zu Host1 her.

  2. VM1 ruft ein eindeutiges Identitätstoken vom Metadatenserver ab und legt die Zielgruppe des Tokens fest. In diesem Beispiel ist der Zielgruppenwert der URI für Host1. Die Anfrage an den Metadatenserver enthält den Zielgruppen-URI, damit Host1 den Wert später im Schritt zur Bestätigung des Tokens überprüfen kann.

  3. Google generiert ein neues, eindeutiges Instanzidentitätstoken im JWT-Format und stellt es für VM1 bereit. Die Nutzlast des Tokens umfasst verschiedene Details der Instanz und enthält außerdem den Zielgruppen-URI. Eine vollständige Beschreibung der Inhalte von Tokens finden Sie unter Tokeninhalte.

  4. VM1 sendet das Identitätstoken über die bestehende sichere Verbindung an Host1.

  5. Host1 decodiert das Identitätstoken, um den Header und die Nutzlastwerte des Tokens abzurufen.

  6. Host1 überprüft, ob das Token von Google signiert ist. Hierzu wird der Zielgruppenwert geprüft und die Zertifikatssignatur mit dem öffentlichen Google-Zertifikat verglichen.

  7. Bei einem gültigen Token startet Host1 die Datenübertragung und trennt die Verbindung, wenn die Übertragung beendet ist. Für jede nachfolgende Herstellung einer Verbindung zu VM1 müssen Host1 und alle anderen Systeme ein neues Token anfordern.

Identitätstoken der Instanz abrufen

Wenn Ihre VM-Instanz eine Anfrage erhält, ihr Identitätstoken zu senden, fordert sie dieses Token nach dem Standardverfahren zum Abruf von Instanzmetadaten beim Metadatenserver an. Beispielsweise können Sie eine der folgenden Methoden verwenden:

cURL

Erstellen Sie eine curl-Anfrage und geben Sie für den Parameter audience einen Wert an. Optional können Sie den Parameter format einschließen, um anzugeben, ob Sie Projekt- und Instanzdetails in die Nutzlast aufnehmen möchten. Wenn Sie das Format full verwenden, können Sie den Parameter licenses einschließen, um zu festzulegen, ob die Lizenzcodes in der Nutzlast enthalten sein sollen.

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

Dabei gilt:

  • [AUDIENCE] ist der eindeutige URI, der von der Instanz und vom System zur Prüfung der Identität der Instanz definiert wurde. Die Zielgruppe kann zum Beispiel eine URL für die Verbindung zwischen den beiden Systemen sein.
  • [FORMAT] ist der optionale Parameter, der festlegt, ob in die Nutzlast Projekt- und Instanzinformationen aufgenommen werden. Wählen Sie den Wert full, um diese Informationen in die Nutzlast einzubeziehen, oder standard, um sie auszuschließen. Der Standardwert ist standard. Ausführliche Informationen über das Format von Tokens finden Sie unter Format von Identitätstokens.
  • [LICENSES] ist ein optionaler Parameter, der angibt, ob Lizenzcodes für die mit dieser Instanz verbundenen Images in die Nutzlast eingeschlossen werden oder nicht. Geben Sie TRUE an, um diese Informationen einzuschließen, oder FALSE, um die Informationen aus der Nutzlast auszuschließen. Der Standardwert ist FALSE. Er hat nur dann Auswirkungen, wenn für format der Wert full festgelegt wurde.

Der Metadatenserver antwortet auf diese Anfrage mit einem JSON Web Token (JWT), das nach dem Algorithmus RS256 signiert wurde. Die Nutzlast des Tokens enthält eine Google-Signatur und Zusatzinformationen. Sie können dieses Token an andere Systeme und Anwendungen senden, damit diese das Token prüfen und die Identität Ihrer Instanz bestätigen.

Python

Mit den Methoden aus der requests-Bibliothek von Python können Sie von Ihrer Instanz eine einfache Anfrage an den Metadatenserver senden. Im nachstehenden Beispiel wird ein Instanz-Identitätstoken angefordert und anschließend gedruckt. Das Token ist eindeutig für die Instanz, von der die Anfrage gesendet wird.

import requests

AUDIENCE_URL = 'http://www.example.com'
METADATA_HEADERS = {'Metadata-Flavor': 'Google'}
FORMAT = 'full'
LICENSES = 'TRUE'

# Construct a URL with the audience and format.
url = 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience={}&format={}&licenses={}'
url = url.format(AUDIENCE_URL, FORMAT, LICENSES)

# Request a token from the metadata server.
r = requests.get(url, headers=METADATA_HEADERS)

# Extract the token from the response.
token = r.text

print(token)

Der Metadatenserver antwortet auf diese Anfrage mit einem JSON Web Token (JWT), das nach dem Algorithmus RS256 signiert wurde. Die Nutzlast des Tokens enthält eine Google-Signatur und Zusatzinformationen. Sie können dieses Token an andere Systeme und Anwendungen senden, damit diese das Token prüfen und die Identität Ihrer Instanz bestätigen.

Token verifizieren

Nachdem Ihre Anwendung ein Instanzidentitätstoken von einer Compute Engine-Instanz erhalten hat, kann sie dieses Token mit folgenden Vorgängen prüfen:

  1. Sie empfängt das Token von einer VM-Instanz, decodiert es mithilfe eines RS256-JWT-Decodierers und liest den Wert kid aus dem Header.

  2. Sie prüft durch Vergleich mit dem öffentlichen Google Zertifikat, ob das Token signiert ist. Alle öffentlichen Zertifikate haben einen Wert kid, der dem kid-Wert im Tokenheader entspricht.

  3. Ist das Token gültig, prüft die Anwendung den Inhalt der Nutzlast auf die erwarteten Werte. Enthält die Nutzlast des Tokens Informationen über die Instanz und das Projekt, kann die Anwendung die Werte für instance_id, project_id und zone prüfen. Diese Werte sind global eindeutige Tupel, die prüfen, ob die Anwendung mit der korrekten Instanz im gewünschten Projekt kommuniziert.

Sie können das Token mit jedem beliebigen Tool decodieren und prüfen. Die gängigste Methode ist die Verwendung der Bibliotheken der von Ihnen gewählten Sprache. Beispielsweise können Sie für Python die Methode verify_token der Google-OAuth 2.0-Bibliothek verwenden. Die Methode verify_token vergleicht den Wert kid mit dem geeigneten Zertifikat, verifiziert die Signatur, prüft die Zielgruppenanforderung und gibt die Nutzlastinhalte des Tokens zurück.

# Import libraries for token verification
import google.auth.transport.requests
from google.oauth2 import id_token

# Receive token from VM over an SSL connection
token = …
…

# Verify token signature and store the token payload
request = google.auth.transport.requests.Request()
payload = id_token.verify_token(token, request=request, audience=audience)
…

Nachdem die Anwendung das Token und dessen Inhalte geprüft hat, kann sie mit der jeweiligen Instanz über eine sichere Verbindung kommunizieren und nach Abschluss des Vorgangs die Verbindung trennen. Für nachfolgende Verbindungen wird von der Instanz ein neues Token angefordert und deren Identität noch einmal überprüft.

Tokeninhalte

Das Instanz-Identitätstoken hat drei Hauptbestandteile:

Der Header enthält den Wert kid, der festlegt, mit welchen öffentlichen OAuth2-Zertifikaten Sie die Signatur überprüfen müssen. Außerdem enthält der Header den Wert alg, um anzugeben, dass die Signatur mit dem Algorithmus RS256 generiert wurde.

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

Nutzlast

Die Nutzlast enthält die Zielgruppenanforderung aud. Wenn von der Instanz bei der Anforderung des Tokens format=full angegeben wurde, enthält die Nutzlast Informationsanforderungen über die VM-Instanz und deren Projekt. Wenn Sie ein Token im vollständigen Format anfordern, werden durch Angabe von licenses=TRUE auch Anforderungen in Bezug auf die mit der Instanz verknüpften Lizenzen eingeschlossen.

{
   "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],
      "license_id": [
        "[LICENSE_1]",
          ...
        "[LICENSE_N]"
      ]
    }
  }
}

Dabei gilt:

  • [TOKEN_ISSUER] ist eine URL, die den Aussteller des Tokens identifiziert. Für Compute Engine ist dies https://accounts.google.com.
  • [ISSUED_TIME] ist ein UNIX-Zeitstempel, der angibt, wann das Token ausgestellt wurde. Dieser Wert wird jedes Mal aktualisiert, wenn die Instanz ein Token vom Metadatenserver anfordert.
  • [EXPIRED_TIME] ist ein UNIX-Zeitstempel, der angibt, wann die Gültigkeit des Tokens abläuft.
  • [AUDIENCE] ist der eindeutige URI, der von der Instanz und vom System zur Prüfung der Identität der Instanz definiert wurde. Die Zielgruppe kann zum Beispiel eine URL für die Verbindung zwischen den beiden Systemen sein.
  • [SUBJECT] ist der Inhalt des Tokens, d. h., die eindeutige ID des Dienstkontos, das Sie mit Ihrer Instanz verknüpft haben.
  • [AUTHORIZED_PARTY] ist die Partei, für die das Identitätstoken ausgestellt wurde, d. h., die eindeutige ID des Dienstkontos, das Sie mit Ihrer Instanz verknüpft haben.
  • [PROJECT_ID] ist die ID des Projekts, in dem Sie die Instanz erstellt haben.
  • [PROJECT_NUMBER] ist die eindeutige Nummer des Projekts, in dem Sie die Instanz erstellt haben.
  • [ZONE] ist die Zone, in der sich die Instanz befindet.
  • [INSTANCE_ID] ist die eindeutige ID der Instanz, zu der dieses Token gehört. Diese ID ist eindeutig und wird nicht für andere Instanzen verwendet.
  • [INSTANCE_NAME] ist der Name der Instanz, zu der dieses Token gehört. Dieser Name kann im Zeitablauf von verschiedenen Instanzen genutzt werden. Legen Sie deshalb mit instance_id eine eindeutige Kennzeichnung der Instanz-ID fest.
  • [CREATION_TIMESTAMP] ist ein UNIX-Zeitstempel, der angibt, wann die Instanz erstellt wurde.
  • [LICENSE_1] bis [LICENSE_N] sind die Lizenzcodes für Images, die mit dieser Instanz verbunden sind.

Die Nutzlast sieht in etwa wie im folgenden Beispiel aus:

{
  "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,
      "license_id": [
        "1000204"
      ]
    }
  }
}

Signatur

Google generiert die Signatur mit Base64Url, durch Codierung des Headers und der Nutzlast sowie Verkettung der beiden Werte. Sie können diese Werte mit den öffentlichen OAuth2-Zertifikaten vergleichen, um das Token zu prüfen.

Weitere Informationen

Hat Ihnen diese Seite weitergeholfen? Teilen Sie uns Ihr Feedback mit:

Feedback geben zu...

Compute Engine-Dokumentation