Cette page présente les problèmes que vous pouvez rencontrer lors de la configuration de VPC Service Controls.
Comportement inattendu de la règle à champ d'application
Vous remarquerez peut-être des cas de non-respect inattendus liés à VPC Service Controls définie doit permettre. Il s'agit d'un problème connu que, si vous ne disposez pas des règles d'accès au niveau de l'organisation, vous risquez de rencontrer les problèmes liés à vos règles d'accès délimitées.
Pour résoudre ce problème, créez une règle d'accès au niveau de l'organisation à l'aide de la commande suivante :
gcloud access-context-manager policies create --organization <var>ORGANIZATION_ID</var> --title <var>POLICY_TITLE</var>
Remplacez les éléments suivants :
- ORGANIZATION_ID : ID de l'organisation.
- POLICY_TITLE: titre lisible pour votre règle d'accès.
Pour en savoir plus, consultez la section Créer une règle d'accès.
VPC partagé
Lorsque vous utilisez un VPC partagé, le périmètre de service incluant les projets appartenant à un réseau VPC partagé doit également inclure le projet qui héberge le réseau. Lorsque les projets appartenant à un réseau VPC partagé ne se trouvent pas dans le même périmètre que le projet hôte, les services peuvent ne pas fonctionner comme prévu ou être entièrement bloqués.
Vérifiez que l'hôte du réseau VPC partagé se trouve dans le même périmètre de service que les projets connectés au réseau.
Impossible d'ajouter un réseau VPC
L'erreur suivante peut se produire lorsque vous essayez d'ajouter un réseau VPC à un périmètre de service:
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)
Cette erreur se produit pour l'une des raisons suivantes :
- Le réseau VPC n'existe pas.
- Le réseau VPC existe, mais ne comporte pas de sous-réseau.
- L'appelant ne dispose pas de l'autorisation requise.
Pour résoudre ce problème, procédez comme suit :
Vérifiez si le réseau VPC spécifié dans le message d'erreur existe en affichant les réseaux de votre projet.
Avant de vérifier le réseau VPC, assurez-vous que le L'API Compute Engine est activée dans le projet associé à l'appel d'API. en procédant comme suit:
Dans la console Google Cloud, accédez à la page API et services.
Accéder aux API et servicesSur la page API et services, vérifiez si l'API Compute Engine est listée.
Si l'API Compute Engine est manquante, activez-la.
Activez le API
Vérifiez si au moins un sous-réseau existe dans le réseau VPC en affichant les sous-réseaux. Si aucun sous-réseau n'est défini, ajoutez-en un au réseau VPC.
Vérifiez si l'appelant dispose de l'autorisation suivante sur le projet hôte du Réseau VPC:
compute.networks.get
. Cette autorisation vous permet d'afficher les réseaux VPC d'un projet.Demander à l'administrateur de l'organisation propriétaire du projet hôte de au réseau VPC pour accorder à l'appelant disposant de l'autorisation
compute.networks.get
sur le projet hôte. Pour par exemple, le rôle "Lecteur de réseau Compute".Pour en savoir plus sur l'attribution de rôles, consultez la page Gérer l'accès.
Veillez à lire les limites à l'utilisation de réseaux VPC dans les périmètres de service.
Requêtes entre périmètres
Normalement, des niveaux d'accès sont utilisés pour autoriser les requêtes provenant de l'extérieur d'un périmètre de service pour des ressources protégées à l'intérieur d'un périmètre.
Cependant, une requête provenant d'un projet situé dans un périmètre et portant sur une ressource protégée dans un autre périmètre est refusée, même si le niveau d'accès autorise normalement la requête.
Supposons que le projet A du périmètre 1 envoie une requête pour une ressource du projet B. La ressource du projet B est protégée par le périmètre 2. La requête est refusée car le projet A se trouve dans un périmètre distinct, même si un niveau d'accès pour le périmètre 2 autorise normalement la requête pour la ressource protégée.
Pour faciliter les requêtes entre les périmètres, utilisez l'une des approches suivantes :
Utilisez une règle de sortie et une règle d'entrée. Pour autoriser les requêtes provenant d'un autre périmètre vers des ressources protégées dans votre périmètre, l'autre périmètre doit utiliser une règle de sortie et vous devez définir une règle d'entrée dans votre périmètre.
Utiliser les liaisons de périmètre. Les liaisons permettent à deux projets ou plus situés dans des périmètres différents d'envoyer des requêtes à tous les services de ces projets. Ces demandes sont autorisées même si le sont protégés par les périmètres respectifs.
Assurez-vous que les périmètres ne protègent pas le service demandeur et la ressource cible. L'opération va alors réussir, car les services ne sont pas protégés.
L'adresse e-mail est incorrecte ou inexistante
Lorsque vous mettez à jour un périmètre contenant un principal supprimé, le message d'erreur The email address is invalid or non-existent
peut s'afficher.
Pour résoudre ce problème, vous pouvez effectuer l'une des tâches suivantes:
Supprimez l'adresse e-mail non valide du périmètre, qui comprend les niveaux d'accès et les règles d'entrée et de sortie.
Vous pouvez utiliser la console Google Cloud ou la Google Cloud CLI.
Effectuez une opération groupée (Google Cloud CLI uniquement) si l'adresse e-mail figure à la fois dans le test et dans le périmètre appliqué.
- Obtenez tous vos périmètres:
gcloud access-context-manager perimeters list --format=list \ --policy=<POLICY_NAME> > my-perimeters.yaml
Supprimez l'adresse e-mail non valide du fichier
my-perimeters.yaml
, puis enregistrez-le sous le nommy-perimeters-updated.yaml
.Remplacez tous vos périmètres :
gcloud access-context-manager perimeters replace-all --format=list \ --source-file=my-perimeters-updated.yaml \ --policy=<POLICY_NAME>
Violations des règles d'entrée et de sortie
Le journal d'audit contient des informations sur les violations des règles d'entrée et de sortie qui vous aident à comprendre les violations de périmètre.
Violations des règles d'entrée
Une violation de règle d'entrée indique qu'un client API situé en dehors du périmètre a tenté d'accéder à une ressource située à l'intérieur du périmètre. Le périmètre de service rejette la requête, car il n'existe aucune règle d'entrée ni aucun niveau d'accès correspondant.
Une violation de règle d'entrée dans le journal d'audit contient les détails suivants :
- Le nom du périmètre dans lequel la violation de la règle d'entrée s'est produite.
- La ressource au sein du périmètre à laquelle le client API en dehors du périmètre a tenté d'accéder.
Dans l'exemple de violation de règle d'entrée suivant, un client API en dehors du périmètre tente d'accéder au bucket Cloud Storage prod-protected-storage-bucket
situé au sein du périmètre prod-perimeter
.
ingressViolations: [
0: {
targetResource: "projects/1234/buckets/prod-protected-storage-bucket"
servicePerimeter: "accessPolicies/123456789/servicePerimeters/prod-perimeter"
}
]
Pour résoudre ce problème, créez une règle d'entrée pour votre périmètre. Pour en savoir plus sur les règles d'entrée, consultez la documentation de référence sur les règles d'entrée.
Violation des règles de sortie
Une violation de règle de sortie dans le journal d'audit indique l'un des événements suivants :
- Un client API au sein du périmètre a tenté d'accéder à une ressource située en dehors du périmètre.
- Une requête API implique une ressource située à l'intérieur du périmètre et une ressource en dehors du périmètre. Par exemple, un client Cloud Storage appelle une commande de copie, où un bucket se trouve dans le périmètre et l'autre en dehors du périmètre.
Le périmètre de service rejette la requête, car il n'existe aucune règle de sortie correspondante. Une violation de règle de sortie dans le journal d'audit inclut les éléments suivants :
- Le type de source, tel que le réseau ou la ressource.
- La source, qui est une ressource ou un réseau, pour laquelle le périmètre a rencontré une violation de sortie.
- Le périmètre qui a rencontré une violation de sortie.
- La ressource cible située en dehors du périmètre auquel la requête a tenté d'accéder.
Dans l'exemple de violation de règle de sortie suivant, la requête API inclut une ressource de projets/5678, qui se trouve dans le périmètre prod-perimeter
, et un objet du bucket Cloud Storage external-storage-bucket
, qui se trouve en dehors du périmètre.
egressViolations: [
0: {
sourceType: "Resource"
source: "projects/5678"
targetResource: "projects/4321/buckets/external-storage-bucket/objects/corp-resources.json"
servicePerimeter: "accessPolicies/123456789/servicePerimeters/prod-perimeter"
}
]
Pour résoudre ce problème, créez une règle de sortie pour votre périmètre. Pour en savoir plus sur les règles de sortie, consultez la section Règles de sortie référence.
Requêtes de débogage bloquées par VPC Service Controls
Le journal d'audit de VPC Service Controls est le principal outil de débogage permettant d'identifier la raison pour laquelle une requête a été bloquée par VPC Service Controls.
Lorsque l'accès a été bloqué de manière inattendue, consultez les journaux d'audit dans le projet protégé par le périmètre de service. Ces journaux contiennent des données significatives sur les ressources demandées et la raison pour laquelle la demande a été refusée. Pour en savoir plus sur les journaux d'audit, consultez la section Diagnostiquer des problèmes à l'aide de l'outil de dépannage.
Les sections suivantes répertorient les valeurs violationReason
que vous pouvez rencontrer
lorsque vous utilisez VPC Service Controls.
NETWORK_NOT_IN_SAME_SERVICE_PERIMETER
Ce problème peut être dû à l'une des raisons suivantes :
- Un client d'un réseau VPC dans un périmètre de service tente d'accéder à un projet qui ne fait pas partie du même périmètre. Cette requête entraîne une violation de sortie. Créez une règle de sortie pour résoudre ce problème.
- Un client d'un réseau VPC situé en dehors d'un périmètre de service tente d'accéder à un projet protégé par ce périmètre. Cette demande entraîne une violation d'entrée. Créez une règle d'entrée pour résoudre ce problème.
Le client peut envoyer la requête à partir d'une VM Compute Engine ou Google Kubernetes Engine, ou à partir d'un réseau sur site via Cloud Interconnect ou d'un VPN configuré à l'aide d'un réseau VPC.
Le diagramme suivant montre qu'une violation de sortie se produit lorsqu'un client d'un réseau VPC situé dans un périmètre de service tente d'accéder à un projet en dehors du périmètre :
Voici un exemple de non-respect des règles d'egress :
egressViolations: [
{
servicePerimeter: "accessPolicies/<POLICY_NAME>/servicePerimeters/<PERIMETER_NAME>"
source: "projects/<NETWORK_PROJECT_NUMBER>"
sourceType: "Network"
targetResource: "projects/<RESOURCE_PROJECT_NUMBER>"
}
]
Où :
<POLICY_NAME>
est le nom numérique de votre règle d'accès.<PERIMETER_NAME>
est le nom du périmètre de service.<NETWORK_PROJECT_NUMBER>
est le numéro du projet Google Cloud qui contient votre réseau VPC.<RESOURCE_PROJECT_NUMBER>
est le numéro du projet Google Cloud contenant la ressource.
Le diagramme suivant montre qu'une violation d'entrée se produit lorsqu'un client en dehors du périmètre tente d'accéder à un projet situé à l'intérieur du périmètre :
Voici un exemple de non-respect des règles d'accès :
ingressViolations: [
{
targetResource: "projects/<RESOURCE_PROJECT_NUMBER>",
source: "projects/<NETWORK_PROJECT_NUMBER>"
servicePerimeter: "accessPolicies/<POLICY_NAME>/servicePerimeters/<PERIMETER_NAME>"
}
]
Où :
<RESOURCE_PROJECT_NUMBER>
est le numéro du projet Google Cloud contenant la ressource.<NETWORK_PROJECT_NUMBER>
est le numéro du projet Google Cloud qui contient votre réseau VPC.<POLICY_NAME>
est le nom numérique de votre règle d'accès.<PERIMETER_NAME>
est le nom du périmètre de service.
Solution
Pour résoudre cette erreur, créez une règle d'entrée ou de sortie pour votre périmètre.
RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER
Ce problème se produit lorsqu'une même requête accède à plusieurs ressources, mais que la ne se trouvent pas dans le même périmètre de service. Ce problème survient indépendamment l'emplacement du client et s'il a accès aux ressources.
Le schéma suivant montre un client accédant aux ressources à partir d'un projet en dehors du périmètre et d'un projet dans le périmètre de service :
Le schéma suivant montre un client accédant aux ressources de projets situés dans deux périmètres de service différents, mais qui ne communiquent pas entre eux :
Voici un exemple de non-respect des règles de sortie:
egressViolations: [
{
servicePerimeter: "accessPolicies/<POLICY_NAME>/servicePerimeters/<PERIMETER_NAME>"
source: "projects/<RESOURCE_PROJECT_INSIDE_THIS_PERIMETER>"
sourceType: "Resource"
targetResource: "projects/<RESOURCE_PROJECT_OUTSIDE_THIS-PERIMETER>"
}
]
Où :
<POLICY_NAME>
est le nom numérique de votre règle d'accès.<PERIMETER_NAME>
est le nom du périmètre de service.<RESOURCE_PROJECT_INSIDE_THIS_PERIMETER>
est le numéro du projet Google Cloud situé dans le périmètre.<RESOURCE_PROJECT_OUTSIDE_THIS_PERIMETER>
est le numéro du projet Google Cloud situé en dehors du périmètre.
Solution
Pour résoudre ce problème, créez une règle de sortie pour votre périmètre.
NO_MATCHING_ACCESS_LEVEL
Ce problème survient lorsque l'adresse IP, la configuration requise de l'appareil ou l'identité de l'utilisateur
ne correspond à aucune règle d'entrée ni aucun niveau d'accès attribué au périmètre. Cela signifie qu'un client qui ne fait pas partie du réseau Google Cloud tente d'accéder aux ressources réseau Google Cloud en dehors du périmètre. Par exemple, l'adresse IP correspondant au champ callerIp
de l'enregistrement d'audit ne correspond à aucune plage CIDR définie dans les niveaux d'accès du périmètre de service.
Si l'adresse IP de l'appelant est manquante ou apparaît en tant qu'adresse IP interne, cette violation peut être due à un service Google Cloud qui n'est pas intégré à VPC Service Controls. Cela peut être dû au fait que le service Google Cloud tente d'accéder à un service protégé et échoue, comme prévu.
Pour résoudre ce problème, nous vous recommandons de créer une règle d'entrée plutôt qu'un niveau d'accès, car une règle d'entrée offre un contrôle d'accès précis.
Le schéma suivant montre un client qui tente d'accéder à des ressources en dehors du périmètre :
Voici un exemple de violation d'entrée:
authenticationInfo: {
principalEmail: "EMAIL"
}
requestMetadata: {
callerIp: "<PUBLIC_IP_ADDRESS>"
deviceState: "Cross Organization"
}
ingressViolations: [
{
targetResource: "projects/<RESOURCE_PROJECT_NUMBER>",
servicePerimeter: "accessPolicies/<POLICY_NAME>/servicePerimeters/<PERIMETER-NAME>"
}
]
Où :
<EMAIL>
est l'adresse e-mail du compte de service ou de l'utilisateur authentifié.Si vous utilisez un service Google Cloud que VPC Service Controls n'utilise pas assistance, les adresses e-mail appartenant au domaine
google.com
sont masqués et remplacés pargoogle-internal
google-internal
fait référence aux identités internes appartenant à Google.<PUBLIC_IP_ADDRESS>
est l'adresse IP de l'appelant. Pour un appelant depuis Internet, il s'agit de l'adresse IPv4 ou IPv6 publique.<RESOURCE_PROJECT_NUMBER>
est le numéro du projet Google Cloud contenant la ressource.<POLICY_NAME>
est le nom numérique de votre règle d'accès.<PERIMETER_NAME>
est le nom du périmètre de service.
Notez que dans ce cas, metadata.accessLevels
peut toujours être présent puisque
ces niveaux d'accès peuvent ne pas être spécifiés dans le périmètre enfreint.
SERVICE_NOT_ALLOWED_FROM_VPC
Ce problème survient lorsqu'un client tente d'accéder aux ressources Google Cloud à partir d'un réseau VPC. Le client peut envoyer la requête à partir d'une VM Compute Engine ou Google Kubernetes Engine, ou d'un réseau sur site via Cloud Interconnect ou un VPN configuré à l'aide d'un réseau VPC.
Pour résoudre ce problème, assurez-vous que le service appelé est autorisé par le réseau VPC accessible services du périmètre de service.
Exemples de cas de figure
Les exemples suivants couvrent des problèmes que vous pouvez rencontrer lors de l'utilisation de VPC Service Controls :
- Accès à Cloud Storage à partir d'un environnement sur site
- Accès à BigQuery à partir d'une VM située en dehors du projet
- Requête BigQuery entre projets
- Déplacer un fichier Cloud Storage dans le périmètre
- Déplacer un fichier Cloud Storage en dehors du périmètre
- Copie d'un ensemble de données BigQuery à partir d'une VM située dans le périmètre
- Lecture d'une tâche Dataproc à partir d'un projet
- Service non compatible avec l'adresse IP virtuelle restreinte
- Exportation de journal vers un projet situé en dehors du périmètre
- Extraction BigQuery vers Cloud Storage
Accès à Cloud Storage à partir d'un environnement sur site
Dans cet exemple, VPC Service Controls bloque une requête provenant du poste de travail d'un employé (identifié par callerIp
) vers un bucket Cloud Storage dans le projet corp-storage
.
La requête génère l'enregistrement de journal d'audit suivant :
{
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"
}
Le projet corp-storage
est inclus dans un périmètre de service. Le poste de travail de l'employé n'appartient à aucun réseau de ce périmètre. Comme le poste de travail de l'employé existe en dehors du périmètre, la requête est bloquée.
Accès à BigQuery à partir d'une VM située en dehors du projet
Dans cet exemple, une VM appartenant au projet 458854174376
(data-collector
) tente d'exécuter une requête BigQuery sur un ensemble de données du projet 798816221974
(corp-resources-protected
) ; cette requête est refusée.
La VM utilise la requête suivante :
bq --project=corp-resources-protected query 'select count(*) from babynames.yob2000'
La requête renvoie le résultat suivant :
BigQuery error in query operation: VPC Service Controls: Request is
prohibited by organization's policy. Operation ID:
33643962-6a0f-4091-9283-bcdf7e9271f0
L'enregistrement de journal d'audit suivant est généré :
{
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"
}
Dans cet exemple, violationReason
est NETWORK_NOT_IN_SAME_SERVICE_PERIMETER
. callerNetwork
est inclus en plus de callerIp
. L'adresse IP est privée et le réseau est spécifié afin de lever toute ambiguïté. Les ressources pertinentes en cause ici sont répertoriées à deux emplacements : VpcServiceControlAuditMetadata.resourceNames
et requestMetadata.callerNetwork
(le projet qui héberge le réseau).
Le problème se produit car le projet corp-resources-protected
se trouve dans un périmètre de service, tandis que data-collector
, le projet qui inclut le réseau auquel la VM appartient, n'en fait pas partie. Dans ce cas, l'accès est logiquement refusé.
Requête BigQuery entre projets
Dans cet exemple, une VM appartenant au projet perimeter-network
tente d'interroger les instances BigQuery de deux projets différents : corp-resources-protected
, qui se trouve dans le même périmètre de service que perimeter-network
, et corp-resources-public
, qui se trouve lui en dehors.
La VM utilise la commande suivante :
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 requête renvoie le résultat suivant :
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
L'enregistrement de journal d'audit suivant est généré :
{
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"
}
En examinant callerNetwork
et VpcServiceControlAuditMetadata.resourceNames
, nous pouvons voir trois projets : perimeter-network
, 117961063178
(corp-resources-public
) et 690885588241
(corp-resources-protected
). Rappelez-vous que corp-resources-public
ne se situe pas dans le même périmètre de service que perimeter-network
et corp-resources-protected
.
L'enregistrement violationReason
, RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER
indique que certaines ressources de la requête se situent en dehors du périmètre s'appliquant à la requête. Dans le cas présent, il s'agit de la ressource corp-resources-public
.
Déplacer un fichier Cloud Storage dans le périmètre
Dans cet exemple, une VM du projet perimeter-network
utilise une commande pour déplacer un fichier d'un bucket Cloud Storage, situé dans le projet corp-resources-protected
, vers un autre bucket, situé dans le projet corp-resources-public
.
La VM utilise la commande suivante :
gcloud storage mv gs://corp-resources-private-1/yob2000.txt gs://corp-resources-public-1/babynames/
La commande renvoie le résultat suivant :
Copying gs://corp-resources-private-1/yob2000.txt [Content-Type=text/plain]...
AccessDeniedException: 403 Request violates VPC Service Controls.
L'enregistrement de journal d'audit suivant est généré :
{
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"
}
Dans ce cas, le journal est moins explicite, car la méthode indiquée est BillingRequiredRead
et l'action effectuée est move
. Il s'agit d'une limitation associée au journal d'audit actuel de VPC Service Controls.
Bien que le motif soit moins évident, l'enregistrement de journal d'audit nous informe qu'une ressource de la requête se situe en dehors d'un périmètre s'appliquant à la requête. Dans ce cas, cette ressource est corp-resources-public
.
Déplacer un fichier Cloud Storage en dehors du périmètre
Dans cet exemple, une VM du projet public-network
utilise une commande pour déplacer un fichier d'un bucket Cloud Storage, situé dans le projet corp-resources-protected
, vers un autre bucket, situé dans le projet corp-resources-public
.
Le projet corp-resources-protected
est protégé par un périmètre de service. Les projets public-network
et corp-resources-public
se situent en dehors du périmètre.
La VM utilise la commande suivante :
gcloud storage mv gs://corp-resources-private-1/yob2000.txt gs://corp-resources-public-1/babynames/
La commande renvoie le résultat suivant :
Copying gs://corp-resources-private-1/yob2000.txt [Content-Type=text/plain]...
AccessDeniedException: 403 Request violates VPC Service Controls.
L'enregistrement de journal d'audit suivant est généré :
{
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"
}
Dans cet exemple, le journal d'audit indique qu'il n'est pas possible de copier des données au-delà de la limite du périmètre d'un service (les deux ressources figurent dans l'enregistrement de journal d'audit).
Rappelez-vous que la requête provient de l'extérieur du périmètre (la VM du projet public-network
) et que l'un des buckets se situe en dehors du périmètre (corp-resources-public-1
).
Il est possible d'écrire des données dans le bucket corp-resources-public-1
depuis l'extérieur du périmètre, et de faire ainsi aboutir la vérification qui a échoué dans l'exemple précédent. Toutefois, la vérification ultérieure concernant la copie effective des données va échouer.
Cet exemple montre comment une opération utilisateur unique peut parfois entraîner plusieurs opérations internes qui doivent être autorisées par VPC Service Controls pour être appliquées.
Copie d'un ensemble de données BigQuery à partir d'une VM située dans le périmètre
Dans cet exemple, une VM du projet 927005422713
(perimeter-network
) tente de copier un ensemble de données BigQuery du projet corp-resources-private
vers le projet corp-resources-public
(117961063178
). Les projets perimeter-network
et corp-resources-private
partagent un même périmètre, tandis que corp-resources-public
se situe en dehors de ce périmètre.
La VM utilise la commande suivante :
bq cp corp-resources-private:babynames.yob2000 \
corp-resources-public:babynames.yob2000
La commande renvoie le résultat suivant :
BigQuery error in cp operation: VPC Service Controls: Request is prohibited by
organization's policy. Operation ID: c00dbc44-460f-4bd0-9d09-cda98ac800f9
L'enregistrement de journal d'audit suivant est généré :
{
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"
}
Dans cet exemple, aucune action d'API sous-jacente unique ne montre toutes les ressources en jeu dans cette requête, en raison des limites du mécanisme de journalisation et de l'architecture distribuée de BigQuery.
L'enregistrement du journal d'audit indique que l'opération a échoué car, pour pouvoir copier les données, BigQuery doit accéder au projet cible (corp-resources-public
) en utilisant le réseau du projet perimeter-network
(source de la requête). Rappelez-vous que le projet corp-resources-public
est situé en dehors du périmètre qui protège perimeter-network
. La requête est refusée, car elle est considérée comme une tentative d'exfiltration de données vers corp-resources-public
.
Cet exemple illustre le fait qu'une opération conceptuelle, telle que la copie de données, peut déclencher diverses tentatives d'accès aux données de différents systèmes de stockage, comme Cloud Storage, BigQuery ou Bigtable. Selon le mode d'exécution de l'opération, l'enregistrement de journal d'audit généré diffère de la commande utilisateur d'origine. De plus, lorsque plusieurs vérifications sont effectuées au sein d'un service donné et échouent potentiellement, l'enregistrement de journal d'audit généré semble différent de la commande utilisateur d'origine.
Lecture d'une tâche Dataproc à partir d'un projet
Cet exemple montre comment déboguer des erreurs indirectes liées à VPC Service Controls lors de l'utilisation de services de traitement de données tels que Dataproc.
Dans cet exemple, un cluster Dataproc est exécuté dans un projet protégé par VPC Service Controls. Hello-world.py
est une tâche pyspark qui tente d'accéder aux données d'un bucket Cloud Storage situé à l'intérieur du périmètre, puis de les écrire dans un autre bucket situé en dehors du périmètre.
VPC Service Controls bloque l'opération qui écrit des données dans un bucket situé en dehors du périmètre.
La commande suivante est utilisée pour exécuter Hello-world.py
:
gcloud dataproc jobs submit pyspark hello-world.py --cluster test-cluster-new2
La commande renvoie le résultat suivant :
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].
Notez l'exception d'E/S qui se produit lors de l'appel de la méthode saveAsTextFile
.
Cloud Storage renvoie une erreur 403
avec le message Request violates VPC Service Controls
. L'erreur indique que l'opération du journal d'audit Cloud Storage doit être examinée.
Dans les journaux d'audit du projet perimeter-network
, où la commande a été exécutée, il existe un enregistrement de journal d'audit pour l'opération 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"
}
En raison des limites du journal d'audit, le nom de la méthode (methodName
) pour Cloud Storage est défini sur Read
alors qu'il s'agit d'une opération write
. L'enregistrement du journal d'audit indique que l'opération a échoué, car un réseau du projet corp-resources-private
tentait d'accéder aux données (ici, en écriture) d'une ressource dans le bucket corp-resources-public-1
. En raison des limites du journal d'audit de Cloud Storage, il n'est pas possible de savoir à quel projet appartient le bucket corp-resources-public-1
.
Pour identifier le projet qui contient corp-resources-public-1
, utilisez la commande suivante :
gcloud storage ls gs://corp-resources-public-1 --buckets --log-http 2>&1 | grep projectNumber
La commande renvoie le résultat suivant:
"projectNumber": "117961063178",
117961063178
est le projet corp-resources-public
, qui se situe en dehors du périmètre.
L'erreur est donc une conséquence normale.
Erreur due à des services non compatibles
Certains services Google Cloud dépendent d'autres services Google Cloud dans le cadre de leur implémentation. Si un service non compatible tel qu'App Engine est utilisé dans un projet protégé par un périmètre, les ressources du service peuvent ne pas être accessibles.
Pour en savoir plus sur les problèmes connus, consultez la page Limites connues
Service incompatible avec l'adresse IP virtuelle restreinte
Toute tentative d'accès à une API incompatible avec l'adresse IP virtuelle restreinte de VPC Service Controls génère une erreur 403
. Par exemple, VPC Service Controls
n'est pas compatible avec App Engine. L'API App Engine Admin est donc
n'est pas disponible lors de l'utilisation de l'adresse IP virtuelle restreinte.
Par exemple, supposons que la commande suivante soit utilisée pour répertorier toutes les ressources App Engine services dans un périmètre de service:
gcloud app services list
La commande renvoie le résultat suivant :
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>
Ce type d'erreur est attendu pour les services non compatibles avec VPC Service Controls et qui ne sont pas disponibles sur l'adresse IP virtuelle restreinte. Si cette erreur pour un service compatible avec VPC Service Controls, nous vous recommandons de consulter la liste des services Limites pour ce service pour voir s'il s'agit d'une limitation connue. Dans le cas contraire, signalez le problème.
Exportation de journal vers un projet situé en dehors du périmètre
Dans cet exemple, une exportation de journal est bloquée par VPC Service Controls.
La destination de l'exportation (le projet corp-resources-public
) se trouve en dehors du périmètre de VPC Service Controls, tandis que le récepteur est créé sur le projet perimeter-network
, qui se situe dans le périmètre.
Supposons par exemple que la commande suivante soit utilisée :
gcloud logging sinks describe example-sink
La commande renvoie le résultat suivant :
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
L'enregistrement de journal d'audit suivant est généré :
{
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"
}
L'enregistrement de journal d'audit est généré pour BigQuery, et non pour Logging. En effet, BigQuery est le service du récepteur sur lequel Logging tente d'écrire des données.
L'exportation échoue, car corp-resources-public
se situe en dehors du périmètre qui protège perimeter-network
.
Cet exemple montre que lorsqu'un service Google Cloud appelle un autre service à l'aide d'un compte de service géré interne à Google Cloud, tel que p927005422713-439672@gcp-sa-logging.iam.gserviceaccount.com
, le "projet réseau" (ici, perimeter-network
) de la requête est dérivé de cette identité. Cette même identité représente la ressource d'exportation de journal elle-même.
Cette tendance est courante dans Google Cloud et s'applique à de nombreux cas d'interaction entre les services.
Extraction BigQuery vers Cloud Storage
Cet exemple explique comment déboguer les échecs d'extraction BigQuery vers Cloud Storage.
Ici, corp-resources-private
et perimeter-network
sont des projets protégés par un périmètre de service. corp-resources-public
est un projet qui se situe en dehors du périmètre.
Supposons que la commande suivante ait été utilisée :
bq extract babynames.yob2000
La commande renvoie le résultat suivant :
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.
Dans ce cas, l'erreur n'implique pas spécifiquement VPC Service Controls. Une erreur similaire s'affiche en cas d'échec de Cloud IAM.
L'enregistrement de journal d'audit suivant est généré :
{
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"
}
Dans cet enregistrement de journal d'audit, storage-accessing@example.iam.gserviceaccount.com
est considéré comme l'identité qui tente d'exécuter l'opération. Dans cet exemple, supposons que storage-accessing@example.iam.gserviceaccount.com
dispose des autorisations IAM requises pour exécuter la commande.
Comme les autorisations IAM ne sont pas en cause, l'étape suivante consiste à rechercher les échecs liés à VPC Service Controls.
L'enregistrement de journal d'audit pour le service de destination (Cloud Storage) contient les raisons détaillées de l'échec :
{
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"
}
Ce journal indique clairement que les deux projets 1004338142803
(corp-resources-private-1
) et corp-resources-public
sont tous deux utilisés pour exécuter la commande. Comme ils ne partagent pas de périmètre, la tâche d'extraction échoue.
Cet exemple montre que lorsque vous avez affaire à des opérations multiservices complexes, les journaux d'audit des services sources et de destination peuvent contenir des données de débogage utiles.
Accès au périmètre via la passerelle Cloud NAT
Supposons dans cet exemple que le projet A de l'organisation A ne soit configuré dans aucune périmètre. Le projet B est sécurisé par un périmètre dans une autre organisation. Les ressources privées du projet A utilisent la passerelle Cloud NAT pour accéder à Internet, ainsi qu'aux API et services Google. Un niveau d'accès est configuré sur le projet B pour autoriser l'accès en fonction des adresses IP de la passerelle externe du projet A.
Une VM appartenant au projet A (qui peut être un nœud Google Kubernetes Engine) tente d'accéder à une ressource protégée dans le projet B, mais la connexion échoue. L'enregistrement de journal d'audit suivant est généré dans le projet B :
{
"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 ressource callerIp
n'enregistre pas d'adresse IP externe. Au lieu de l'adresse IP externe de la passerelle Cloud NAT, la ressource callerIp
affiche gce-internal-ip
.
Le champ callerIp
est masqué dans gce-internal-ip
lorsque les requêtes
proviennent d'un autre projet ou d'une autre organisation, et la source
La VM Compute Engine ne possède pas d'adresse IP externe.
Cloud NAT offre une intégration avec l'accès privé à Google ; qui active automatiquement l'accès privé à Google sur le sous-réseau de la ressource, et maintient le trafic vers les API et services Google en interne, et les acheminer vers Internet à l'aide de la passerelle Cloud NAT externe l'adresse IP.
Dans ce cas, comme le trafic est acheminé dans le réseau Google interne, le champ RequestMetadata.caller_ip
de l'objet AuditLog
est masqué en gce-internal-ip
. Pour résoudre ce problème, au lieu d'utiliser le service
adresse IP externe de la passerelle dans le niveau d'accès pour la liste d'autorisation basée sur les adresses IP
configurer une règle d'entrée à autoriser depuis le projet ou le compte de service.
Étape suivante
- Découvrez comment récupérer les erreurs VPC Service Controls à partir des journaux d'audit.
- Découvrez comment résoudre les problèmes courants liés à d'autres services Google Cloud.