Risolvi i problemi comuni

Questa pagina elenca vari problemi che potresti riscontrare durante la configurazione dei Controlli di servizio VPC.

Comportamento imprevisto della policy con ambito

Potresti notare alcune violazioni impreviste dei Controlli di servizio VPC che la tua policy con ambito dovrebbe consentire. È un problema noto che, se non hai una policy di accesso a livello di organizzazione, potresti riscontrare alcuni problemi imprevisti con le policy di accesso con ambito.

Per risolvere il problema, crea una policy di accesso a livello di organizzazione utilizzando il seguente comando:

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

Sostituisci quanto segue:

  • ORGANIZATION_ID: l'ID organizzazione.
  • POLICY_TITLE: un titolo leggibile per la policy di accesso.

Per saperne di più, consulta Crea una policy di accesso.

VPC condiviso

Quando utilizzi un VPC condiviso, un perimetro di servizio che include progetti appartenenti a una rete VPC condivisa deve includere anche il progetto che ospita la rete. Quando i progetti che appartengono a una rete VPC condivisa non si trovano nello stesso perimetro del progetto host, i servizi potrebbero non funzionare come previsto o potrebbero essere completamente bloccati.

Assicurati che l'host della rete VPC condivisa si trovi nello stesso perimetro di servizio dei progetti connessi alla rete.

Impossibile aggiungere una rete VPC

Quando provi ad aggiungere una rete VPC a un perimetro di servizio, può verificarsi il seguente errore:

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)

Questo errore si verifica per uno dei seguenti motivi:

  • La rete VPC non esiste.
  • La rete VPC esiste, ma non ha una subnet.
  • Il chiamante non dispone dell'autorizzazione richiesta.

Per risolvere questo problema, completa i seguenti passaggi:

  1. Verifica se la rete VPC specificata nel messaggio di errore esiste visualizzando le reti nel tuo progetto.

    • Prima di verificare la rete VPC, assicurati che l'API Compute Engine sia abilitata nel progetto associato alla chiamata API completando i seguenti passaggi:

      1. Nella console Google Cloud , vai alla pagina API e servizi.
        Vai su API e servizi

      2. Nella pagina API e servizi, verifica se l'API Compute Engine è elencata.

      3. Se l'API Compute Engine non è presente, abilitala.
        Abilita l'API

  2. Verifica che nella rete VPC esista almeno una subnet visualizzando le subnet. Se non ci sono subnet, aggiungi una subnet alla rete VPC.

  3. Verifica se il chiamante dispone della seguente autorizzazione sul progetto host della rete VPC: compute.networks.get. Questa autorizzazione ti consente di visualizzare le reti VPC in un progetto.

    • Chiedi all'amministratore dell'organizzazione proprietaria del progetto host della rete VPC di concedere al chiamante un ruolo IAM con l'autorizzazione compute.networks.get sul progetto host. Ad esempio, il ruolo Compute Network Viewer.

      Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso.

Assicurati di leggere le limitazioni associate all'utilizzo delle reti VPC nei perimetri di servizio.

Richieste tra perimetri

Normalmente, i livelli di accesso vengono utilizzati per consentire le richieste di risorse protette all'interno di un perimetro provenienti dall'esterno di un perimetro di servizio.

Tuttavia, una richiesta proveniente da un progetto all'interno in un perimetro per una risorsa protetta in un altro perimetro viene negata, anche se un livello di accesso normalmente consente la richiesta.

Ad esempio, supponiamo che il Progetto A nel Perimetro 1 richieda una risorsa dal Progetto B. La risorsa nel Progetto B è protetta dal Perimetro 2. Poiché il Progetto A si trova in un perimetro, anche se un livello di accesso per il Perimetro 2 normalmente consente la richiesta della risorsa protetta, la richiesta viene rifiutata.

Utilizza uno dei seguenti approcci per facilitare le richieste tra perimetri:

  • Utilizza policy in uscita e in entrata. Per consentire le richieste da un altro perimetro alle risorse protette nel tuo perimetro, l'altro perimetro deve utilizzare una policy in uscita e tu devi impostare una policy in entrata nel tuo perimetro.

  • Utilizza bridge del perimetro. I bridge consentono a due o più progetti in perimetri diversi di effettuare richieste a qualsiasi servizio in questi progetti. Queste richieste sono consentite anche se i servizi sono protetti dai rispettivi perimetri.

  • Assicurati che sia il servizio richiedente, sia la risorsa di destinazione non siano protetti dai perimetri. In questo scenario, l'operazione ha esito positivo perché i servizi non sono protetti.

L'indirizzo email non è valido o non esiste

Quando aggiorni un perimetro che contiene un'entità eliminata, potrebbe verificarsi l'errore The email address is invalid or non-existent.

Per risolvere il problema, devi rimuovere l'indirizzo email non valido da tutti i perimetri:

  1. Esporta tutti i perimetri. Il seguente comando di esempio esporta un elenco di perimetri di servizio in formato YAML:

    gcloud access-context-manager perimeters list \
        --policy=POLICY_NAME \
        --format="json(name,title,description,perimeterType,status,spec,useExplicitDryRunSpec)" \
        > my-perimeters.yaml
  2. Rimuovi l'indirizzo email non valido dal file my-perimeters.yaml e salvalo come my-perimeters-updated.yaml.

  3. Sostituisci in blocco tutti i perimetri.

Violazioni delle regole in entrata e in uscita

Il log di controllo contiene informazioni sulle violazioni delle regole in entrata e in uscita che ti aiutano a comprendere le violazioni del perimetro.

Violazione della regola in entrata

Una violazione della regola in entrata indica che un client API all'esterno del perimetro ha tentato di accedere a una risorsa all'interno del perimetro. Il perimetro di servizio rifiuta la richiesta perché non esistono regole in entrata o livelli di accesso corrispondenti.

Una violazione della regola in entrata nell'audit log contiene i seguenti dettagli:

  • Il nome del perimetro in cui si è verificata la violazione della regola in entrata.
  • La risorsa all'interno del perimetro a cui il client API all'esterno del perimetro ha tentato di accedere.

Nell'esempio seguente di violazione della regola in entrata, un client API all'esterno del perimetro tenta di accedere al bucket Cloud Storage prod-protected-storage-bucket all'interno del perimetro prod-perimeter.

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

Per risolvere il problema, crea una regola in entrata per il tuo perimetro. Per saperne di più sulle regole in entrata, consulta il Riferimento per le regole in entrata.

Violazione della regola in uscita

Una violazione della regola in uscita nell'audit log indica uno dei seguenti eventi:

  • Un client API all'interno del perimetro ha tentato di accedere a una risorsa all'esterno del perimetro.
  • Una richiesta API che coinvolge una risorsa all'interno del perimetro e una risorsa all'esterno del perimetro. Ad esempio, un client Cloud Storage che chiama un comando di copia e un bucket si trova all'interno del perimetro, mentre l'altro bucket si trova all'esterno del perimetro.

Il perimetro di servizio rifiuta la richiesta perché non esistono regole in uscita corrispondenti. Una violazione della regola in uscita nell'audit log include i seguenti dettagli:

  • Il tipo di origine, ad esempio rete o risorsa.
  • L'origine, ovvero una risorsa o una rete, il cui perimetro ha riscontrato una violazione della regola in uscita.
  • Il perimetro che ha riscontrato una violazione in uscita.
  • La risorsa di destinazione al di fuori del perimetro a cui la richiesta ha tentato di accedere.

Nel seguente esempio di violazione della regola in uscita, la richiesta API include una risorsa di projects/5678, che si trova all'interno del perimetro prod-perimeter, e un oggetto del bucket Cloud Storage external-storage-bucket, che si trova all'esterno del perimetro.

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

Per risolvere il problema, crea una regola in uscita per il tuo perimetro. Per saperne di più sulle regole in uscita, consulta il Riferimento per le regole in uscita.

Debug delle richieste bloccate dai Controlli di servizio VPC

L'audit log dei Controlli di servizio VPC è lo strumento principale per eseguire il debug di una richiesta bloccata dai Controlli di servizio VPC.

Quando l'accesso è stato bloccato in modo imprevisto, consulta gli audit log nel progetto protetto dal perimetro di servizio. Questi log contengono dati importanti sulle risorse richieste e sul motivo per cui la richiesta è stata rifiutata. Per informazioni sulla diagnosi degli audit log, vedi Accedi allo strumento di analisi delle violazioni.

Le sezioni seguenti elencano i valori violationReason che potresti riscontrare quando utilizzi i Controlli di servizio VPC.

NETWORK_NOT_IN_SAME_SERVICE_PERIMETER

Il motivo di questo problema potrebbe essere uno dei seguenti:

  • Un client in una rete VPC all'interno di un perimetro di servizio tenta di accedere a un progetto che non si trova nello stesso perimetro. Questa richiesta comporta una violazione in uscita. Crea una regola in uscita per risolvere il problema.
  • Un client in una rete VPC che si trova al di fuori di un perimetro di servizio tenta di accedere a un progetto protetto dal perimetro di servizio. Questa richiesta comporta una violazione in entrata. Crea una regola in entrata per risolvere il problema.

Il client potrebbe inviare la richiesta da una VM di Compute Engine o Google Kubernetes Engine oppure da una rete on-premise tramite Cloud Interconnect o una VPN configurata utilizzando una rete VPC.

Il seguente diagramma mostra che si verifica una violazione in uscita quando un client in una rete VPC all'interno di un perimetro di servizio tenta di accedere a un progetto all'esterno del perimetro:

Una violazione in uscita dovuta a NETWORK_NOT_IN_SAME_SERVICE_PERIMETER.

Ecco un esempio di violazione in uscita:

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

Dove:

  • <POLICY_NAME> è il nome numerico della tua policy di accesso.
  • <PERIMETER_NAME> è il nome del perimetro di servizio.
  • <NETWORK_PROJECT_NUMBER> è il numero di progetto del progetto Google Cloud che contiene la rete VPC.
  • <RESOURCE_PROJECT_NUMBER> è il numero di progetto del progetto Google Cloud che contiene la risorsa.

Il seguente diagramma mostra che si verifica una violazione in entrata quando un client all'esterno del perimetro tenta di accedere a un progetto all'interno del perimetro:

Una violazione in entrata dovuta a NETWORK_NOT_IN_SAME_SERVICE_PERIMETER.

Ecco un esempio di violazione in entrata:

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

Dove:

  • <RESOURCE_PROJECT_NUMBER> è il numero di progetto del progetto Google Cloud che contiene la risorsa.
  • <NETWORK_PROJECT_NUMBER> è il numero di progetto del progetto Google Cloud che contiene la rete VPC.
  • <POLICY_NAME> è il nome numerico della tua policy di accesso.
  • <PERIMETER_NAME> è il nome del perimetro di servizio.

Risoluzione

Per risolvere questo errore, crea una regola in entrata o in uscita per il tuo perimetro.

RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER

Questo problema si verifica quando una singola richiesta accede a più risorse, ma le risorse non si trovano nello stesso perimetro di servizio. Il problema si verifica indipendentemente dalla posizione del client e dal fatto che il client abbia o meno accesso alle risorse.

Il seguente diagramma mostra un client che accede alle risorse da un progetto all'esterno del perimetro e da un progetto all'interno del perimetro di servizio:

Una violazione in uscita dovuta a un client che accede alle risorse da un progetto all&#39;esterno del perimetro.

Il seguente diagramma mostra un client che accede alle risorse di progetti che si trovano in due perimetri di servizio diversi, ma i perimetri non comunicano tra loro:

Una violazione in uscita dovuta a un client che accede a risorse di progetti che si trovano in due perimetri di servizio diversi.

Ecco un esempio di violazione in uscita:

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

Dove:

  • <POLICY_NAME> è il nome numerico della tua policy di accesso.
  • <PERIMETER_NAME> è il nome del perimetro di servizio.
  • <RESOURCE_PROJECT_INSIDE_THIS_PERIMETER> è il numero di progetto del progetto Google Cloud che si trova all'interno del perimetro.
  • <RESOURCE_PROJECT_OUTSIDE_THIS_PERIMETER> è il numero di progetto del progetto Google Cloud che si trova all'esterno del perimetro.

Risoluzione

Per risolvere il problema, crea una regola in uscita per il tuo perimetro.

NO_MATCHING_ACCESS_LEVEL

Questo problema si verifica quando l'indirizzo IP, il requisito del dispositivo o l'identità dell'utente non corrispondono a una regola in entrata o a un livello di accesso assegnati al perimetro. Ciò significa che un client che non fa parte della rete Google Cloud tenta di accedere alle risorse di rete Google Cloud dall'esterno del perimetro. Ad esempio, l'indirizzo IP corrispondente al campo callerIp del record di audit non corrisponde ad alcun intervallo CIDR definito nei livelli di accesso per il perimetro di servizio.

Se l'indirizzo IP del chiamante non è presente o viene visualizzato come indirizzo IP interno, questa violazione potrebbe essere dovuta a un servizio Google Cloud che non è integrato con i Controlli di servizio VPC. Il motivo potrebbe essere che il servizioGoogle Cloud tenta di accedere a un servizio protetto e non ci riesce, come previsto.

Per risolvere il problema, ti consigliamo di creare una regola in entrata anziché un livello di accesso, perché una regola in entrata fornisce un controllo dell'accesso granulare.

Il seguente diagramma mostra un client che tenta di accedere alle risorse dall'esterno del perimetro:

Una violazione in entrata dovuta a NO_MATCHING_ACCESS_LEVEL.

Ecco un esempio di violazione in entrata:

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

Dove:

  • <EMAIL> è l'indirizzo email del service account o dell'utente autenticato.

    Se utilizzi un servizio Google Cloud non supportato dai Controlli di servizio VPC, gli indirizzi email appartenenti al dominio google.com vengono oscurati e sostituiti con google-internal. google-internal si riferisce alle identità interne di proprietà di Google.

  • <PUBLIC_IP_ADDRESS> è l'indirizzo IP del chiamante. Per un chiamante da internet, sarà l'indirizzo IPv4 o IPv6 pubblico.

  • <RESOURCE_PROJECT_NUMBER> è il numero di progetto del progetto Google Cloud che contiene la risorsa.

  • <POLICY_NAME> è il nome numerico della tua policy di accesso.

  • <PERIMETER_NAME> è il nome del perimetro di servizio.

Tieni presente che, in questo caso, metadata.accessLevels potrebbe comunque essere presente poiché questi livelli di accesso potrebbero non essere specificati nel perimetro violato.

SERVICE_NOT_ALLOWED_FROM_VPC

Questo problema si verifica quando un client tenta di accedere alle risorse Google Cloud da una rete VPC. Il client potrebbe inviare la richiesta da una VM di Compute Engine o Google Kubernetes Engine oppure da una rete on-premise tramite Cloud Interconnect o una VPN configurata utilizzando una rete VPC.

Per risolvere il problema, assicurati che il servizio chiamato sia consentito dalla configurazione dei servizi accessibili da VPC del perimetro di servizio.

Scenari di esempio

Gli esempi seguenti riguardano i problemi che potresti riscontrare durante l'utilizzo dei Controlli di servizio VPC.

Accesso a Cloud Storage da on-premise

In questo esempio, Controlli di servizio VPC blocca una richiesta dalla workstation di un dipendente (identificata da callerIp) a un bucket Cloud Storage nel progetto corp-storage.

La richiesta genera il seguente record dell'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"
}

Il progetto corp-storage è incluso in un perimetro di servizio. La workstation del dipendente non fa parte di alcuna rete all'interno di questo perimetro. Poiché la workstation del dipendente si trova al di fuori del perimetro, la richiesta viene bloccata.

Accesso a BigQuery da VM all'esterno del progetto

In questo esempio, una VM appartenente al progetto 458854174376 (data-collector) tenta di eseguire una query BigQuery su un set di dati nel progetto 798816221974 (corp-resources-protected) e l'operazione viene negata.

La VM utilizza la seguente query:

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

La query restituisce il seguente output:

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

Viene generato il seguente record dell'audit log:

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

In questo esempio, violationReason è NETWORK_NOT_IN_SAME_SERVICE_PERIMETER. callerNetwork è incluso in aggiunta a callerIp. L'indirizzo IP è privato e per distinguerlo viene fornita la rete. Le risorse pertinenti qui in discussione sono elencate in due posizioni: VpcServiceControlAuditMetadata.resourceNames e requestMetadata.callerNetwork (il progetto proprietario della rete).

Il problema è che il progetto corp-resources-protected si trova all'interno di un perimetro di servizio, mentre data-collector, il progetto che include la rete a cui appartiene la VM, non lo è. In questo caso, l'accesso viene negato come previsto.

Query BigQuery tra progetti

In questo esempio, una VM appartenente al progetto perimeter-network tenta di eseguire query sulle istanze BigQuery di due progetti diversi: corp-resources-protected, che si trova nello stesso perimetro di servizio di perimeter-network, e corp-resources-public, che si trova altrove.

La VM utilizza il seguente comando:

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'

La query restituisce il seguente output:

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

Viene generato il seguente record dell'audit log:

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

Se esaminiamo callerNetwork e VpcServiceControlAuditMetadata.resourceNames, possiamo vedere tre progetti: perimeter-network, 117961063178 (corp-resources-public) e 690885588241 (corp-resources-protected). Ricorda che corp-resources-public non si trova nello stesso perimetro di servizio di perimeter-network e corp-resources-protected.

Il valore di violationReason RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER indica che alcune risorse nella richiesta si trovano al di fuori di un perimetro che si applica alla richiesta. In questo caso, la risorsa è corp-resources-public.

Spostamento di file Cloud Storage all'interno del perimetro

In questo esempio, una VM nel progetto perimeter-network utilizza un comando per spostare un file da un bucket Cloud Storage che si trova nel progetto corp-resources-protected a un altro bucket, che si trova nel progetto corp-resources-public.

La VM utilizza il seguente comando:

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

Il comando restituisce il seguente output:

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

Viene generato il seguente record dell'audit log:

{
 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 questo caso, il log è meno chiaro perché il metodo elencato è BillingRequiredRead e l'azione intrapresa è move. Si tratta di una limitazione delle attuali funzionalità dell'audit log dei Controlli di servizio VPC.

Anche se il motivo è meno chiaro, questo record dell'audit log indica che alcune risorse nella richiesta si trovano al di fuori di un perimetro che si applica alla richiesta. In questo caso, la risorsa è corp-resources-public.

Spostamento di file Cloud Storage all'esterno del perimetro

In questo esempio, una VM nel progetto public-network utilizza un comando per spostare un file da un bucket Cloud Storage che si trova nel progetto corp-resources-protected a un altro bucket, che si trova nel progetto corp-resources-public.

Il progetto corp-resources-protected è protetto da un perimetro di servizio. I progetti public-network e corp-resources-public si trovano all'esterno del perimetro.

La VM utilizza il seguente comando:

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

Il comando restituisce il seguente output:

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

Viene generato il seguente record dell'audit log:

{
 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 questo esempio, l'audit log indica che non è possibile copiare i dati oltre il confine di un perimetro di servizio (entrambe le risorse si trovano nel record dell'audit log). Ricorda che la richiesta ha origine all'esterno del perimetro (la VM in public-network) e che uno dei bucket si trova all'esterno del perimetro (corp-resources-public-1).

Dall'esterno del perimetro è possibile scrivere nel bucket corp-resources-public-1, quindi il controllo che ha avuto esito negativo nell'esempio precedente viene superato. Tuttavia, il controllo successivo per copiare effettivamente i dati non va a buon fine.

Questo esempio mostra come a volte una singola operazione dell'utente comporti più operazioni interne che devono superare l'applicazione dei Controlli di servizio VPC.

Copia del set di dati BigQuery da VM all'interno del perimetro

In questo esempio, una VM nel progetto 927005422713 (perimeter-network) tenta di copiare un set di dati BigQuery dal progetto corp-resources-private a corp-resources-public (117961063178). perimeter-network e corp-resources-private condividono un perimetro, mentre corp-resources-public si trova all'esterno del perimetro.

La VM utilizza il seguente comando:

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

Il comando restituisce il seguente output:

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

Viene generato il seguente record dell'audit log:

{
 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 questo esempio, non esiste una singola azione API sottostante che mostri tutte le risorse in gioco in questa richiesta, a causa delle limitazioni del meccanismo di logging e dell'architettura distribuita di BigQuery.

Il record dell'audit log indica che l'operazione non è riuscita perché, per copiare i dati, BigQuery deve accedere al progetto di destinazione (corp-resources-public) utilizzando la rete nel progetto perimeter-network (l'origine della richiesta). Ricorda che corp-resources-public si trova all'esterno del perimetro che protegge perimeter-network. La richiesta viene rifiutata in quanto tentativo di esfiltrazione di dati verso corp-resources-public.

Questo esempio mostra che una sola operazione concettuale, come la copia dei dati, può attivare più tentativi di accesso ai dati da parte di diversi sistemi di archiviazione, come Cloud Storage, BigQuery e Bigtable. A seconda di come viene eseguita l'operazione, il record dell'audit log generato è diverso dal comando originale dell'utente. Inoltre, quando vengono eseguiti e potenzialmente non superati più controlli all'interno di un determinato servizio, il record dell'audit log generato è diverso dal comando dell'utente originale.

Job Dataproc che legge dal progetto

Questo esempio mostra come eseguire il debug degli errori indiretti dei Controlli di servizio VPC che si verificano quando si utilizzano servizi di elaborazione dei dati come Dataproc.

In questo esempio, un cluster Dataproc è in esecuzione in un progetto protetto dai Controlli di servizio VPC. Hello-world.py è un job pyspark che tenta di accedere ai dati dal bucket Cloud Storage all'interno del perimetro e poi di scriverli in un altro bucket che si trova fuori dal perimetro. I Controlli di servizio VPC bloccano l'operazione che scrive dati in un bucket all'esterno del perimetro.

Il seguente comando viene utilizzato per eseguire Hello-world.py:

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

Il comando restituisce il seguente output:

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].

Nota l'eccezione di IO che si verifica quando viene chiamato il metodo saveAsTextFile. Cloud Storage restituisce l'errore 403 con il messaggio Request violates VPC Service Controls. L'errore indica che l'operazione dell'audit log di Cloud Storage deve essere verificata.

Negli audit log del progetto perimeter-network, in cui è stato eseguito il comando, è presente un record dell'audit log per l'operazione saveAsTextFile:

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

A causa delle limitazioni dell'audit log, il valore methodName per Cloud Storage è elencato come Read anche se in realtà è un'operazione write. Il record dell'audit log indica che l'operazione non è riuscita perché una rete nel progetto corp-resources-private stava tentando di accedere ai dati (in scrittura, in questo caso) di una risorsa nel bucket corp-resources-public-1. A causa delle limitazioni dell'audit log di Cloud Storage, non è chiaro a quale progetto appartenga il bucket corp-resources-public-1.

Per identificare il progetto che contiene corp-resources-public-1, utilizza il seguente comando:

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

Il comando restituisce il seguente output: "projectNumber": "117961063178",

117961063178 è il progetto corp-resources-public, che si trova all'esterno del perimetro. Pertanto, l'errore è previsto.

Errore dovuto a servizi non supportati

Alcuni servizi Google Cloud dipendono da altri Google Cloud servizi come parte della loro implementazione. Se un servizio non supportato come App Engine viene utilizzato all'interno di un progetto protetto da un perimetro, le risorse del servizio potrebbero non essere accessibili.

Per informazioni sui casi problematici noti, consulta Limitazioni note dei servizi.

Servizio non supportato con VIP con limitazioni

Il tentativo di accedere a un'API non supportata dal VIP con limitazioni dei Controlli di servizio VPC genera un errore 403. Ad esempio, i Controlli di servizio VPC non supportano App Engine, quindi l'API App Engine Admin non è disponibile quando si utilizza il VIP con limitazioni.

Ad esempio, supponiamo che il seguente comando venga utilizzato per elencare tutti i servizi App Engine all'interno di un perimetro di servizio:

gcloud app services list

Il comando restituisce il seguente output:

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>

Questo tipo di errore è previsto per i servizi non supportati dai Controlli di servizio VPC e non disponibili nel VIP con limitazioni. Se questo errore si verifica per un servizio supportato dai Controlli di servizio VPC, ti consigliamo di controllare le limitazioni note dei servizi per verificare se si tratta di una limitazione nota. In caso contrario, il problema va segnalato.

Esportazione dei log in un progetto all'esterno del perimetro

In questo esempio, un'esportazione di log viene bloccata dai Controlli di servizio VPC. La destinazione di esportazione, il progetto corp-resources-public, si trova all'esterno del perimetro di Controlli di servizio VPC, mentre il sink viene creato nel progetto perimeter-network, che si trova all'interno del perimetro.

Ad esempio, supponiamo che venga utilizzato il seguente comando:

gcloud logging sinks describe example-sink

Il comando restituisce il seguente output:

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

Viene generato il seguente record dell'audit log:

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

Il record dell'audit log viene generato per BigQuery, non per Logging. Questo perché BigQuery è il servizio sink in cui Logging sta tentando di scrivere.

L'esportazione non riesce perché corp-resources-public si trova all'esterno del perimetro che protegge perimeter-network.

Questo esempio mostra che, nei casi in cui un servizio Google Cloud ne chiama un altro utilizzando un service account gestito interno a Google Cloud, ad esempio p927005422713-439672@gcp-sa-logging.iam.gserviceaccount.com, il "progetto di rete" (in questo caso, perimeter-network) della richiesta viene ricavato da questa identità. La stessa identità rappresenta la risorsa di esportazione log stessa.

Questo schema è comune in Google Cloud e si applica a numerosi casi di interazione tra servizi.

Estrazione BigQuery in Cloud Storage

Questo esempio descrive come eseguire il debug delle estrazioni BigQuery in Cloud Storage non riuscite.

In questo esempio, corp-resources-private e perimeter-network sono progetti protetti da un perimetro di servizio. corp-resources-public è un progetto che si trova all'esterno del perimetro.

Supponiamo che sia stato utilizzato il seguente comando:

bq extract babynames.yob2000

Il comando restituisce il seguente output:

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 questo caso l'errore non riguarda specificamente i Controlli di servizio VPC. Se si verifica un problema in Identity and Access Management, viene visualizzato un errore simile.

Viene generato il seguente record dell'audit log:

{
 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 questo record dell'audit log, storage-accessing@example.iam.gserviceaccount.com è identificata come l'identità che tenta di eseguire l'operazione. In questo esempio, supponiamo che storage-accessing@example.iam.gserviceaccount.com disponga delle autorizzazioni IAM necessarie per eseguire il comando.

Poiché le autorizzazioni IAM non sono il problema, il passaggio successivo consiste nel verificare la presenza di errori dei Controlli di servizio VPC.

Il record dell'audit log per il servizio di destinazione (Cloud Storage) contiene i motivi dettagliati dell'errore:

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

Da questo log è chiaro che i due progetti 1004338142803 (corp-resources-private-1) e corp-resources-public vengono utilizzati entrambi per completare il comando. Poiché questi progetti non condividono un perimetro, il job di estrazione non va a buon fine.

Questo esempio mostra che, nelle operazioni multiservizio complesse, gli audit log dei servizi sia di origine che di destinazione potrebbero contenere dati utili per il debug.

Accesso al perimetro tramite il gateway Cloud NAT

In questo esempio, supponiamo che il Progetto A dell'Organizzazione A non sia configurato in alcun perimetro. Il Progetto B è protetto da un perimetro in un'organizzazione diversa. Le risorse private del Progetto A utilizzano il gateway Cloud NAT per raggiungere internet e i servizi e le API di Google. Nel Progetto B è configurato un livello di accesso per consentire l'accesso in base agli indirizzi IP del gateway esterno del Progetto A.

Una VM appartenente al Progetto A (che può essere un nodo Google Kubernetes Engine) tenta di accedere a una risorsa protetta nel Progetto B, ma la connessione non riesce e nel Progetto B viene generato il seguente record dell'audit log:

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

La risorsa callerIp non registra un indirizzo IP esterno. Anziché l'indirizzo IP esterno del gateway Cloud NAT, la risorsa callerIp mostra gce-internal-ip.

Il campo callerIp viene oscurato con gce-internal-ip quando le richieste provengono da un progetto o un'organizzazione differente e la VM di Compute Engine di origine non ha un indirizzo IP esterno.

Cloud NAT ha un'integrazione con l'accesso privato Google che attiva automaticamente l'accesso privato Google sulla subnet della risorsa e mantiene interno il traffico verso i servizi e le API di Google, anziché instradarlo a internet utilizzando l'indirizzo IP esterno del gateway Cloud NAT.

In questo caso, poiché il traffico viene instradato entro la rete Google interna, il campo RequestMetadata.caller_ip dell'oggetto AuditLog viene modificato in gce-internal-ip. Per risolvere il problema, anziché utilizzare l'indirizzo IP esterno del gateway Cloud NAT nel livello di accesso per la lista consentita basata su IP, configura una regola in entrata per consentire l'accesso dal progetto o dal service account.

Passaggi successivi