Soluciona problemas

En esta página, se indican varios problemas que pueden surgir al intentar configurar los controles de servicio de VPC.

Encuentra los errores en los controles del servicio de VPC

Esta sección detalla dos métodos para encontrar errores de VPC en tus registros de auditoría: usar un ID único de error o usar metadatos para identificar errores.

Usar el ID único del error

Un error generado por los Controles de servicio de VPC incluye un ID único que se utiliza para identificar registros de auditoría relevantes.

Este procedimiento usa términos de la documentación de Logging. Para obtener más información, consulte Filtros de registro básicos.

Para obtener información sobre un error con el ID único:

  1. En Cloud Console, ve a la página Stackdriver Logging del proyecto dentro del perímetro de servicio que activó el error.

    Ir a la página de Stackdriver Logging

  2. En el cuadro de filtro de búsqueda, ingrese el ID único del error.

Filtrar registros con metadatos

Para encontrar errores relacionados con los controles del servicio de VPC, usa Cloud Logging.

Console

Este procedimiento usa términos de la documentación de Logging. Para obtener más información, consulte Filtros de registro básicos.

Para obtener las últimas 24 horas de errores de los Controles del servicio de VPC en Logging:

  1. En Google Cloud Console, ve a la página Stackdriver Logging del proyecto dentro del perímetro de servicio.

    Ir a la página de Stackdriver Logging

  2. En el cuadro de filtro de búsqueda, ingresa lo siguiente:

    protoPayload.metadata.@type:"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
        
  3. En el menú del selector básico de recursos, seleccione Recurso auditado.

  4. En el menú desplegable del selector de intervalo de tiempo, seleccione Últimas 24 horas.

  5. De manera opcional, si deseas encontrar los errores de los Controles de servicio de VPC que se produjeron durante un período de tiempo diferente, usa el menú desplegable del selector de intervalo de tiempo para cambiarlo.

gcloud

Para obtener las últimas 24 horas de errores en los Controles del servicio de VPC, usa el siguiente comando:

gcloud logging read 'protoPayload.metadata.@type:"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"'
    

De forma predeterminada, el comando read está limitado a las últimas 24 horas. Para obtener registros de Controles de servicio de VPC para un período de tiempo diferente, usa uno de los siguientes comandos.

Para limitar los registros en relación con la fecha actual:

gcloud logging read \
      'protoPayload.metadata.@type:"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"' \
      --freshness=DURATION
    

Aquí:

Por ejemplo, para obtener todos los errores de los Controles del servicio de VPC que ocurrieron durante la última semana:

gcloud logging read \
      'protoPayload.metadata.@type:"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"' \
      --freshness=7d
    

Para limitar los registros a un período de tiempo específico:

gcloud logging read \
      'protoPayload.metadata.@type:"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata" AND
      timestamp>="DATETIME" AND
      timestamp<="DATETIME"'
    

Aquí:

Por ejemplo, para obtener todos los errores de los Controles de servicio de VPC que ocurrieron entre el 22 de marzo de 2019 y el 26 de marzo de 2019:

gcloud logging read \
      'protoPayload.metadata.@type:"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata" AND
      timestamp>="2019-03-22T23:59:59Z" AND
      timestamp<="2019-03-26T00:00:00Z"'
    

Servicios no admitidos

Para obtener más información sobre los productos y servicios compatibles con los Controles de servicio de VPC, consulta la página Productos compatibles.

Si intentas restringir un servicio no compatible con la herramienta de línea de comandos gcloud o la API de Access Context Manager, se producirá un error.

Los controles de servicio de VPC bloquearán el acceso de varios proyectos a los datos de los servicios compatibles. Además, el VIP restringido se puede usar para bloquear la capacidad de las cargas de trabajo para llamar a servicios no compatibles.

VPC compartida

Cuando se usa una VPC compartida, un perímetro de servicio que incluye proyectos que pertenecen a una red de VPC compartida también debe incluir el proyecto que aloja la red. Cuando los proyectos que pertenecen a una red de VPC compartida no están en el mismo perímetro que el proyecto host, es posible que los servicios no funcionen como se espera o que se bloqueen por completo.

Asegúrese de que el host de red de VPC compartida esté en el mismo perímetro de servicio que los proyectos conectados a la red.

Solicitudes entre perímetros

Normalmente, los niveles de acceso se usan para permitir solicitudes fuera de un perímetro de servicio para recursos protegidos dentro de un perímetro.

Sin embargo, se rechazarán las solicitudes de un proyecto en un perímetro de un recurso protegido en otro perímetro, incluso si un nivel de acceso normalmente permitiría la solicitud.

Por ejemplo, supongamos que el proyecto A en el perímetro 1 solicita un recurso del proyecto B. El recurso del proyecto B está protegido por el perímetro 2. Debido a que el Proyecto A está en un perímetro, incluso si un nivel de acceso para el Perímetro 2 normalmente permitiría la solicitud del recurso protegido, se rechaza la solicitud.

Existen dos maneras de facilitar las solicitudes entre perímetros:

  • Usa puentes perimetrales. Los puentes permiten que dos o más proyectos en diferentes perímetros realicen solicitudes a cualquier servicio en esos proyectos. Estas solicitudes se permiten incluso si los servicios están protegidos por los perímetros.

  • Asegúrese de que tanto el servicio solicitante como el recurso objetivo no estén protegidos por los perímetros. En este caso, la operación tendrá éxito porque no hay servicios protegidos.

Determinar si un error se debe a los Controles de servicio de VPC

Debido a que los Controles de servicio de VPC modifican ciertas propiedades de bajo nivel de Google Cloud, pueden tener efectos en cascada en los servicios que pueden ser difíciles de depurar si no sabes qué buscar.

Para identificar si el error está relacionado con los Controles de servicio de VPC, verifica si habilitaste los Controles de servicio de VPC y si los aplicaste a los proyectos y servicios que intentas usar. Esto se puede hacer a través de la herramienta de línea de comandos gcloud o Cloud Console.

Si estás usando un servicio marcado como servicio restringido por los servicios del Controlador de VPC en un proyecto que está dentro de un perímetro de servicio, los Controles de servicio de VPC podrían estar fallando.

Para obtener información sobre casos problemáticos conocidos, consulta Limitaciones de servicios conocidos.

Por lo general, los servicios propagan los mensajes de error de sus dependencias. Si encuentras uno de los siguientes errores, es indicativo de un problema con los controles del servicio de VPC.

  • Cloud Storage 403: Request violates VPC Service Controls.

  • BigQuery 403: VPC Service Controls: Request is prohibited by organization's policy.

  • Otros servicios 403: Request is prohibited by organization's policy.

Depurar una solicitud bloqueada por motivos inesperados por los Controles de servicio de VPC

El registro de auditoría de los Controles del servicio de VPC es la herramienta principal para depurar por qué una solicitud ha sido bloqueada por los Controles de servicio de VPC.

En la mayoría de los casos, cuando el acceso se bloqueó de forma inesperada, consulta los registros de auditoría del proyecto que originó la solicitud. Estos registros contienen datos significativos sobre los recursos solicitados y el motivo por el cual se rechazó la solicitud.

Para obtener más información sobre la visualización de registros, consulta Visualización de registros.

En la siguiente tabla se enumeran los valores violationReason que puedes encontrar cuando usas los Controles de servicio de VPC.

violationReason Explicación
RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER Los recursos enumerados en resourceNames en el registro de auditoría no se encuentran en el mismo perímetro de servicio.
NETWORK_NOT_IN_SAME_SERVICE_PERIMETER Los recursos correspondientes a callerNetwork y resourceNames en el registro de auditoría no se encuentran en el mismo perímetro de servicio.
NO_MATCHING_ACCESS_LEVEL

La dirección IP correspondiente a callerIp en el registro de auditoría no coincide con ningún rango de IP en los niveles de acceso asignados al perímetro de servicio.

Situaciones de ejemplo

Los siguientes ejemplos abarcan las situaciones que puedes encontrar al usar los Controles de servicio de VPC.

Acceso a Cloud Storage desde las instalaciones

En este ejemplo, los Controles de servicio de VPC bloquean una solicitud de una estación de trabajo de empleado (identificada por callerIp) a un depósito de Cloud Storage en el proyecto corp-storage.

La solicitud genera el siguiente registro de auditoría:

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

El proyecto corp-storage se incluye en un perímetro de servicio. La estación de trabajo del empleado no forma parte de ninguna red dentro de ese perímetro. Debido a que la estación de trabajo del empleado existe fuera del perímetro, la solicitud se bloquea.

Acceso a BigQuery desde la VM fuera del proyecto

En este ejemplo, una VM que pertenece al proyecto 458854174376 (data-collector) intenta ejecutar una consulta de BigQuery contra un conjunto de datos en el proyecto 798816221974 (corp-resources-protected) y se rechaza.

La VM usa la siguiente consulta:

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

La consulta muestra lo siguiente:

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

Se genera el siguiente registro de registro de auditoría:

{
     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@example.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"
    }
    

En este ejemplo, violationReason es NETWORK_NOT_IN_SAME_SERVICE_PERIMETER. callerNetwork se incluye además de callerIp. La dirección IP es privada y la red se proporciona para eliminar ambigüedades. Los recursos relevantes en cuestión se enumeran en dos lugares: VpcServiceControlAuditMetadata.resourceNames y requestMetadata.callerNetwork (el proyecto que posee la red).

El problema es que el proyecto corp-resources-protected está dentro de un perímetro de servicio, mientras que data-collector, el proyecto que incluye la red a la que pertenece la VM no lo está. En este caso, el acceso se rechaza como se espera.

Consulta de BigQuery en varios proyectos

En este ejemplo, una VM que pertenece al proyecto perimeter-network intenta consultar las instancias de BigQuery de dos proyectos diferentes: corp-resources-protected, que está en el mismo perímetro de servicio que perimeter-network y corp-resources-public, que no lo es.

La VM usa el siguiente 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 consulta muestra lo siguiente:

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
    

Se genera el siguiente registro de auditoría:

{
     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 cuanto a callerNetwork y VpcServiceControlAuditMetadata.resourceNames, podemos ver tres proyectos: perimeter-network, 117961063178 (corp-resources-public) y 690885588241 (corp-resources-protected). Recuerde que corp-resources-public no está en el mismo perímetro de servicio que perimeter-network y corp-resources-protected.

violationReason, RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER indica que algún recurso de la solicitud está fuera de un perímetro que se aplica a la solicitud. En este caso, ese recurso es corp-resources-public.

Mover el archivo de Cloud Storage desde la VM dentro del perímetro

En este ejemplo, una VM del proyecto perimeter-network usa un comando para mover un archivo de un depósito de Cloud Storage, ubicado en el proyecto corp-resources-protected, a otro depósito, ubicado en el proyecto corp-resources-public.

La VM usa el siguiente comando:

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

El comando muestra lo siguiente:

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

Se genera el siguiente registro de auditoría:

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

En este caso, el registro es menos claro porque el método indicado es BillingRequiredRead y la acción realizada es move. Esta es una limitación de la funcionalidad actual del registro de auditoría de los Controles de servicio de VPC.

Si bien el motivo es menos claro, este registro de auditoría indica que algún recurso de la solicitud está fuera de un perímetro que se aplica a la solicitud. En este caso, ese recurso es corp-resources-public.

Mover el archivo de Cloud Storage desde la VM fuera del perímetro

En este ejemplo, una VM del proyecto public-network usa un comando para mover un archivo de un depósito de Cloud Storage, ubicado en el proyecto corp-resources-protected, a otro depósito, ubicado en el proyecto corp-resources-public.

corp-resources-protected está protegido por un perímetro de servicio. public-network y corp-resources-public existen fuera del perímetro.

La VM usa el siguiente comando:

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

El comando muestra lo siguiente:

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

Se genera el siguiente registro de auditoría:

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

En este ejemplo, el registro de auditoría indica que no se pueden copiar datos entre los límites de un perímetro de servicio (ambos recursos están en el registro de auditoría). Recuerde que la solicitud se origina fuera del perímetro (la VM en public-network) y que uno de los depósitos existe fuera del perímetro (corp-resources-public-1).

Desde fuera del perímetro, se puede escribir en el depósito corp-resources-public-1, por lo que se aprueba la verificación que falló en el ejemplo anterior. Sin embargo, la verificación posterior para copiar realmente los datos falla.

En este ejemplo, se demuestra cómo, a veces, una sola operación de usuario da como resultado varias operaciones internas que deben pasar la aplicación de los controles de servicio de VPC.

Copia del conjunto de datos de BigQuery de la VM dentro del perímetro

En este ejemplo, una VM del proyecto 927005422713 (perimeter-network) intenta copiar un conjunto de datos de BigQuery del proyecto corp-resources-private a corp-resources-public (117961063178). perimeter-network y corp-resources-private comparten un perímetro, mientras que corp-resources-public existe fuera del perímetro.

La VM usa el siguiente comando:

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

El comando muestra lo siguiente:

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

Se genera el siguiente registro de auditoría:

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

En este ejemplo, no hay ninguna acción subyacente de la API que muestre todos los recursos en juego en esta solicitud debido a limitaciones del mecanismo de registro y la arquitectura distribuida de BigQuery.

El registro de auditoría indica que la operación falló porque para copiar los datos, BigQuery debe acceder al proyecto objetivo (corp-resources-public) mediante la red del proyecto perimeter-network (la fuente de la solicitud). Recuerde que corp-resources-public está fuera del perímetro que protege perimeter-network. La solicitud se rechaza como un intento de extraer datos a corp-resources-public.

Este ejemplo ilustra que una operación conceptual, como copiar datos, puede desencadenar varios intentos de acceso a datos desde diferentes sistemas de almacenamiento, como Cloud Storage, BigQuery y Bigtable. Según el modo en que se ejecuta la operación, el registro de auditoría que se genera puede parecer diferente del comando original del usuario, especialmente cuando se realizan varias verificaciones dentro de un servicio determinado y pueden fallar.

Lectura de trabajos de Dataproc del proyecto

En este ejemplo, se muestra cómo depurar los errores indirectos de los controles del servicio de VPC que ocurren cuando se usan servicios de procesamiento de datos, como Dataproc.

En este ejemplo, un clúster de Dataproc se está ejecutando en un proyecto protegido por los Controles de servicio de VPC. Hello-world.py es un trabajo de pyspark que intenta acceder a los datos del depósito de Cloud Storage dentro del perímetro y luego escribirlo en otro depósito fuera del perímetro, operación que los Controles de servicio de VPC deberían bloquear.

El siguiente comando se usa para ejecutar Hello-world.py:

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

El comando muestra lo siguiente:

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

Observe la excepción IO que se produce cuando se invoca saveAsTextFile. Cloud Storage muestra un error 403 con el mensaje Request violates VPC Service Controls. El error indica que debe revisarse la operación de registro de auditoría de Cloud Storage.

En los registros de auditoría del proyecto perimeter-network, donde se ejecutó el comando, hay un registro de auditoría para la operación 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@example.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"
    }
    

Debido a las limitaciones del registro de auditoría, methodName para Cloud Storage aparece como Read, aunque en realidad es una operación write. El registro de auditoría indica que la operación falló porque una red del proyecto corp-resources-private intentaba acceder a los datos (escritura, en este caso) de un recurso en el depósito corp-resources-public-1. Debido a las limitaciones del registro de auditoría de Cloud Storage, no está claro a qué corp-resources-public-1 pertenece el depósito del proyecto.

Para identificar el proyecto que contiene corp-resources-public-1, se usa el siguiente comando:

gsutil --debug ls -L -b gs://corp-resources-public-1 2>&1 | grep projectNumber
    

El comando muestra lo siguiente:

projectNumber: u'117961063178'
    

117961063178 es el proyecto corp-resources-public, que está fuera del perímetro. Por lo tanto, se espera una falla.

Servicio no admitido con VIP restringido

Si intentas acceder a una API que no es compatible con la VIP restringida de los Controles de servicio de VPC, se producirá un error 404. Por ejemplo, debido a que Cloud DNS actualmente no es compatible con los controles de servicio de VPC, la API de Cloud DNS no está disponible cuando se usa el VIP restringido.

Por ejemplo, supongamos que se usa el siguiente comando:

gcloud dns managed-zones list
    

El comando muestra lo siguiente:

ERROR: (gcloud.dns.managed-zones.list) Project [corp-resources-private] not found: <!DOCTYPE html>
    <html lang=en>
      <meta charset=utf-8>
      <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
      <title>Error 404 (Not Found)!!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>404.</b> <ins>That's an error.</ins>
      <p>The requested URL <code>/dns/v1/projects/corp-resources-private/managedZones</code> was not found on this server.  <ins>That's all we know.</ins>
    

Se espera este tipo de error para los servicios que no son compatibles con los Controles de servicio de VPC y no están disponibles en el VIP restringido. Si este error se produce para un servicio que es compatible con los Controles de servicio de VPC, deberías verificar las limitaciones de servicio conocidas para ese servicio para ver si se trata de una limitación conocida. De lo contrario, el problema debería denunciarse.

Exportación de registros al proyecto fuera del perímetro

En este ejemplo, los controles de servicio de VPC bloquean una exportación de registros. El proyecto corp-resources-public de destino de exportación está fuera del perímetro de controles de servicio de VPC, mientras que el receptor se crea en el proyecto perimeter-network, que está dentro del perímetro.

Por ejemplo, supongamos que se usa el siguiente comando:

gcloud logging sinks describe example-sink
    

El comando muestra lo siguiente:

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

    

Se genera el siguiente registro de auditoría:

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

El registro de auditoría se genera para BigQuery, no para Logging. Esto se debe a que BigQuery es el servicio receptor en el que Logging intenta escribir.

La exportación falla porque corp-resources-public existe fuera del perímetro que protege perimeter-network.

Este ejemplo muestra que cuando un servicio de Google Cloud llama a otro mediante una cuenta de servicio administrado interno a GCP como p927005422713-439672@gcp-sa-logging.iam.gserviceaccount.com, el "proyecto de red" (en este caso, perimeter-network) de esa solicitud deriva de esa identidad. La misma identidad representa el recurso de exportación de registros.

Este patrón es común en Google Cloud y se aplica a numerosos casos de interacción entre servicios.

Extraer BigQuery en Cloud Storage

En este ejemplo, se describe cómo depurar extracciones de BigQuery en Cloud Storage.

En este ejemplo, corp-resources-private y perimeter-network son proyectos protegidos por un perímetro de servicio. corp-resources-public es un proyecto que existe fuera del perímetro.

Supongamos que se usó el siguiente comando:

bq extract babynames.yob2000
    

El comando muestra lo siguiente:

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.
    

En este caso, el error no implica específicamente los Controles de servicio de VPC (se mostraría un error similar si se produjera un error de Cloud Identity and Access Management).

Se genera el siguiente registro de auditoría:

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

En este registro de auditoría, storage-accessing@example.iam.gserviceaccount.com se identifica como la identidad que intenta ejecutar la operación. En este ejemplo, supongamos que storage-accessing@example.iam.gserviceaccount.com tiene los permisos necesarios de Cloud IAM para ejecutar el comando.

Dado que los permisos de Cloud IAM no son el problema, el siguiente paso es comprobar si hay fallas en los controles del servicio de VPC.

El registro de auditoría del servicio de destino (Cloud Storage) contiene los motivos detallados del error:

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

En este registro, está claro que los dos proyectos 1004338142803 (corp-resources-private-1) y corp-resources-public se usan para completar el comando. Debido a que esos proyectos no comparten un perímetro, el trabajo de extracción falla.

Este ejemplo ilustra que en operaciones complejas de varios servicios, los registros de auditoría para los servicios de origen y de destino pueden contener datos de depuración útiles.