Häufige Probleme beheben

Auf dieser Seite werden verschiedene Probleme aufgeführt, die bei der Konfiguration von VPC Service Controls auftreten können.

Unerwartetes Verhalten von bereichsbezogenen Richtlinien

Ihnen fallen einige Verstöße gegen VPC Service Controls-auf, die Sie aufgrund Ihrer bereichsbezogenen Richtlinie eigentlich nicht erwarten würden. Dieses bekannte Problem tritt auf, wenn Sie keine Zugriffsrichtlinie auf Organisationsebene eingerichtet haben.

Um das Problem zu beheben, erstellen Sie mit dem folgenden Befehl eine Zugriffsrichtlinie auf Organisationsebene:

gcloud access-context-manager policies create --organization <var>ORGANIZATION_ID</var> --title <var>POLICY_TITLE</var>

Ersetzen Sie die folgenden Variablen:

  • ORGANIZATION_ID: Die Organisations-ID.
  • POLICY_TITLE: Ein menschenlesbarer Titel der Zugriffsrichtlinie.

Weitere Informationen finden Sie unter Zugriffsrichtlinie erstellen.

Gemeinsam genutzte VPC

Wenn Sie eine VPC gemeinsam nutzen, muss im Dienstperimeter neben den Projekten des gemeinsam genutzten VPC-Netzwerks auch das Projekt enthalten sein, das das Netzwerk hostet. Das heißt, alle Projekte, die zum gemeinsam genutzten VPC-Netzwerk gehören, und das Host-Projekt müssen sich im selben Perimeter befinden. Andernfalls funktionieren die Dienste möglicherweise nicht wie erwartet oder werden insgesamt blockiert.

Achten Sie darauf, dass sich der Host des gemeinsam genutzten VPC-Netzwerks im gleichen Dienstperimeter befindet wie die zum Netzwerk gehörenden Projekte.

VPC-Netzwerk kann nicht hinzugefügt werden

Der folgende Fehler kann auftreten, wenn Sie versuchen, einem Dienstperimeter ein VPC-Netzwerk hinzuzufügen:

ERROR: (gcloud.access-context-manager.perimeters.update) PERMISSION_DENIED: Permission 'compute.networks.get' denied on resource '//compute.googleapis.com/projects/PROJECT_NAME/global/networks/VPC_NETWORK_NAME' (or it may not exist)

Dieser Fehler tritt aus einem der folgenden Gründe auf:

  • Das VPC-Netzwerk ist nicht vorhanden.
  • Das VPC-Netzwerk ist vorhanden, hat aber kein Subnetz.
  • Der Aufrufer hat nicht die erforderliche Berechtigung.

So beheben Sie das Problem:

  1. Prüfen Sie, ob das in der Fehlermeldung angegebene VPC-Netzwerk vorhanden ist. Sehen Sie sich dazu die Netzwerke in Ihrem Projekt an.

    • Bevor Sie das VPC-Netzwerk überprüfen, müssen Sie die Compute Engine API im Projekt aktivieren, das mit dem API-Aufruf verknüpft ist. Führen Sie dazu die folgenden Schritte aus:

      1. Rufen Sie in der Google Cloud Console die Seite APIs und Dienste auf.
        Zu APIs und Dienste

      2. Prüfen Sie auf der Seite APIs und Dienste, ob die Compute Engine API aufgeführt ist.

      3. Falls sie nicht aufgeführt ist, aktivieren Sie die API.
        API aktivieren

  2. Prüfen Sie, ob im VPC-Netzwerk mindestens ein Subnetz vorhanden ist, indem Sie die Subnetze aufrufen. Wenn kein Subnetz vorhanden ist, fügen Sie dem VPC-Netzwerk ein Subnetz hinzu.

  3. Prüfen Sie, ob der Aufrufer die folgende Berechtigung für das Hostprojekt des VPC-Netzwerks hat: compute.networks.get. Mit dieser Berechtigung können Sie VPC-Netzwerke in einem Projekt ansehen.

    • Bitten Sie den Administrator der Organisation, die Eigentümerin des Hostprojekts im VPC-Netzwerks ist, dem Aufrufer eine IAM-Rolle mit der Berechtigung compute.networks.get für das Hostprojekt zuzuweisen. Das kann zum Beispiel die Rolle „Compute-Netzwerkbetrachter“ sein.

      Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff verwalten.

Lesen Sie sich die Einschränkungen durch, die mit der Verwendung von VPC-Netzwerken in Dienstperimetern verbunden sind.

Anfragen zwischen Perimetern

In der Regel ist es mithilfe von Zugriffsebenen möglich, Anfragen zuzulassen, die von außerhalb eines Dienstperimeters an geschützte Ressourcen innerhalb eines Perimeters gerichtet werden.

Anfragen, die sich an geschützte Ressourcen in einem anderen Perimeter richten, werden jedoch abgelehnt, selbst wenn gemäß Zugriffsebene die Anfrage eigentlich zulässig wäre.

Beispiel: Projekt A in Perimeter 1 fragt eine Ressource von Projekt B an. Die Ressource in Projekt B ist durch Perimeter 2 geschützt. Da sich Projekt A in einem anderen Perimeter befindet, wird die Anfrage abgelehnt, selbst wenn eine Zugriffsebene für Perimeter 2 die Anfrage für die geschützte Ressource eigentlich zulassen würde.

Mit den folgenden Möglichkeiten können Sie Anfragen zwischen Perimetern vereinfachen:

  • Richtlinien für ausgehenden und eingehenden Traffic. Anfragen von einem anderen Perimeter an geschützte Ressourcen in Ihrem Perimeter werden zugelassen, wenn Sie für den anderen Perimeter eine Richtlinie für ausgehenden Traffic und für Ihren Perimeter eine Richtlinie für eingehenden Traffic verwenden.

  • Perimeter-Bridges. Mithilfe von Bridges können zwei oder mehr Projekte in verschiedenen Perimetern Anfragen an beliebige Dienste in diesen Projekten stellen. Die Anfragen werden auch dann zugelassen, wenn die Dienste durch die jeweiligen Perimeter geschützt sind.

  • Sorgen Sie dafür, dass der anfragende Dienst und auch die Zielressource nicht durch die Perimeter geschützt sind. Anfragen sind in einem solchen Szenario möglich, weil die Dienste nicht geschützt sind.

Ungültige oder nicht vorhandene E-Mail-Adresse

Der Fehler The email address is invalid or non-existent kann auftreten, wenn Sie einen Perimeter aktualisieren, der ein gelöschtes Hauptkonto enthält.

Um dieses Problem zu beheben, müssen Sie die ungültige E-Mail-Adresse aus allen Perimetern entfernen:

  1. Exportieren Sie alle Ihre Perimeter. Mit dem folgenden Beispielbefehl werden die Dienstperimeter im YAML-Format in einer Liste exportiert:

    gcloud access-context-manager perimeters list \
        --policy=POLICY_NAME \
        --format="json(name,title,description,perimeterType,status,spec,useExplicitDryRunSpec)" \
        > my-perimeters.yaml
  2. Entfernen Sie die ungültige E-Mail-Adresse aus der Datei my-perimeters.yaml und speichern Sie sie als my-perimeters-updated.yaml.

  3. Ersetzen Sie alle Perimeter in einem Schritt.

Verstöße gegen Regeln für eingehenden- und ausgehenden Traffic

Im Audit-Log finden Sie Informationen zu den Verstößen gegen die Regeln für eingehenden und ausgehenden Traffic, die Ihnen beim Verständnis helfen.

Verstoß gegen Regeln für eingehenden Traffic

Ein Verstoß gegen die Regeln für eingehenden Traffic bedeutet, dass ein API-Client außerhalb des Perimeters versucht hat, auf eine Ressource innerhalb des Perimeters zuzugreifen. Da die Regeln für eingehenden Traffic oder Zugriffsebenen nicht erfüllt sind, lehnt der Dienstperimeter die Anfrage ab.

Bei einem Verstoß gegen die Regeln für eingehenden Traffic werden im Audit-Log die folgenden Details protokolliert:

  • Den Namen des Perimeters, in dem der Verstoß gegen die Regel für eingehenden Traffic aufgetreten ist.
  • Die Ressource innerhalb des Perimeters, auf die der API-Client außerhalb des Perimeters zugreifen wollte.

Im folgenden Beispiel versucht ein API-Client von außerhalb des Perimeters auf den Cloud Storage-Bucket prod-protected-storage-bucket innerhalb des Perimeters prod-perimeter zuzugreifen.

ingressViolations: [
  0: {
    targetResource: "projects/1234/buckets/prod-protected-storage-bucket"
    servicePerimeter: "accessPolicies/123456789/servicePerimeters/prod-perimeter"
  }
]

Um dieses Problem zu beheben, erstellen Sie für Ihren Perimeter eine Regel für eingehenden Traffic. Weitere Informationen zu Regeln für eingehenden Traffic finden Sie unter Referenz zu Regeln für eingehenden Traffic.

Verstoß gegen Regeln für ausgehenden Traffic

Ein im Audit-Log angegebener Verstoß gegen eine Regel für ausgehenden Traffic weist auf eines der folgenden Ereignisse hin:

  • Ein API-Client innerhalb des Perimeters hat versucht, auf eine Ressource außerhalb des Perimeters zuzugreifen.
  • Eine API-Anfrage, die eine Ressource innerhalb des Perimeters und eine Ressource außerhalb des Perimeters betrifft. Zum Beispiel ein Cloud Storage-Client, der einen Kopierbefehl aufruft, wobei sich ein Bucket innerhalb des Perimeters und der andere Bucket außerhalb des Perimeters befindet.

Der Dienstperimeter lehnt die Anfrage ab, da es keine übereinstimmenden Regeln für ausgehenden Traffic gibt. Bei einem Verstoß gegen Regeln für ausgehenden Traffic werden im Audit-Log die folgenden Details angegeben:

  • Der Quelltyp, z. B. Netzwerk oder Ressource.
  • Die Quelle, also eine Ressource oder ein Netzwerk, dessen Perimeter einen Verstoß gegen die Regeln für ausgehenden Traffic festgestellt hat.
  • Der Perimeter, der einen Verstoß gegen die Regeln für ausgehenden Traffic festgestellt hat.
  • Die Zielressource außerhalb des Perimeters, auf die die Anfrage zugreifen wollte.

Im folgenden Beispiel umfasst die API-Anfrage eine Ressource aus projects/5678, die sich innerhalb des Perimeters prod-perimeter befindet, und ein Objekt aus dem Cloud Storage-Bucket external-storage-bucket, der sich außerhalb des Perimeters befindet.

egressViolations: [
  0: {
    sourceType: "Resource"
    source: "projects/5678"
    targetResource: "projects/4321/buckets/external-storage-bucket/objects/corp-resources.json"
    servicePerimeter: "accessPolicies/123456789/servicePerimeters/prod-perimeter"
  }
]

Um dieses Problem zu beheben, erstellen Sie für Ihren Perimeter eine Regel für ausgehenden Traffic. Weitere Informationen zu Regeln für ausgehenden Traffic finden Sie in der Referenz zu Regeln für ausgehenden Traffic.

Debuggen von Anfragen, die von VPC Service Controls blockiert wurden

Das Audit-Log von VPC Service Controls ist das wichtigste Tool zum Debuggen von Anfrage, die von VPC Service Controls blockiert wurden.

Wenn der Zugriff wider Erwarten blockiert wurde, sehen Sie sich die Audit-Logs in dem durch den Dienstperimeter geschützten Projekt an. Diese Logs enthalten wichtige Daten zu den angefragten Ressourcen und zum Grund für die Ablehnung der Anfrage. Informationen zur Diagnose der Audit-Logs finden Sie unter Auf den Analysator für Richtlinienverstöße zugreifen.

In den folgenden Abschnitten sind die Werte für violationReason aufgeführt, die bei Verwendung von VPC Service Controls vorkommen können.

NETWORK_NOT_IN_SAME_SERVICE_PERIMETER

Für dieses Problem kann es folgende Gründe geben:

  • Ein Client in einem VPC-Netzwerk innerhalb eines Dienstperimeters versucht, auf ein Projekt zuzugreifen, das sich in einem anderen Perimeter befindet. Eine solche Anfrage führt zu einem Verstoß gegen die Regeln für ausgehenden Traffic. Erstellen Sie eine Regel für ausgehenden Traffic, um dieses Problem zu beheben.
  • Ein Client in einem VPC-Netzwerk außerhalb eines Dienstperimeters versucht, auf ein Projekt zuzugreifen, das durch den Dienstperimeter geschützt ist. Eine solche Anfrage führt zu einem Verstoß gegen die Regeln für eingehenden Traffic. Erstellen Sie eine Regel für eingehenden Traffic, um dieses Problem zu beheben.

Der Client sendet die Anfrage möglicherweise von einer Compute Engine-VM bzw. Google Kubernetes Engine-VM oder von einem lokalen Netzwerk über Cloud Interconnect oder einem VPN, das mit einem VPC-Netzwerk konfiguriert wurde.

Im folgenden Diagramm ist ein Verstoß gegen Regeln für ausgehenden Traffic zu sehen, der auftritt, wenn ein Client in einem VPC-Netzwerk innerhalb eines Dienstperimeters versucht, auf ein Projekt außerhalb des Perimeters zuzugreifen:

Eine Verletzung der Regeln für ausgehenden Traffic durch NETWORK_NOT_IN_SAME_SERVICE_PERIMETER.

Hier ein Beispiel für eine Verletzung der Regeln für ausgehenden Traffic:

egressViolations: [
{
  servicePerimeter: "accessPolicies/<POLICY_NAME>/servicePerimeters/<PERIMETER_NAME>"
  source: "projects/<NETWORK_PROJECT_NUMBER>"
  sourceType: "Network"
  targetResource: "projects/<RESOURCE_PROJECT_NUMBER>"
}
]

Dabei gilt:

  • <POLICY_NAME> ist der numerische Name Ihrer Zugriffsrichtlinie.
  • <PERIMETER_NAME> ist der Name des Dienstperimeters.
  • <NETWORK_PROJECT_NUMBER> ist die Projektnummer des Projekts von Google Cloud , das Ihr VPC-Netzwerk enthält.
  • <RESOURCE_PROJECT_NUMBER> ist die Projektnummer des Projekts von Google Cloud , das die Ressource enthält.

Im folgenden Diagramm ist ein Verstoß gegen Regeln für eingehenden Traffic zu sehen, der auftritt, wenn ein Client außerhalb des Perimeters versucht, auf ein Projekt innerhalb eines Perimeters zuzugreifen:

Eine Verletzung der Regeln für eingehenden Traffic durch NETWORK_NOT_IN_SAME_SERVICE_PERIMETER.

Hier ein Beispiel für eine Verletzung der Regeln für eingehenden Traffic:

ingressViolations: [
{
          targetResource: "projects/<RESOURCE_PROJECT_NUMBER>",
      source: "projects/<NETWORK_PROJECT_NUMBER>"
          servicePerimeter: "accessPolicies/<POLICY_NAME>/servicePerimeters/<PERIMETER_NAME>"
}
]

Dabei gilt:

  • <RESOURCE_PROJECT_NUMBER> ist die Projektnummer des Projekts von Google Cloud , das die Ressource enthält.
  • <NETWORK_PROJECT_NUMBER> ist die Projektnummer des Projekts von Google Cloud , das Ihr VPC-Netzwerk enthält.
  • <POLICY_NAME> ist der numerische Name Ihrer Zugriffsrichtlinie.
  • <PERIMETER_NAME> ist der Name des Dienstperimeters.

Lösung

Um diesen Fehler zu beheben, erstellen Sie für Ihren Perimeter eine Regel für eingehenden oder ausgehenden Traffic.

RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER

Dieses Problem tritt auf, wenn eine einzelne Anfrage auf mehrere Ressourcen zugreift, diese Ressourcen sich jedoch nicht im selben Dienstperimeter befinden. Dieses Problem tritt unabhängig davon auf, wo sich der Client befindet und ob er Zugriff auf die Ressourcen hat.

Das folgende Diagramm zeigt einen Client, der auf Ressourcen aus einem Projekt außerhalb und aus einem Projekt innerhalb des Dienstperimeters zugreift:

Ein Verstoß gegen Regeln für ausgehenden Traffic aufgrund eines Clients, der auf Ressourcen aus einem Projekt außerhalb des Perimeters zugreift.

Das folgende Diagramm zeigt einen Client, der auf Ressourcen aus Projekten zugreift, die sich in zwei verschiedenen Dienstperimetern befinden. Die Perimeter kommunizieren jedoch nicht miteinander:

Ein Verstoß beim ausgehenden Traffic, weil ein Client auf Ressourcen aus Projekten zugreift, die sich in zwei verschiedenen Dienstperimetern befinden.

Hier ein Beispiel für eine Verletzung der Regeln für ausgehenden Traffic:

egressViolations: [
{
  servicePerimeter: "accessPolicies/<POLICY_NAME>/servicePerimeters/<PERIMETER_NAME>"
  source: "projects/<RESOURCE_PROJECT_INSIDE_THIS_PERIMETER>"
  sourceType: "Resource"
  targetResource: "projects/<RESOURCE_PROJECT_OUTSIDE_THIS-PERIMETER>"
}
]

Dabei gilt:

  • <POLICY_NAME> ist der numerische Name Ihrer Zugriffsrichtlinie.
  • <PERIMETER_NAME> ist der Name des Dienstperimeters.
  • <RESOURCE_PROJECT_INSIDE_THIS_PERIMETER> ist die Projektnummer des Projekts von Google Cloud , das sich innerhalb des Perimeters befindet.
  • <RESOURCE_PROJECT_OUTSIDE_THIS_PERIMETER> ist die Projektnummer des Projekts von Google Cloud , das sich außerhalb des Perimeters befindet.

Lösung

Um dieses Problem zu beheben, erstellen Sie für Ihren Perimeter eine Regel für ausgehenden Traffic.

NO_MATCHING_ACCESS_LEVEL

Dieses Problem tritt auf, wenn die IP-Adresse, die Geräteanforderung oder die Nutzeridentität nicht mit den dem Perimeter zugewiesenen Regeln für eingehenden Traffic oder Zugriffsebenen übereinstimmen. Das heißt, ein Client, der nicht Teil des Netzwerks von Google Cloud ist, versucht, von außerhalb des Perimeters auf Ressourcen des Google Cloud -Netzwerks zuzugreifen. Dabei stimmt beispielsweise die IP-Adresse, die dem Feld callerIp des Audit-Eintrags entspricht, mit keinem der CIDR-Bereiche überein, die in den Zugriffsebenen für den Dienstperimeter definiert sind.

Fehlt die IP-Adresse des Aufrufers oder wird sie als interne IP-Adresse angezeigt, ist der Verstoß möglicherweise auf einen Dienst von Google Cloud zurückzuführen, der nicht in VPC Service Controls integriert ist. Möglicherweise versucht der Dienst vonGoogle Cloud auf einen geschützten Dienst zuzugreifen, was erwartungsgemäß fehlschlägt.

Um dieses Problem zu beheben, empfehlen wir, anstelle einer Zugriffsebene eine Regel für eingehenden Traffic zu erstellen, da eine solche Regel eine detaillierte Zugriffssteuerung ermöglicht.

Das folgende Diagramm zeigt einen Client, der versucht, von außerhalb des Perimeters auf Ressourcen zuzugreifen:

Hier ein Beispiel für einen Verstoß aufgrund von NO_MATCHING_ACCESS_LEVEL.

Hier ein Beispiel für eine Verletzung der Regeln für eingehenden Traffic:

authenticationInfo: {
  principalEmail: "EMAIL"
}
requestMetadata: {
callerIp: "<PUBLIC_IP_ADDRESS>"
deviceState: "Cross Organization"
}
ingressViolations: [
        {
          targetResource: "projects/<RESOURCE_PROJECT_NUMBER>",
          servicePerimeter: "accessPolicies/<POLICY_NAME>/servicePerimeters/<PERIMETER-NAME>"
        }
  ]

Dabei gilt:

  • <EMAIL> ist die E-Mail-Adresse des Dienstkontos oder authentifizierten Nutzers.

    Wenn Sie einen Dienst von Google Cloud verwenden, der nicht von VPC Service Controls unterstützt wird, werden E-Mail-Adressen, die zur Domain google.com gehören, unkenntlich gemacht und durch google-internal ersetzt. google-internal bezieht sich auf interne Google-Identitäten.

  • <PUBLIC_IP_ADDRESS> ist die IP-Adresse des Aufrufers. Für Aufrufer aus dem Internet ist dies die öffentliche IPv4- oder IPv6-Adresse.

  • <RESOURCE_PROJECT_NUMBER> ist die Projektnummer des Projekts in Google Cloud , das die Ressource enthält.

  • <POLICY_NAME> ist der numerische Name Ihrer Zugriffsrichtlinie.

  • <PERIMETER_NAME> ist der Name des Dienstperimeters.

Beachten Sie, dass in diesem Fall metadata.accessLevels trotzdem vorhanden sein könnte, da diese Zugriffsebenen im verletzten Perimeter möglicherweise nicht angegeben sind.

SERVICE_NOT_ALLOWED_FROM_VPC

Dieses Problem tritt auf, wenn ein Client versucht, über ein VPC-Netzwerk auf Ressourcen von Google Cloud zuzugreifen. Der Client sendet die Anfrage möglicherweise von einer Compute Engine-VM bzw. Google Kubernetes Engine-VM oder von einem lokalen Netzwerk über Cloud Interconnect oder einem VPN, das mit einem VPC-Netzwerk konfiguriert wurde.

Prüfen Sie zur Behebung dieses Problems, ob der aufgerufene Dienst in der Konfiguration der zugänglichen VPC-Dienste des Dienstperimeters zugelassen ist.

Beispielszenarien

Die folgenden Beispiele decken Probleme ab, die bei der Verwendung von VPC Service Controls auftreten können.

Cloud Storage-Zugriff aus lokaler Umgebung

In diesem Beispiel blockiert VPC Service Controls eine Anfrage von einer Mitarbeiter-Workstation (identifiziert durch callerIp) an einen Cloud Storage-Bucket im Projekt corp-storage.

Die Anfrage generiert den folgenden Eintrag im Audit-Log:

{
 insertId:  "222lvajc6f7"
 logName:  "projects/corp-storage/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "someone@google.com"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/_"
   ]
   violationReason:  "NO_MATCHING_ACCESS_LEVEL"
  }
  methodName:  "google.storage.NoBillingOk"
  requestMetadata: {
   callerIp:  "b1d5:d26d:5b17:43fe:d358:586b:db59:9617"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/690885588241"
  serviceName:  "storage.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-27T21:40:43.823209571Z"
 resource: {
  labels: {
   method:  "google.storage.NoBillingOk"
   project_id:  "corp-storage"
   service:  "storage.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-27T21:40:42.973784140Z"
}

Das Projekt corp-storage ist in einem Dienstperimeter enthalten. Die Mitarbeiter-Workstation gehört nicht zu einem Netzwerk innerhalb dieses Perimeters. Die Anfrage wird blockiert, da sich die Mitarbeiter-Workstation außerhalb des Perimeters befindet.

BigQuery-Zugriff von einer VM außerhalb des Projekts

In diesem Beispiel versucht eine VM aus dem Projekt 458854174376 (data-collector), eine BigQuery-Abfrage für ein Dataset im Projekt 798816221974 (corp-resources-protected) auszuführen. Der Zugriff wird verweigert.

Die VM führt folgende Abfrage aus:

bq --project=corp-resources-protected query 'select count(*) from babynames.yob2000'

Die Abfrage gibt die folgende Ausgabe zurück:

BigQuery error in query operation: VPC Service Controls: Request is
prohibited by organization's policy. Operation ID:
33643962-6a0f-4091-9283-bcdf7e9271f0

Der folgende Eintrag ins Audit-Log wird generiert:

{
 insertId:  "1ei551d2pdq"
 logName:  "projects/corp-resources-protected/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "714877721106-compute@developer.gserviceaccount.com"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/1004338142803"
   ]
   violationReason:  "NETWORK_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "bigquery.googleapis.com/bigquery.jobs.create"
  requestMetadata: {
   callerIp:  "10.105.0.2"
   callerNetwork:  "//compute.googleapis.com/projects/ameet-dataflow/global/networks/__unknown__"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/1004338142803"
  serviceName:  "bigquery.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-28T23:06:13.579882505Z"
 resource: {
  labels: {
   method:  "bigquery.googleapis.com/bigquery.jobs.create"
   project_id:  "corp-resources-protected"
   service:  "bigquery.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-28T23:06:12.799656975Z"
}

Die violationReason in diesem Beispiel lautet NETWORK_NOT_IN_SAME_SERVICE_PERIMETER. Neben callerNetwork wird callerIp aufgeführt. Die IP-Adresse ist privat und das Netzwerk wird zur Unterscheidung angegeben. Die relevanten Ressourcen sind an zwei Stellen aufgelistet: VpcServiceControlAuditMetadata.resourceNames und requestMetadata.callerNetwork (das Projekt, dem das Netzwerk angehört).

Das Problem besteht darin, dass sich das Projekt corp-resources-protected in einem Dienstperimeter befindet und sich das Projekt data-collector, das das Netzwerk enthält, zu dem die VM gehört, nicht in einem Perimeter befindet. Der Zugriff wird in diesem Fall erwartungsgemäß verweigert.

Projektübergreifende BigQuery-Abfrage

In diesem Beispiel versucht eine VM aus dem Projekt perimeter-network, die BigQuery-Instanzen von zwei verschiedenen Projekten abzufragen: corp-resources-protected, das sich im gleichen Dienstperimeter befindet wie perimeter-network, und corp-resources-public, das sich nicht im gleichen Perimeter befindet.

Die VM führt den folgenden Befehl aus:

bq query --use_legacy_sql=false \
    'select count(priv.name),count(pub.name) from \
    `corp-resources-protected.babynames.yob2000` as priv, \
    `corp-resources-public.babynames.yob2000` as pub'

Die Abfrage gibt die folgende Ausgabe zurück:

BigQuery error in query operation: Error processing job
'example:bqjob_r211e6f6eec928ffb_000001675c996aa8_1': VPC Service Controls:
Request is prohibited by organization's policy. Operation ID:
dc4fc177-4850-4fc5-b2e7-8c33f302149a

Der folgende Eintrag ins Audit-Log wird generiert:

{
 insertId:  "17kg4exd24ag"
 logName:  "projects/perimeter-network/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/117961063178"
    1:  "projects/690885588241"
   ]
   violationReason:  "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "bigquery.googleapis.com/bigquery.tables.getData"
  requestMetadata: {
   callerIp:  "130.211.225.66"
   callerNetwork:  "//compute.googleapis.com/projects/perimeter-network/global/networks/__unknown__"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/927005422713"
  serviceName:  "bigquery.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-28T20:48:51.384237810Z"
 resource: {
  labels: {
   method:  "bigquery.googleapis.com/bigquery.tables.getData"
   project_id:  "perimeter-network"
   service:  "bigquery.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-28T20:48:50.561884949Z"
}

Bei der Betrachtung von callerNetwork und VpcServiceControlAuditMetadata.resourceNames sehen wir drei Projekte: perimeter-network, 117961063178 (corp-resources-public) und 690885588241 (corp-resources-protected). corp-resources-public befindet sich, wie oben beschrieben, nicht im gleichen Dienstperimeter wie perimeter-network und corp-resources-protected.

Die violationReason RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER gibt an, dass sich eine Ressource in der Anfrage außerhalb eines Perimeters befindet, der für die Anfrage gilt. Das ist in diesem Fall corp-resources-public.

Verschieben von Cloud Storage-Datei innerhalb des Perimeters

In diesem Beispiel wird von einer VM im Projekt perimeter-network ein Befehl ausgeführt, um eine Datei von einem Cloud Storage-Bucket im Projekt corp-resources-protected in einen anderen Bucket im Projekt corp-resources-public zu verschieben.

Die VM führt den folgenden Befehl aus:

gcloud storage mv gs://corp-resources-private-1/yob2000.txt gs://corp-resources-public-1/babynames/

Der Befehl gibt die folgende Ausgabe zurück:

Copying gs://corp-resources-private-1/yob2000.txt [Content-Type=text/plain]...
AccessDeniedException: 403 Request violates VPC Service Controls.

Der folgende Eintrag ins Audit-Log wird generiert:

{
 insertId:  "1xxnssmd2hqo"
 logName:  "projects/perimeter-network/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "storage-accessing@example.iam.gserviceaccount.com"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/_/buckets/corp-resources-public-1"
   ]
   violationReason:  "NETWORK_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "google.storage.BillingRequiredRead"
  requestMetadata: {
   callerIp:  "130.211.225.66"
   callerNetwork:  "//compute.googleapis.com/projects/perimeter-network/global/networks/__unknown__"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/927005422713"
  serviceName:  "storage.googleapis.com"
  status: {}
 }
 receiveTimestamp:  "2018-11-28T00:45:31.531623485Z"
 resource: {
  labels: {
   method:  "google.storage.BillingRequiredRead"
   project_id:  "perimeter-network"
   service:  "storage.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-28T00:45:31.351140381Z"
}

In diesem Fall enthält das Log nicht so klare Informationen, da die aufgelistete Methode BillingRequiredRead und die durchgeführte Aktion move lautet. Dies ist eine Einschränkung der derzeitigen Audit-Logfunktionalität von VPC Service Controls.

Obwohl die Ursache des Fehlers weniger eindeutig ist, zeigt dieser Audit-Logeintrag, dass sich eine Ressource in der Anfrage außerhalb eines Perimeters befindet, der für die Anfrage gilt. Das ist in diesem Fall corp-resources-public.

Verschieben von Cloud Storage-Datei außerhalb des Perimeters

In diesem Beispiel wird von einer VM im Projekt public-network ein Befehl ausgeführt, um eine Datei von einem Cloud Storage-Bucket im Projekt corp-resources-protected in einen anderen Bucket im Projekt corp-resources-public zu verschieben.

Das Projekt corp-resources-protected ist durch einen Dienstperimeter geschützt. Die Projekte public-network und corp-resources-public befinden sich außerhalb des Perimeters.

Die VM führt den folgenden Befehl aus:

gcloud storage mv gs://corp-resources-private-1/yob2000.txt gs://corp-resources-public-1/babynames/

Der Befehl gibt die folgende Ausgabe zurück:

Copying gs://corp-resources-private-1/yob2000.txt [Content-Type=text/plain]...
AccessDeniedException: 403 Request violates VPC Service Controls.

Der folgende Eintrag ins Audit-Log wird generiert:

{
 insertId:  "10moqhsch9v"
 logName:  "projects/corp-resources-private/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "user@example.biz"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/_/buckets/corp-resources-private-1/objects/yob2000.txt"
    1:  "projects/_/buckets/corp-resources-public-1/objects/out.txt"
   ]
   violationReason:  "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "google.storage.Write"
  requestMetadata: {
   callerIp:  "2620:15c:2c4:203:63d6:5eb8:418d:c034"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/1004338142803"
  serviceName:  "storage.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-30T16:34:46.948010626Z"
 resource: {
  labels: {
   method:  "google.storage.Write"
   project_id:  "corp-resources-private"
   service:  "storage.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-30T16:34:46.898098978Z"
}

In diesem Beispiel weist das Audit-Log darauf hin, dass das Kopieren von Daten über die Grenze eines Dienstperimeters hinweg nicht möglich ist (beide Ressourcen werden im Audit-Logeintrag genannt). Die Anfrage stammt von außerhalb des Perimeters (von der VM in public-network) und einer der Buckets befindet sich außerhalb des Perimeters (corp-resources-public-1).

Der Schreibvorgang in den Bucket corp-resources-public-1 von außerhalb des Perimeters kann ausgeführt werden. Die Prüfung, die im vorherigen Beispiel den Fehler ausgelöst hat, wird hier also bestanden. Bei der nachfolgenden Prüfung des eigentlichen Kopiervorgangs wird jedoch ein Fehler ausgegeben.

Dieses Beispiel zeigt, dass ein einzelner Nutzervorgang manchmal mehrere interne Vorgänge nach sich zieht, die eine Prüfung anhand der Regeln von VPC Service Controls bestehen müssen.

BigQuery-Dataset wird von einer VM innerhalb des Perimeters kopiert

In diesem Beispiel versucht eine VM im Projekt 927005422713 (perimeter-network), ein BigQuery-Dataset aus dem Projekt corp-resources-private in das Projekt corp-resources-public (117961063178) zu kopieren. perimeter-network und corp-resources-private teilen sich einen Perimeter, corp-resources-public befindet sich außerhalb des Perimeters.

Die VM führt den folgenden Befehl aus:

bq cp corp-resources-private:babynames.yob2000 \
    corp-resources-public:babynames.yob2000

Der Befehl gibt die folgende Ausgabe zurück:

BigQuery error in cp operation: VPC Service Controls: Request is prohibited by
organization's policy. Operation ID: c00dbc44-460f-4bd0-9d09-cda98ac800f9

Der folgende Eintrag ins Audit-Log wird generiert:

{
 insertId:  "146o5fd2hbp"
 logName:  "projects/perimeter-network/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/117961063178"
   ]
   violationReason:  "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "bigquery.googleapis.com/bigquery.tables.get"
  requestMetadata: {
   callerIp:  "131.201.221.16"
   callerNetwork:  "//compute.googleapis.com/projects/perimeter-network/global/networks/__unknown__"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/927005422713"
  serviceName:  "bigquery.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-28T00:27:05.688803777Z"
 resource: {
  labels: {
   method:  "bigquery.googleapis.com/bigquery.tables.get"
   project_id:  "perimeter-network"
   service:  "bigquery.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-28T00:27:05.378584819Z"
}

In diesem Beispiel gibt es aufgrund der Einschränkungen des Logging-Mechanismus und der verteilten Architektur von BigQuery keine einzelne zugrunde liegende API-Aktion, die alle an dieser Anfrage beteiligten Ressourcen aufzeigt.

Der Audit-Logeintrag zeigt, dass der Vorgang fehlgeschlagen ist, weil BigQuery zum Kopieren der Daten über das Netzwerk im Projekt perimeter-network (die Quelle der Anfrage) auf das Zielprojekt (corp-resources-public) zugreifen muss. corp-resources-public befindet sich jedoch außerhalb des Perimeters, der perimeter-network schützt. Die Anfrage wird als Versuch, Daten an corp-resources-public zu übertragen, verweigert.

Das Beispiel veranschaulicht, dass ein allgemeiner Vorgang wie das Kopieren von Daten mehrere Datenzugriffsversuche von verschiedenen Speichersystemen auslösen kann, etwa Cloud Storage, BigQuery und Bigtable. Je nachdem, wie der Vorgang ausgeführt wird, unterscheidet sich der generierte Audit-Logeintrag vom ursprünglichen Nutzerbefehl. Wenn mehrere Prüfungen innerhalb eines bestimmten Dienstes durchgeführt werden und möglicherweise fehlschlagen, sieht der generierte Audit-Logeintrag ebenfalls anders aus als der ursprüngliche Nutzerbefehl.

Dataproc-Job liest aus Projekt

In diesem Beispiel wird gezeigt, wie Sie indirekte VPC Service Controls-Fehler beheben, die auftreten, wenn Sie Datenverarbeitungsdienste wie Dataproc verwenden.

In diesem Beispiel wird ein Dataproc-Cluster in einem Projekt ausgeführt, das durch VPC Service Controls geschützt wird. Hello-world.py ist ein PySpark-Job, der versucht, auf Daten im Cloud Storage-Bucket innerhalb des Perimeters zuzugreifen und sie dann in einen Bucket außerhalb des Perimeters zu schreiben. VPC Service Controls blockiert den Vorgang, bei dem Daten in einen Bucket außerhalb des Perimeters geschrieben werden.

Hello-world.py wird mit dem folgenden Befehl ausgeführt:

gcloud dataproc jobs submit pyspark hello-world.py --cluster test-cluster-new2

Der Befehl gibt die folgende Ausgabe zurück:

Job [50f16ca8-5102-442b-a545-eed5e4f5f5da] submitted.
Waiting for job output...
18/11/29 00:31:34 INFO org.spark_project.jetty.util.log: Logging initialized @2552ms
18/11/29 00:31:34 INFO org.spark_project.jetty.server.Server: jetty-9.3.z-SNAPSHOT
18/11/29 00:31:34 INFO org.spark_project.jetty.server.Server: Started @2640ms
18/11/29 00:31:34 INFO org.spark_project.jetty.server.AbstractConnector: Started ServerConnector@1f1c18ec{HTTP/1.1,[http/1.1]}{0.0.0.0:4040}
18/11/29 00:31:34 INFO com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystemBase: GHFS version: 1.6.4-hadoop2
18/11/29 00:31:35 INFO org.apache.hadoop.yarn.client.RMProxy: Connecting to ResourceManager at test-cluster-new2-m/10.246.0.3:8032
18/11/29 00:31:37 INFO org.apache.hadoop.yarn.client.api.impl.YarnClientImpl: Submitted application application_1522454176466_0005
Traceback (most recent call last):
  File "/tmp/50f16ca8-5102-442b-a545-eed5e4f5f5da/hello-world.py", line 8, in <module>
    lear.saveAsTextFile("gs://corp-resources-public-1/out.txt")
  File "/usr/lib/spark/python/lib/pyspark.zip/pyspark/rdd.py", line 1553, in saveAsTextFile
  File "/usr/lib/spark/python/lib/py4j-0.10.4-src.zip/py4j/java_gateway.py", line 1133, in __call__
  File "/usr/lib/spark/python/lib/py4j-0.10.4-src.zip/py4j/protocol.py", line 319, in get_return_value
py4j.protocol.Py4JJavaError: An error occurred while calling o49.saveAsTextFile.
: java.io.IOException: Error accessing: bucket: corp-resources-public-1, object: out.txt
    at com.google.cloud.hadoop.gcsio.GoogleCloudStorageImpl.wrapException(GoogleCloudStorageImpl.java:1767)
$sp(PairRDDFunctions.scala:961)

 (truncated)

Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Request violates VPC Service Controls.",
    "reason" : "vpcServiceControls"
  } ],
  "message" : "Request violates VPC Service Controls."
}
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)

 (truncated)

18/11/29 00:31:43 INFO org.spark_project.jetty.server.AbstractConnector: Stopped Spark@1f1c18ec{HTTP/1.1,[http/1.1]}{0.0.0.0:4040}
ERROR: (gcloud.dataproc.jobs.submit.pyspark) Job [50f16ca8-5102-442b-a545-eed5e4f5f5da] entered state [ERROR] while waiting for [DONE].

Achten Sie auf die E/A-Ausnahme, die beim Aufruf von saveAsTextFile auftritt. Cloud Storage gibt einen 403-Fehler mit der Meldung Request violates VPC Service Controls zurück. Der Fehler weist darauf hin, dass der Cloud Storage-Audit-Logvorgang überprüft werden muss.

In den Audit-Logs für das Projekt perimeter-network, in dem der Befehl ausgeführt wurde, liegt ein Audit-Logeintrag für den Vorgang saveAsTextFile vor:

{
 insertId:  "qdj1o9d1run"
 logName:  "projects/corp-resources-private/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "1004338142803-compute@developer.gserviceaccount.com"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/_/buckets/corp-resources-public-1/objects/out.txt"
   ]
   violationReason:  "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "google.storage.BillingRequiredRead"
  requestMetadata: {
   callerIp:  "10.246.0.3"
   callerNetwork:  "//compute.googleapis.com/projects/corp-resources-private/global/networks/__unknown__"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/1004338142803"
  serviceName:  "storage.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-29T00:31:43.666227930Z"
 resource: {
  labels: {
   method:  "google.storage.BillingRequiredRead"
   project_id:  "corp-resources-private"
   service:  "storage.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-29T00:31:43.608250320Z"
}

Aufgrund von Audit-Logeinschränkungen wird der methodName für Cloud Storage als Read aufgelistet, obwohl es sich um einen write-Vorgang handelt. Der Audit-Logeintrag zeigt, dass der Vorgang fehlgeschlagen ist, da ein Netzwerk in Projekt corp-resources-private versucht hat, auf die Daten einer Ressource im Bucket corp-resources-public-1 zuzugreifen (in diesem Fall per Schreibzugriff). Aufgrund der Einschränkungen des Audit-Logs von Cloud Storage ist nicht klar, zu welchem Projekt-Bucket corp-resources-public-1 gehört.

Mit dem folgenden Befehl wird das Projekt ermittelt, das corp-resources-public-1 enthält:

gcloud storage ls gs://corp-resources-public-1 --buckets --log-http 2>&1 | grep projectNumber

Der Befehl "projectNumber": "117961063178", gibt die folgende Ausgabe zurück:

117961063178 ist das Projekt corp-resources-public, das sich außerhalb des Perimeters befindet. Deshalb schlägt der Vorgang erwartungsgemäß fehl.

Fehler aufgrund nicht unterstützter Dienste

Einige Dienste von Google Cloud sind für ihre Implementierung auf andere Dienste von Google Cloud angewiesen. Wird ein nicht unterstützter Dienst wie App Engine innerhalb eines durch einen Perimeter geschützten Projekts verwendet, sind die Ressourcen des Dienstes möglicherweise nicht zugänglich.

Informationen zu bekannten Problemfällen finden Sie unter Bekannte Diensteinschränkungen.

Nicht unterstützter Dienst mit eingeschränkter VIP

Der versuchte Zugriff auf eine API, die von der eingeschränkten VIP von VPC Service Controls nicht unterstützt wird, führt zu einem 403-Fehler. Beispielsweise wird App Engine von VPC Service Controls nicht unterstützt, das heißt, die App Engine Admin API ist mit einer eingeschränkten VIP nicht verfügbar.

Angenommen, der folgende Befehl wird ausgeführt, um alle App Engine-Dienste innerhalb eines Dienstperimeters aufzulisten:

gcloud app services list

Der Befehl gibt die folgende Ausgabe zurück:

ERROR: (gcloud.app.services.list) User [***] does not have permission to access apps instance [***] (or it may not exist): <!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
  <title>Error 403 (Forbidden)!!1</title>
  <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){ #logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){ #logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
  </style>
  <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
  <p><b>403.</b> <ins>That's an error.</ins>
  <p>Your client does not have permission to get URL <code>/v1/apps/***/services</code> from this server.  <ins>That's all we know.</ins>

Diese Art von Fehler ist bei Diensten zu erwarten, die von VPC Service Controls nicht unterstützt werden und die über die eingeschränkte VIP nicht verfügbar sind. Wenn der Fehler bei einem von VPC Service Controls unterstützten Dienst auftritt, empfehlen wir Ihnen, unter bekannte Diensteinschränkungen zu überprüfen, ob es sich um eine bekannte Einschränkung handelt. Wenn das nicht der Fall ist, sollten Sie das Problem melden.

Logexport in ein Projekt außerhalb des Perimeters

In diesem Beispiel wird ein Logexport von VPC Service Controls blockiert. Das Exportziel, Projekt corp-resources-public, befindet sich außerhalb des Perimeters von VPC Service Controls, und die Senke wird im Projekt perimeter-network innerhalb des Perimeters erstellt.

Als Beispiel wird der folgende Code ausgeführt:

gcloud logging sinks describe example-sink

Der Befehl gibt die folgende Ausgabe zurück:

destination: bigquery.googleapis.com/projects/corp-resources-public/datasets/logs
filter: |-
  resource.type="audited_resource"
  resource.labels.service="bigquery.googleapis.com"
name: example-sink
outputVersionFormat: V2
writerIdentity: serviceAccount:p927005422713-439672@gcp-sa-logging.iam.gserviceaccount.com

Der folgende Eintrag ins Audit-Log wird generiert:

{
 insertId:  "e5i2i8cbqw"
 logName:  "projects/perimeter-network/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "p927005422713-439672@gcp-sa-logging.iam.gserviceaccount.com"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "corp-resources-public"
   ]
   violationReason:  "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "google.cloud.bigquery.v2.TableDataService.InsertAll"
  requestMetadata: {
   callerIp:  "2002:a49:8c51::"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/927005422713"
  serviceName:  "bigquery.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-11-29T17:32:19.287138882Z"
 resource: {
  labels: {
   method:  "google.cloud.bigquery.v2.TableDataService.InsertAll"
   project_id:  "perimeter-network"
   service:  "bigquery.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-11-29T17:32:19.054662413Z"
}

Der Audit-Log-Eintrag wird für BigQuery generiert, nicht für Logging. Das liegt daran, dass BigQuery der Senkendienst ist, in den Logging zu schreiben versucht.

Der Export schlägt fehl, weil sich corp-resources-public außerhalb des Perimeters befindet, mit dem perimeter-network geschützt wird.

Dieses Beispiel zeigt: Wenn ein Dienst von Google Cloud ein GCP-internes verwaltetes Dienstkonto wie p927005422713-439672@gcp-sa-logging.iam.gserviceaccount.com verwendet, um einen anderen Dienst von Google Cloudaufzurufen, wird das "Netzwerkprojekt" der Anfrage (in diesem Fall perimeter-network) von dieser Identität abgeleitet. Dieselbe Identität stellt auch die Logexport-Ressource dar.

Dieses Muster ist in Google Cloud häufig anzutreffen und gilt für zahlreiche Fälle der Interaktion zwischen Diensten.

BigQuery-Extraktion in Cloud Storage

In diesem Beispiel wird die Fehlerbehebung für fehlgeschlagene BigQuery-Extraktionen in Cloud Storage beschrieben.

Die Projekte corp-resources-private und perimeter-network werden durch einen Dienstperimeter geschützt. Das Projekt corp-resources-public befindet sich außerhalb des Perimeters.

Der folgende Befehl wird ausgeführt:

bq extract babynames.yob2000

Der Befehl gibt die folgende Ausgabe zurück:

gs://corp-resources-public-1/export.txt
Waiting on bqjob_r47ee34109d02b41_000001676b27157c_1 ... (1s) Current status: DONE
BigQuery error in extract operation: Error processing job 'corp-resources-private:bqjob_r47ee34109d02b41_000001676b27157c_1': Access
Denied: BigQuery BigQuery: Permission denied while writing data.

In diesem Fall betrifft der Fehler nicht speziell VPC Service Controls. Die Ausgabe ist ähnlich, wenn bei der Identitäts- und Zugriffsverwaltung ein Fehler auftritt.

Der folgende Eintrag ins Audit-Log wird generiert:

{
 insertId:  "4gbh6pe8jld7"
 logName:  "projects/corp-resources-private/logs/cloudaudit.googleapis.com%2Fdata_access"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "storage-accessing@example.iam.gserviceaccount.com"
  }
  methodName:  "jobservice.jobcompleted"
  requestMetadata: {
   callerIp:  "10.5.0.4"
   callerNetwork:  "//compute.googleapis.com/projects/perimeter-network/global/networks/__unknown__"
   callerSuppliedUserAgent:  "google-api-python-client/1.6.5 (gzip),gzip(gfe)"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/corp-resources-private/jobs/bqjob_r47ee34109d02b41_000001676b27157c_1"
  serviceData: {
   @type:  "type.googleapis.com/google.cloud.bigquery.logging.v1.AuditData"
   jobCompletedEvent: {
    eventName:  "extract_job_completed"
    job: {
     jobConfiguration: {
      extract: {
       destinationUris: [
        0:  "gs://corp-resources-public-1/export.txt"
       ]
       sourceTable: {
        datasetId:  "babynames"
        projectId:  "corp-resources-private"
        tableId:  "yob2000"
       }
      }
     }
     jobName: {
      jobId:  "bqjob_r47ee34109d02b41_000001676b27157c_1"
      location:  "US"
      projectId:  "corp-resources-private"
     }
     jobStatistics: {
      createTime:  "2018-12-01T19:03:03.908Z"
      endTime:  "2018-12-01T19:03:05.494Z"
      startTime:  "2018-12-01T19:03:04.013Z"
     }
     jobStatus: {
      additionalErrors: [
       0: {
        code:  7
        message:  "Access Denied: BigQuery BigQuery: Permission denied while writing data."
       }
      ]
      error: {
       code:  7
       message:  "Access Denied: BigQuery BigQuery: Permission denied while writing data."
      }
      state:  "DONE"
     }
    }
   }
  }
  serviceName:  "bigquery.googleapis.com"
  status: {
   code:  7
   message:  "Access Denied: BigQuery BigQuery: Permission denied while writing data."
  }
 }
 receiveTimestamp:  "2018-12-01T19:03:05.532169998Z"
 resource: {
  labels: {
   project_id:  "corp-resources-private"
  }
  type:  "bigquery_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-12-01T19:03:05.503Z"
}

In diesem Audit-Logeintrag wird storage-accessing@example.iam.gserviceaccount.com als Identität ermittelt, die den Vorgang auszuführen versucht. Wir gehen in diesem Beispiel davon aus, dass storage-accessing@example.iam.gserviceaccount.com die erforderlichen IAM-Berechtigungen zum Ausführen des Befehls hat.

Da das Problem nicht auf die IAM-Berechtigungen zurückzuführen ist, sollten wir als Nächstes prüfen, ob VPC Service Controls-Fehler vorliegen.

Der Audit-Logeintrag für den Zieldienst (Cloud Storage) enthält detaillierte Informationen zu den Fehlerursachen:

{
 insertId:  "1bq397kcfj1"
 logName:  "projects/corp-resources-private/logs/cloudaudit.googleapis.com%2Fpolicy"
 protoPayload: {
  @type:  "type.googleapis.com/google.cloud.audit.AuditLog"
  authenticationInfo: {
   principalEmail:  "storage-accessing@example.iam.gserviceaccount.com"
  }
  metadata: {
   @type:  "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
   resourceNames: [
    0:  "projects/1004338142803"
    1:  "projects/_/buckets/corp-resources-public-1"
   ]
   violationReason:  "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
  }
  methodName:  "google.storage.BillingRequiredRead"
  requestMetadata: {
   callerIp:  "10.5.0.4"
   callerNetwork:  "//compute.googleapis.com/projects/perimeter-network/global/networks/__unknown__"
   destinationAttributes: {
   }
   requestAttributes: {
   }
  }
  resourceName:  "projects/1004338142803"
  serviceName:  "storage.googleapis.com"
  status: {
   code:  7
   details: [
    0: {
     @type:  "type.googleapis.com/google.rpc.PreconditionFailure"
     violations: [
      0: {
       type:  "VPC_SERVICE_CONTROLS"
      }
     ]
    }
   ]
   message:  "Request is prohibited by organization's policy"
  }
 }
 receiveTimestamp:  "2018-12-01T19:03:05.617451586Z"
 resource: {
  labels: {
   method:  "google.storage.BillingRequiredRead"
   project_id:  "corp-resources-private"
   service:  "storage.googleapis.com"
  }
  type:  "audited_resource"
 }
 severity:  "ERROR"
 timestamp:  "2018-12-01T19:03:05.420005215Z"
}

Aus diesem Log geht hervor, dass beide Projekte, 1004338142803 (corp-resources-private-1) und corp-resources-public, verwendet werden, um den Befehl abzuschließen. Da diese Projekte nicht dem gleichen Perimeter angehören, schlägt der Extraktionsjob fehl.

Dieses Beispiel verdeutlicht, dass die Audit-Logs bei komplexen Vorgängen mit mehreren Diensten sowohl für den Quell- als auch für den Zieldienst nützliche Debugging-Daten enthalten können.

Perimeterzugriff über Cloud NAT-Gateway

In diesem Beispiel wird davon ausgegangen, dass Projekt A aus Organisation A in keinem Perimeter konfiguriert ist. Projekt B wird durch einen Perimeter in einer anderen Organisation geschützt. Private Ressourcen in Projekt A verwenden das Cloud NAT-Gateway, um das Internet sowie Google APIs und ‑Dienste zu erreichen. Für Projekt B ist eine Zugriffsebene konfiguriert, die den Zugriff auf Grundlage der externen Gateway-IP-Adressen von Projekt A zulässt.

Eine VM, die zu Projekt A gehört (kann ein Google Kubernetes Engine-Knoten sein), versucht, auf eine geschützte Ressource in Projekt B zuzugreifen. Die Verbindung schlägt jedoch fehl und in Projekt B wird der folgende Audit-Log-Eintrag generiert:

{
  "protoPayload": {
    "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
    "status": {
      "code": 7,
      "message": "Request is prohibited by organization's policy. vpcServiceControlsUniqueIdentifier: kmpY9Fgfuhgi2NE90lURjFWuiS1nGRqxCw4L12HdW8h46Un__-_LZw",
      "details": [
        {
          "@type": "type.googleapis.com/google.rpc.PreconditionFailure",
          "violations": [
            {
              "type": "VPC_SERVICE_CONTROLS",
              "description": "kmpY9Fgfuhgi2NE90lURjFWuiS1nGRqxCw4L12HdW8h46Un__-_LZw"
            }
          ]
        }
      ]
    },
    "authenticationInfo": {
      "principalEmail": "my-user@example.iam.gserviceaccount.com",
      "serviceAccountKeyName": "//iam.googleapis.com/projects/my-project/serviceAccounts/my-user@example.iam.gserviceaccount.com/keys/<code><var>ACCOUNT_KEY</var></code>"
    },
    "requestMetadata": {
      "callerIp": "gce-internal-ip",
      "requestAttributes": {},
      "destinationAttributes": {}
    },
    "serviceName": "cloudfunctions.googleapis.com",
    "methodName": "google.cloud.functions.v1.CloudFunctionsService.ListFunctions",
    "resourceName": "<code><var>PROJECT_ID_1</var></code>",
    "metadata": {
      "violationReason": "NETWORK_NOT_IN_SAME_SERVICE_PERIMETER",
      "resourceNames": [
        "projects/<code><var>PROJECT_ID_2</var></code>/locations/-"
      ],
      "securityPolicyInfo": {
        "servicePerimeterName": "accessPolicies/<code><var>ACCESS_POLICY</var></code>/servicePerimeters/us_sandbox",
        "organizationId": "<code><var>ORGANIZATION_ID</var></code>"
      },
      "deviceState": "Unknown",
      "vpcServiceControlsUniqueId": "kmpY9Fgfuhgi2NE90lURjFWuiS1nGRqxCw4L12HdW8h46Un__-_LZw",
      "ingressViolations": [
        {
          "targetResource": "projects/<code><var>PROJECT_ID_1</var></code>",
          "servicePerimeter": "accessPolicies/<code><var>ACCESS_POLICY</var></code>/servicePerimeters/<code><var>PERIMETER_NAME</var></code>",
          "source": "<code><var>PROJECT_ID_2</var></code>"
        }
      ],
      "@type": "type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
    }
  },
  "insertId": "tzf7fd103i",
  "resource": {
    "type": "audited_resource",
    "labels": {
      "service": "cloudfunctions.googleapis.com",
      "method": "google.cloud.functions.v1.CloudFunctionsService.ListFunctions",
      "project_id": "<code><var>PROJECT_ID_2</var></code>"
    }
  },
  "timestamp": "2024-04-02T19:56:10.770681816Z",
  "severity": "ERROR",
  "logName": "projects/<code><var>PROJECT_ID_2</var></code>/logs/cloudaudit.googleapis.com%2Fpolicy",
  "receiveTimestamp": "2024-04-02T19:56:11.463811603Z"
}

Die Ressource callerIp zeichnet keine externe IP-Adresse auf. Anstelle der externen IP-Adresse des Cloud NAT-Gateways wird in der callerIp-Ressource gce-internal-ip angezeigt.

Das Feld callerIp wird zu gce-internal-ip geändert, wenn die Anfragen aus einem anderen Projekt oder einer anderen Organisation stammen und die Quell-Compute Engine-VM keine externe IP-Adresse hat.

Cloud NAT ist in den privaten Google-Zugriff eingebunden. Dadurch wird der private Google-Zugriff automatisch im Subnetz der Ressource aktiviert. Der Traffic zu Google APIs und ‑Diensten bleibt intern und wird nicht über die externe IP-Adresse des Cloud NAT-Gateways ins Internet geleitet.

Da der Traffic in diesem Fall innerhalb des internen Google-Netzwerks weitergeleitet wird, wird das Feld RequestMetadata.caller_ip des AuditLog-Objekts zu gce-internal-ip geändert. Um dieses Problem zu beheben, konfigurieren Sie für die IP-basierte Zulassungsliste anstelle der externen IP-Adresse des Cloud NAT-Gateways in der Zugriffsebene eine Regel für eingehenden Traffic, um den Zugriff vom Projekt oder Dienstkonto zuzulassen.

Nächste Schritte