Auf dieser Seite werden verschiedene Probleme aufgeführt, die beim Konfigurieren von VPC Service Controls auftreten können.
Unerwartetes Verhalten von Richtlinien mit begrenztem Geltungsbereich
Möglicherweise stellen Sie unerwartete VPC Service Controls-Verstöße fest, die gemäß Ihrer richtlinienbasierten Zugriffssteuerung zulässig sein sollten. Es ist ein bekanntes Problem, dass es zu unerwarteten Problemen mit Ihren Zugriffsrichtlinien mit begrenztem Umfang kommen kann, wenn Sie keine Zugriffsrichtlinie auf Organisationsebene haben.
Um dieses 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 Folgendes:
- ORGANIZATION_ID: Die Organisations-ID.
- POLICY_TITLE: Ein für Nutzer lesbarer Titel für Ihre Zugriffsrichtlinie.
Weitere Informationen finden Sie unter Zugriffsrichtlinie erstellen.
Freigegebene VPC
Wenn Sie eine freigegebene VPC verwenden, muss ein Dienstperimeter, der Projekte eines freigegebenen VPC-Netzwerks enthält, auch das Projekt enthalten, das das Netzwerk hostet. Wenn Projekte, die zu einem freigegebenen VPC-Netzwerk gehören, nicht im gleichen Perimeter wie das Hostprojekt sind, funktionieren Dienste möglicherweise nicht wie erwartet oder werden komplett blockiert.
Sorgen Sie dafür, dass sich der Host des freigegebenen VPC-Netzwerks im gleichen Dienstperimeter befinden wie Projekte, die mit dem Netzwerk verbunden sind.
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 gibt es, hat aber kein Subnetz.
- Der Aufrufer hat nicht die erforderliche Berechtigung.
So beheben Sie das Problem:
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 prüfen, müssen Sie die Compute Engine API im Projekt aktivieren, das mit dem API-Aufruf verknüpft ist. Gehen Sie dazu so vor:
Rufen Sie in der Google Cloud Console die Seite APIs & Dienste auf.
Rufen Sie „APIs und Dienste“ auf.Prüfen Sie auf der Seite APIs und Dienste, ob die Compute Engine API aufgeführt ist.
Wenn die Compute Engine API fehlt, aktivieren Sie sie.
API aktivieren
Prüfen Sie, ob im VPC-Netzwerk mindestens ein Subnetz vorhanden ist. Sehen Sie sich dazu die Subnetze an. Wenn es keine Subnetze gibt, fügen Sie dem VPC-Netzwerk ein Subnetz hinzu.
Prüfen Sie, ob der Aufrufer die folgende Berechtigung für das Hostprojekt des VPC-Netzwerk hat:
compute.networks.get
. Mit dieser Berechtigung können Sie VPC-Netzwerke in einem Projekt aufrufen.Bitten Sie den Administrator der Organisation, die Inhaber des Hostprojekts des VPC-Netzwerk ist, dem Anrufer eine IAM-Rolle mit der Berechtigung
compute.networks.get
für das Hostprojekt zu gewähren. Beispiel: die Rolle „Compute-Netzwerkbetrachter“.Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff verwalten.
Lesen Sie die Einschränkungen, die mit der Verwendung von VPC-Netzwerken in Dienstperimetern verbunden sind.
Anfragen zwischen Perimetern
Normalerweise werden Zugriffsebenen verwendet, um Anfragen von außerhalb eines Dienstperimeters für geschützte Ressourcen innerhalb eines Perimeters zuzulassen.
Eine Anfrage von einem Projekt in einem Perimeter für eine geschützte Ressource in einem anderen Perimeter wird jedoch abgelehnt, auch wenn eine Zugriffsebene die Anfrage normalerweise zulässt.
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 Projekt A sich in einem Perimeter befindet, wird die Anfrage auch dann abgelehnt, wenn die Zugriffsebene für Perimeter 2 normalerweise die Anfrage für die geschützte Ressource zulässt.
Sie haben folgende Möglichkeiten, um Anfragen zwischen Perimetern zu vereinfachen:
Verwenden Sie Richtlinie für ausgehenden Traffic und Richtlinien für eingehenden Traffic. Damit Anfragen von einem anderen Perimeter an geschützte Ressourcen in Ihrem Perimeter zugelassen werden, muss der andere Perimeter eine Richtlinie für ausgehenden Traffic verwenden und Sie müssen eine Richtlinie für eingehenden Traffic in Ihrem Perimeter festlegen.
Verwenden Sie Perimeter-Bridges. Mit Bridges können zwei oder mehr Projekte in verschiedenen Perimetern Anfragen an alle Dienste in diesen Projekten senden. Diese Anfragen sind auch dann erlaubt, wenn die Dienste durch die jeweiligen Perimeter geschützt sind.
Sorgen Sie dafür, dass sowohl der anfragende Dienst als auch die Zielressource durch die Perimeter geschützt sind. In diesem Szenario ist der Vorgang erfolgreich, da die Dienste nicht geschützt sind.
Die E-Mail-Adresse ist ungültig oder existiert nicht
Wenn Sie einen Perimeter aktualisieren, der eine gelöschte Entität enthält, wird möglicherweise die Fehlermeldung The email address is invalid or non-existent
angezeigt.
Sie haben folgende Möglichkeiten, dieses Problem zu beheben:
Entfernen Sie die ungültige E-Mail-Adresse aus dem Perimeter, einschließlich Zugriffsebenen und Ein- und Ausstiegsregeln.
Sie können dazu die Google Cloud Console oder die Google Cloud CLI verwenden.
Führen Sie einen Bulk-Vorgang (nur Google Cloud CLI) aus, wenn sich die E-Mail-Adresse sowohl im Trockenen Durchlauf als auch im erzwungenen Perimeter befindet.
- Alle Perimeter abrufen:
gcloud access-context-manager perimeters list --format=list \ --policy=<POLICY_NAME> > my-perimeters.yaml
Entfernen Sie die ungültige E-Mail-Adresse aus der Datei
my-perimeters.yaml
und speichern Sie sie alsmy-perimeters-updated.yaml
.Ersetzen Sie alle Perimeter:
gcloud access-context-manager perimeters replace-all --format=list \ --source-file=my-perimeters-updated.yaml \ --policy=<POLICY_NAME>
Verstöße gegen Regeln für eingehenden- und ausgehenden Traffic
Das Audit-Log enthält Informationen zu den Verstößen in Bezug auf eingehenden und ausgehenden Traffic, anhand derer Sie die Perimeterverstöße verstehen können.
Verstoß gegen Regeln für eingehenden Traffic
Ein Verstoß gegen Regeln für eingehenden Traffic gibt an, dass ein API-Client außerhalb des Perimeters versucht hat, auf eine Ressource innerhalb des Perimeters zuzugreifen. Der Dienstperimeter lehnt die Anfrage ab, da keine übereinstimmenden Regeln für eingehenden Traffic oder Zugriffsebenen vorhanden sind.
Ein Verstoß gegen eine Regel für eingehenden Traffic im Audit-Log enthält die folgenden Details:
- Der Name 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 zugegriffen hat.
Im folgenden Beispiel für einen Verstoß gegen die Regel für eingehenden Traffic versucht ein API-Client 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 eine Regel für eingehenden Traffic für Ihren Perimeter. Weitere Informationen zu Regeln für eingehenden Traffic finden Sie in der Referenz zu Regeln für eingehenden Traffic.
Verstoß gegen Regeln für ausgehenden Traffic
Ein Verstoß gegen eine Regel für ausgehenden Traffic im Audit-Log 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 umfasst Beispiel: ein Cloud Storage-Client, der einen Kopierbefehl aufruft, bei dem 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. Ein Verstoß gegen Ausgangsregeln im Audit-Log enthält die folgenden Details:
- Der Quelltyp, z. B. Netzwerk oder Ressource.
- Die Quelle, also eine Ressource oder ein Netzwerk, dessen Perimeter einen Verstoß gegen ausgehenden Traffic festgestellt hat.
- Der Perimeter mit einem Verstoß gegen ausgehenden Traffic.
- Die Zielressource außerhalb des Perimeters, auf den die Anfrage zugegriffen hat.
Im folgenden Beispiel für einen Verstoß gegen die Regel für ausgehenden Traffic enthält die API-Anfrage eine Ressource aus projects/5678 im Perimeter prod-perimeter
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"
}
]
Erstellen Sie eine Regel für ausgehenden Traffic für Ihren Perimeter, um dieses Problem zu beheben. Weitere Informationen zu Regeln für ausgehenden Traffic finden Sie in der Referenz zu Regeln für ausgehenden Traffic.
Fehlerbehebung bei Anfragen, die von VPC Service Controls blockiert wurden
Das VPC Service Controls-Audit-Log ist das primäre Tool zum Debuggen einer Anfrage, die von VPC Service Controls blockiert wird.
Wenn der Zugriff unerwartet verweigert wurde, können Sie in der Regel die Audit-Logs im Projekt untersuchen, das durch den Dienstperimeter geschützt ist. Diese Logs enthalten umfassende Daten zu den angeforderten Ressourcen und dem Grund für die Ablehnung der Anfrage. Informationen zu den Audit-Logs finden Sie unter Probleme mit der Fehlerbehebung diagnostizieren.
In den folgenden Abschnitten sind die violationReason
-Werte aufgeführt, die bei der Verwendung von VPC Service Controls auftreten können.
NETWORK_NOT_IN_SAME_SERVICE_PERIMETER
Mögliche Ursachen:
- Ein Client in einem VPC-Netzwerk innerhalb eines Dienstperimeters versucht, auf ein Projekt zuzugreifen, das sich nicht im selben Perimeter befindet. Diese Anfrage führt zu einem Verstoß gegen die Ausstiegsregeln. Erstellen Sie eine Regel für ausgehenden Traffic, um dieses Problem zu beheben.
- Ein Client in einem VPC-Netzwerk, das sich außerhalb eines Dienstperimeters befindet, versucht, auf ein Projekt zuzugreifen, das durch den Dienstperimeter geschützt ist. Diese Anfrage führt zu einem Ingress-Verstoß. Erstellen Sie eine Ingress-Regel, um dieses Problem zu beheben.
Der Client kann die Anfrage von einer Compute Engine- oder Google Kubernetes Engine-VM oder von einem lokalen Netzwerk über Cloud Interconnect oder ein VPN senden, das mit einem VPC-Netzwerk konfiguriert ist.
Das folgende Diagramm zeigt, dass ein Verstoß gegen die ausgehenden Regeln auftritt, wenn ein Client in einem VPC-Netzwerk innerhalb eines Dienstperimeters versucht, auf ein Projekt außerhalb des Perimeters zuzugreifen:
Hier ein Beispiel für einen Verstoß gegen die Ausstiegsregeln:
egressViolations: [
{
servicePerimeter: "accessPolicies/<POLICY_NAME>/servicePerimeters/<PERIMETER_NAME>"
source: "projects/<NETWORK_PROJECT_NUMBER>"
sourceType: "Network"
targetResource: "projects/<RESOURCE_PROJECT_NUMBER>"
}
]
Wobei:
<POLICY_NAME>
ist der numerische Name Ihrer Zugriffsrichtlinie.<PERIMETER_NAME>
ist der Name des Dienstperimeters.<NETWORK_PROJECT_NUMBER>
ist die Projektnummer des Google Cloud-Projekts, das Ihr VPC-Netzwerk enthält.<RESOURCE_PROJECT_NUMBER>
ist die Projektnummer des Google Cloud-Projekts, das die Ressource enthält.
Das folgende Diagramm zeigt, dass ein Verstoß gegen die Regel für eingehenden Traffic auftritt, wenn ein Client außerhalb des Perimeters versucht, auf ein Projekt innerhalb des Perimeters zuzugreifen:
Hier ist ein Beispiel für einen Ingress-Verstoß:
ingressViolations: [
{
targetResource: "projects/<RESOURCE_PROJECT_NUMBER>",
source: "projects/<NETWORK_PROJECT_NUMBER>"
servicePerimeter: "accessPolicies/<POLICY_NAME>/servicePerimeters/<PERIMETER_NAME>"
}
]
Wobei:
<RESOURCE_PROJECT_NUMBER>
ist die Projektnummer des Google Cloud-Projekts, das die Ressource enthält.<NETWORK_PROJECT_NUMBER>
ist die Projektnummer des Google Cloud-Projekts, 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 eine Ingress- oder eine Egress-Regel für Ihren Perimeter.
RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER
Dieses Problem tritt auf, wenn eine einzelne Anfrage auf mehrere Ressourcen zugreift, die sich aber 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 des Perimeters und aus einem Projekt innerhalb des Dienstperimeters zugreift:
Das folgende Diagramm zeigt einen Client, der auf Ressourcen aus Projekten zugreift, die sich in zwei verschiedenen Dienstperimetern befinden, die aber nicht miteinander kommunizieren:
Hier ein Beispiel für einen Verstoß gegen die Ausstiegsregeln:
egressViolations: [
{
servicePerimeter: "accessPolicies/<POLICY_NAME>/servicePerimeters/<PERIMETER_NAME>"
source: "projects/<RESOURCE_PROJECT_INSIDE_THIS_PERIMETER>"
sourceType: "Resource"
targetResource: "projects/<RESOURCE_PROJECT_OUTSIDE_THIS-PERIMETER>"
}
]
Wobei:
<POLICY_NAME>
ist der numerische Name Ihrer Zugriffsrichtlinie.<PERIMETER_NAME>
ist der Name des Dienstperimeters.<RESOURCE_PROJECT_INSIDE_THIS_PERIMETER>
ist die Projektnummer des Google Cloud-Projekts, das sich innerhalb des Perimeter befindet.<RESOURCE_PROJECT_OUTSIDE_THIS_PERIMETER>
ist die Projektnummer des Google Cloud-Projekts, das sich außerhalb des Perimeters befindet.
Lösung
Um dieses Problem zu beheben, erstellen Sie eine Regel für ausgehenden Traffic für Ihren Perimeter.
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 übereinstimmt. Das bedeutet, dass ein Client, der nicht zum Google Cloud-Netzwerk gehört, versucht, von außerhalb des Perimeters auf Google Cloud-Netzwerkressourcen zuzugreifen. Beispielsweise stimmt die IP-Adresse, die dem Feld callerIp
des Audit-Eintrags entspricht, mit keinem der CIDR-Bereiche überein, die auf den Zugriffsebenen für den Dienstperimeter definiert sind.
Wenn die IP-Adresse des Aufrufers fehlt oder als interne IP-Adresse angezeigt wird, liegt dies möglicherweise an einem Google Cloud-Dienst, der nicht in VPC Service Controls eingebunden ist. Möglicherweise versucht der Google Cloud-Dienst, auf einen geschützten Dienst zuzugreifen, und schlägt wie erwartet fehl.
Um dieses Problem zu beheben, empfehlen wir, eine Ingress-Regel anstelle einer Zugriffsebene zu erstellen, da eine Ingress-Regel eine detaillierte Zugriffssteuerung bietet.
Das folgende Diagramm zeigt einen Client, der versucht, von außerhalb des Perimeters auf Ressourcen zuzugreifen:
Hier ist ein Beispiel für einen Ingress-Verstoß:
authenticationInfo: {
principalEmail: "EMAIL"
}
requestMetadata: {
callerIp: "<PUBLIC_IP_ADDRESS>"
deviceState: "Cross Organization"
}
ingressViolations: [
{
targetResource: "projects/<RESOURCE_PROJECT_NUMBER>",
servicePerimeter: "accessPolicies/<POLICY_NAME>/servicePerimeters/<PERIMETER-NAME>"
}
]
Wobei:
<EMAIL>
ist die E-Mail-Adresse des Dienstkontos oder des authentifizierten Nutzers.Wenn Sie einen Google Cloud-Dienst verwenden, der nicht von VPC Service Controls unterstützt wird, werden E-Mail-Adressen, die zur Domain
google.com
gehören, entfernt und durchgoogle-internal
ersetzt.google-internal
bezieht sich auf interne Google-Identitäten.<PUBLIC_IP_ADDRESS>
ist die IP-Adresse des Anrufers. Bei einem Anrufer aus dem Internet ist dies die öffentliche IPv4- oder IPv6-Adresse.<RESOURCE_PROJECT_NUMBER>
ist die Projektnummer des Google Cloud-Projekts, 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
weiterhin vorhanden sein kann, da diese Zugriffsebenen möglicherweise nicht im verletzten Perimeter angegeben sind.
SERVICE_NOT_ALLOWED_FROM_VPC
Dieses Problem tritt auf, wenn ein Client versucht, von einem VPC-Netzwerk aus auf Google Cloud-Ressourcen zuzugreifen. Der Client kann die Anfrage von einer Compute Engine- oder Google Kubernetes Engine-VM oder von einem lokalen Netzwerk über Cloud Interconnect oder ein VPN senden, das mit einem VPC-Netzwerk konfiguriert ist.
Um dieses Problem zu beheben, prüfen Sie, ob der aufgerufene Dienst in der Konfiguration der über VPC zugänglichen Dienste des Dienstperimeters zulässig ist.
Beispielszenarien
In den folgenden Beispielen werden häufige Szenarien beschrieben, die bei der Verwendung von VPC Service Controls auftreten können.
- Cloud Storage-Zugriff aus lokaler Umgebung
- BigQuery-Zugriff von einer VM außerhalb des Projekts
- Projektübergreifende BigQuery-Abfrage
- Cloud Storage-Datei innerhalb des Perimeters verschieben
- Cloud Storage-Datei außerhalb des Perimeters verschieben
- BigQuery-Dataset wird von einer VM innerhalb des Perimeters kopiert
- Dataproc-Job liest aus Projekt
- Nicht unterstützter Dienst mit eingeschränkter VIP
- Logexport in ein Projekt außerhalb des Perimeters
- BigQuery-Extraktion in Cloud Storage
Cloud Storage-Zugriff aus lokaler Umgebung
In diesem Beispiel blockiert VPC Service Controls eine Anfrage von einer Mitarbeiter-Workstation (durch callerIp
identifiziert) an einen Cloud Storage-Bucket im Projekt corp-storage
.
Die Anfrage generiert den folgenden Audit-Logeintrag:
{
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 Audit-Logeintrag 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 Audit-Logeintrag 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
.
Cloud Storage-Datei innerhalb des Perimeters verschieben
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 Audit-Logeintrag 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
.
Cloud Storage-Datei außerhalb des Perimeters verschieben
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
wird 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 Audit-Logeintrag 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 Audit-Logeintrag 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"
}
Aufgrund von Einschränkungen des Logging-Mechanismus und der verteilten Architektur von BigQuery liegt in diesem Beispiel keine einzelne zugrunde liegende API-Aktion vor, die alle an dieser Anfrage beteiligten Ressourcen aufzeigt.
Der Audit-Logeintrag zeigt, dass der Vorgang fehlgeschlagen ist, weil BigQuery über das Netzwerk im Projekt perimeter-network
(die Quelle der Anfrage) auf das Zielprojekt (corp-resources-public
) zugreifen muss, um die Daten zu kopieren. corp-resources-public
befindet sich jedoch außerhalb des Perimeters, mit dem perimeter-network
geschützt wird. 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-Log-Eintrag vom ursprünglichen Nutzerbefehl. Wenn mehrere Prüfungen innerhalb eines bestimmten Dienstes durchgeführt werden und fehlschlagen können, sieht der generierte Audit-Log-Eintrag außerdem vom ursprünglichen Nutzerbefehl aus.
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, der Daten in einen Bucket außerhalb des Perimeters schreibt.
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].
Beachten Sie die IO-Ausnahme, die beim Aufruf der Methode 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 sollte.
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.
Verwenden Sie den folgenden Befehl, um das Projekt zu identifizieren, das corp-resources-public-1
enthält:
gcloud storage ls gs://corp-resources-public-1 --buckets --log-http 2>&1 | grep projectNumber
Der Befehl gibt die folgende Ausgabe zurück:
"projectNumber": "117961063178",
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 Google Cloud-Dienste sind bei der Implementierung von anderen Google Cloud-Diensten abhängig. Wenn ein nicht unterstützter Dienst wie die App Engine in einem Projekt verwendet wird, das durch einen Perimeter geschützt ist, ist möglicherweise kein Zugriff auf die Ressourcen des Dienstes möglich.
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. VPC Service Controls unterstützt beispielsweise keine App Engine. Die App Engine Admin API ist bei Verwendung der eingeschränkten VIP nicht verfügbar.
Angenommen, der folgende Befehl wird verwendet, 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>
Dieser Fehlertyp wird für Dienste erwartet, die nicht von VPC Service Controls unterstützt werden und über die eingeschränkte VIP nicht verfügbar sind. Wenn dieser Fehler jedoch für einen Dienst auftritt, der von VPC Service Controls unterstützt wird, sollten Sie sich die bekannten Diensteinschränkungen für diesen Dienst ansehen. wenn es sich um eine bekannte Einschränkung handelt. Andernfalls muss das Problem gemeldet werden.
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.
Der folgende beispielhafte Befehl wird 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 Audit-Logeintrag 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 veranschaulicht Folgendes: Wenn ein Google Cloud-Dienst ein Google Cloud-internes verwaltetes Dienstkonto wie p927005422713-439672@gcp-sa-logging.iam.gserviceaccount.com
verwendet, um einen anderen Google Cloud-Dienst aufzurufen, wird das „Netzwerkprojekt“ der Anfrage (in diesem Fall perimeter-network
) von dieser Identität abgeleitet. Dieselbe Identität stellt auch die Logexport-Ressource dar.
Dies ist ein gängiges Muster in Google Cloud, das für zahlreiche Fälle von Dienst-zu-Dienst-Interaktionen gilt.
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 verweist der Fehler nicht ausdrücklich auf VPC Service Controls. Ein ähnlicher Fehler wird angezeigt, wenn ein Identitäts- und Zugriffsverwaltungsfehler auftritt.
Der folgende Audit-Logeintrag 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 zeigt, dass die Audit-Logs bei komplexen Vorgängen mit mehreren Diensten nützliche Fehlerbehebungsdaten zum Quell- und zum Zieldienst enthalten können.
Perimeterzugriff über Cloud NAT-Gateway
In diesem Beispiel wird davon ausgegangen, dass Projekt A von Organisation A nicht in einem 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. In Projekt B ist eine Zugriffsebene konfiguriert, die den Zugriff basierend auf den externen Gateway-IP-Adressen von Projekt A zulässt.
Eine VM, die zu Projekt A gehört (dies 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 Prüfprotokolleintrag 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"
}
Für die callerIp
-Ressource wird keine externe IP-Adresse erfasst. Anstelle der externen IP-Adresse des Cloud NAT-Gateways wird für die 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 Privaten Google-Zugriff integriert. Dadurch wird der privater Google-Zugriff automatisch im Subnetzwerk der Ressource aktiviert und der Traffic zu Google APIs und ‑Diensten bleibt intern, anstatt über die externe IP-Adresse des Cloud NAT-Gateways an das Internet weitergeleitet zu werden.
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
entfernt. Um dieses Problem zu beheben, verwenden Sie anstelle der externen IP-Adresse des Cloud NAT-Gateways in der Zugriffsebene für die IP-basierte Zulassungsliste eine Ingress-Regel, die Zugriffe vom Projekt- oder Dienstkonto zulässt.
Nächste Schritte
- Informationen zum Abrufen von VPC Service Controls-Fehlern aus Audit-Logs
- Weitere Informationen zur Behebung häufiger Probleme mit anderen Google Cloud-Diensten