VPC Service Controls - BigQuery Data Transfer Service Protection

1. 简介

在本实验中,我们将了解如何在将数据从 Cloud Storage 转移到 BigQuery 数据集时,使用 VPC Service Controls 保护 BigQuery Data Transfer Service。然后,我们会保护 Cloud Storage,并重复上述过程,以便将数据从 Cloud Storage 转移到 BigQuery。Cloud Storage 的保护功能会导致 VPC Service Controls 违规,您需要解决此问题才能成功完成转移。最后,我们还保护了 BigQuery,然后尝试在项目之间复制数据集,这也会导致违规问题,需要进行修复。

在本实验中,我们将了解如何分别使用入站规则和出站规则来修正入站和出站违规问题。我们还将使用访问权限级别来修正 BigQuery Data Transfer 入站违规问题。此 Codelab 的目标如下:

  • 了解如何针对不同的服务(尤其是 Cloud Storage、BigQuery 和 BigQuery Data Transfer Service)分别使用入站规则和出站规则来修正入站和出站违规问题。
  • 了解发生特定违规行为的原因。

2. 资源设置和要求

准备工作

在此 Codelab 中,我们假设您已经了解:

设置

我们的初始设置如下所示:

Codelab 初始设置示意图

创建范围限定的政策和常规服务边界

在此 Codelab 中,我们将使用常规服务边界来保护 project-2

在边界 perimeter-2 中,限制 BigQuery Data Transfer API

保护数据传输服务的 VPC SC 配置。

创建 Cloud Storage 存储分区和 BigQuery 数据集

在本 Codelab 中,任何 CSV 文件都足以满足需求,无论内容如何。主要限制与共存要求有关,该要求强制执行以下规定:

  • 如果您的 BigQuery 数据集位于多区域,则包含您要转移的数据的 Cloud Storage 存储分区必须位于同一多区域或该多区域内的位置
  • 如果您的数据集位于某个区域,则 Cloud Storage 存储分区必须位于同一区域。

因此,在本 Codelab 中,我们将确保 Cloud Storage 存储分区和 BigQuery 数据集位于同一区域或多区域中。

在项目 project-1 中创建新的 Cloud Storage 存储分区

如需创建新的 Cloud Storage 存储分区,请按照创建新的存储分区的记录步骤操作。

  • 在存储分区名称中,输入符合存储分区名称要求的名称。在此 Codelab 中,我们将该存储分区命名为 codelab-bqtransfer-bucket
  • 在“数据存储位置”(即存储分区位置)部分,选择将永久存储存储分区数据的位置类型位置。在此 Codelab 中,我们将使用 us(美国的多个区域)

Cloud Storage 创建配置。

创建 CSV 文件

在本地机器上或使用 Cloud Shell,我们可以使用 echo 命令通过以下命令创建示例 CSV 文件 codelab-test-file.csv

echo "name,age" > codelab-test-file.csv; \
echo "Alice,10" >> codelab-test-file.csv; \
echo "Bob,20" >> codelab-test-file.csv; \
echo "Carol,30" >> codelab-test-file.csv; \
echo "Dan,40" >> codelab-test-file.csv; \
echo "Eve,50" >> codelab-test-file.csv; \
echo "Frank,60" >> codelab-test-file.csv; \
echo "Grace,70" >> codelab-test-file.csv; \
echo "Heidi,80" >> codelab-test-file.csv;

将 CSV 文件上传到 Cloud Storage 存储分区

创建 CSV 文件后,运行以下命令以将文件对象上传到创建的存储分区

gcloud storage cp codelab-test-file.csv gs://codelab-bqtransfer-bucket

运行 cp 命令将 csv 文件上传到 Cloud Storage。

您可以通过列出存储分区中的对象或运行以下命令来验证文件是否已上传到创建的存储分区:

gcloud storage ls --recursive gs://codelab-bqtransfer-bucket/**

project-2 中创建 BigQuery 数据集和表

  1. 按照这些步骤在项目 project-2 中创建 BigQuery 数据集。
    1. 对于数据集 ID,输入唯一的数据集名称。在此 Codelab 中,我们使用的是:codelab_bqtransfer_dataset
    2. 对于位置类型,为数据集选择一个地理位置。在此 Codelab 中,我们使用与 Cloud Storage 存储分区相同的位置:美国(美国的多个区域)创建 BigQuery 数据集。
  2. 按照这些步骤在创建的数据集 codelab_bqtransfer_dataset 下创建 BigQuery 表。
    1. 来源部分,在基于以下数据源创建表列表中选择空表
    2. 字段中,输入您要创建的表的名称。在此 Codelab 中,我们使用名称 codelab-bqtransfer-table
    3. 确认表类型字段是否设置为原生表
    4. 架构部分,输入架构定义。您可以点击以文本形式修改,然后输入符合创建的 CSV 文件格式的以下架构,以输入架构信息。
    [{
    "name": "name",
    "type": "STRING",
    "mode": "NULLABLE",
    "description": "The name"
    },
    {
    "name": "age",
    "type": "INTEGER",
    "mode": "NULLABLE",
    "description": "The age"
    }]
    

费用

您需要在项目 project-2project-1 中启用结算功能,才能使用 Cloud 资源/API。我们建议关闭所用资源,以免产生超出此 Codelab 范围的费用。

产生费用的资源是 BigQuery 和 Cloud Storage。您可以在 BigQuery 价格计算器Cloud Storage 计算器中查看估算费用。

3. 配置从 Cloud Storage 对象到 BigQuery 表的数据传输

现在,我们将尝试创建一个 Data Transfer Service(位于 project-2 中),以便从 Cloud Storage(位于 project-1 中)转移到 BigQuery(位于 project-2 中),同时让 VPC 服务控制功能保护 project-2 中的 BigQuery Data Transfer Service。仅保护 BigQuery Data Transfer Service(而不保护 BigQuery 和 Cloud Storage)会限制正文仅创建和管理数据传输(例如手动启动数据传输)。

设置从 Cloud Storage 传输数据

如需创建数据传输,请按以下步骤操作:

  1. 前往 project-2Google Cloud 控制台中的 BigQuery 页面
  2. 点击数据传输

“数据传输服务”页面上存在 VPC SC 违规问题。

在访问“数据传输作业”页面时调查违规问题

在 Google Cloud 控制台中,我们可以看到 VPC Service Controls 唯一标识符。使用相同的标识符过滤日志并确定违规详情(将 OBSERVED_VPCSC_DENIAL_UNIQUE_ID 替换为观察到的拒绝 ID):

protoPayload.metadata.@type="type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
protoPayload.metadata.vpcServiceControlsUniqueId="OBSERVED_VPCSC_DENIAL_UNIQUE_ID"

观察到的违规行为是 NO_MATCHING_ACCESS_LEVEL,这是一种入站流量违规行为,详细信息如下所示:

ingressViolations: [
0: {
servicePerimeter: "accessPolicies/987654321/servicePerimeters/perimeter-2"
targetResource: "projects/[PROJECT2_NUMBER]"
}]
violationReason: "NO_MATCHING_ACCESS_LEVEL"
callerIp: "USER_PUBLIC_IP_ADDRESS"
resource: {
labels: {
method: "google.cloud.bigquery.datatransfer.v1.DataTransferService.ListTransferConfigs"
project_id: "project-2"
service: "bigquerydatatransfer.googleapis.com"
}
type: "audited_resource"
}

访问“数据传输”页面会尝试列出任何已配置的数据传输;因此,会违反 ListTransferConfigs 方法。

解决了 bigquerydatatransfer.googleapis.com 服务的违规问题

您可以使用访问权限级别或入站规则来修正入站违规问题。在此 Codelab 中,我们将使用使用被拒绝的用户身份配置的入站规则,该规则允许访问 bigquerydatatransfer.googleapis.com 服务和所有方法。

用于允许数据传输方法的入站规则。

入站规则生效后,您应该可以顺利访问数据传输页面。

继续设置从 Cloud Storage 传输数据

在前面的步骤中,在“数据传输”页面上(点击“数据传输”后),继续执行以下步骤:

  1. 点击 + 创建转移作业
  2. 来源类型部分的来源中,选择 Google Cloud Storage
  3. 转移配置名称部分的显示名称中,输入转移作业的名称,例如 Codelab Transfer
  4. 时间表选项部分中,执行以下操作:
    1. 选择重复频率,例如 15 分钟。
    2. 请务必选择立即开始;否则,数据传输将仅在配置的重复频率之后开始
  5. 目标设置部分的目标数据集中,选择您创建的用来存储数据的数据集:codelab_bqtransfer_dataset
  6. 数据源详细信息部分中
    1. 对于 Destination table,输入目标表的名称。目标表必须遵循表命名规则。在此 Codelab 中,我们将使用之前创建的表:codelab-bqtransfer-table
    2. Cloud Storage URI 部分,输入 Cloud Storage URI。在本 Codelab 中,我们使用创建的存储分区和文件:codelab-bqtransfer-bucket/codelab-test-file.csv
    3. 写入偏好设置部分,保留 APPEND(或选择 MIRROR)。
    4. 请勿选择在转移后删除文件(因为我们会多次重复使用同一文件。不过,您可以使用多个文件,并在转移后删除源文件)
    5. 文件格式部分,选择 CSV
    6. 转移选项CSV 下,输入英文逗号(",") 作为字段分隔符
  7. 服务账号菜单中,从与您的 Google Cloud 项目关联的服务账号中选择一个服务账号
    1. 所选服务账号必须同时拥有托管存储分区的项目(本 Codelab 中的 project-1)上的 Cloud Storage 的必需权限
    2. 在本 Codelab 中,我们将使用在 project-2 中创建的服务账号作为 codelab-sa@project-2.iam.gserviceaccount.com
  8. 点击保存

由于我们选择了立即开始作为时间表选项,因此选择保存后,系统会立即开始首次传输。

验证数据传输服务状态

如需验证已配置的数据传输的状态,请执行以下操作:

Data Transfer Service 作业。

点击 Codelab Transfer(位于“显示名称”下方),系统会显示到目前为止执行的所有运行作业的列表。

Data Transfer Service 运行的详细信息。

数据传输作业应能成功运行,并且手动触发的数据传输和安排的数据传输都不会违反 VPC Service Controls 政策。请注意,只有手动触发的转移需要入站规则来允许手动发起转移的主账号访问。

4. 手动触发的数据传输的 IP 地址限制

当前配置的入站规则允许配置的身份从任何 IP 地址手动触发数据传输。

通过使用访问权限级别,VPC Service Controls 能够根据特定 API 请求属性限制允许的访问权限,具体而言:

  • IP 子网:检查请求是否来自特定 IP 地址。
  • 区域:检查请求是否来自特定区域,该区域由 IP 地址的地理位置决定。
  • 主账号:检查请求是否来自于特定账号。
  • 设备政策:检查请求是否来自符合特定要求的设备。

如需强制验证这些属性以及已配置的入站流量规则,我们必须创建一个允许所需属性的访问权限级别,然后在入站流量规则中将创建的访问权限级别添加为来源。

按用户 IP 地址由 VPC SC 保护的访问此图展示了两个正文(user@example.comuser2@example.com)在三种场景中发起的访问,演示了 VPC Service Controls 如何将来源(入站访问权限级别)和身份属性评估为必须匹配的 AND 条件。

  1. 当用户 user@example.com 尝试通过访问权限级别允许的 IP 地址进行访问时,系统会允许其访问,因为其 IP 地址和用户账号与入站规则中的配置相符。
  2. 用户 user@example.com 的 IP 地址与允许的 IP 地址不匹配,因此其访问权限被屏蔽,尽管其账号是入站规则中配置的账号。
  3. 用户 user2@example.com 在尝试使用允许的 IP 地址进行访问时被屏蔽,因为入站规则不允许其账号进行访问。

创建访问权限级别

如需创建按 IP 地址限制访问权限的访问权限级别,请执行以下操作:

  1. 在 Google Cloud 控制台中打开 Access Context Manager 页面
    • 如果系统提示,请选择文件夹 codelab-folder
  2. Access Context Manager 页面的顶部,点击创建访问权限级别
  3. 新建访问权限级别窗格中,为新访问权限级别指定标题。在此 Codelab 中,我们将其命名为 project_2_al
  4. 条件部分中,点击 IP 子网前面的 +
  5. IP 子网框中,选择公共 IP

在入站流量规则中添加访问权限级别

在入站规则中,访问权限级别在 sources 字段下引用,该字段是必需字段,如入站规则参考中所述。如需允许面向资源的入站流量,VPC Service Controls 会将 sourcesidentityType 属性评估为 AND 条件。入站规则使用手动触发数据传输的主账号的身份,而不是数据传输配置中指定的服务账号。

使用访问权限级别配置的入站规则。

使用限制 IP 地址访问权限的配置重新运行转移

如需评估应用的配置的有效性,请使用以下场景再次触发转移:

  • 使用入站规则引用的访问权限级别中允许的 IP 地址范围内的 IP 地址。
  • 使用配置允许的 IP 地址

从允许的 IP 地址进行访问应该会成功,而从不允许的 IP 地址进行访问应该会失败,并导致 VPC Service Controls 违规。

如需使用其他 IP 地址进行测试,一种简单的方法是允许在使用 Google Cloud 控制台时分配 IP 地址,然后在使用 Cloud Shell 时进行测试。

在 Cloud Shell 中,运行以下命令,替换 RUN_TIME 和 RESOURCE_NAME,以手动触发传输

bq mk \
  --transfer_run \
  --run_time='RUN_TIME' \
  RESOURCE_NAME

例如,以下示例命令会立即针对项目 1234567890 中的转移 12345678-90ab-cdef-ghij-klmnopqrstuv 配置运行。

NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ");
bq mk \
  --transfer_run \
  --run_time=$NOW \
  projects/1234567890/locations/us/transferConfigs/12345678-90ab-cdef-ghij-klmnopqrstuv

观察到的输出显示了 VPC Service Controls 违规行为,这符合预期,因为该 IP 地址不受允许。

来自不允许的 IP 地址的 VPC SC 违规问题。

观察到的违规行为涉及 DataTransferService.StartManualTransferRuns 方法。

ingressViolations: [
0: {
servicePerimeter: "accessPolicies/987654321/servicePerimeters/perimeter-2"
targetResource: "projects/[PROJECT2_NUMBER]"
targetResourcePermissions: [0: "vpcsc.permissions.unavailable"]
}]
violationReason: "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
resource: {
labels: {
method: "google.cloud.bigquery.datatransfer.v1.DataTransferService.StartManualTransferRuns"
project_id: "project-2"
service: "bigquerydatatransfer.googleapis.com"
}
type: "audited_resource"
}
severity: "ERROR"

5. 在保护 Cloud Storage 服务的同时启动数据传输

由于我们要从 Cloud Storage 向 BigQuery 执行转移,因此我们将 Cloud Storage 添加到受 VPC Service Controls 保护的服务中,看看转移能否成功。

perimeter-2 配置中,将 Cloud Storage APIBigQuery Data Transfer API 添加为受限服务之一。

用于保护 Cloud Storage 的 VPC SC 配置。

保护 Cloud Storage API 后,请等待下次安排的数据传输,或按照以下步骤手动触发传输

  1. 转到 Google Cloud 控制台中的 BigQuery 页面。
  2. 点击数据传输
  3. 从列表中选择您的转移作业:在此 Codelab 中,我们使用的是 Codelab Transfer 转移
  4. 点击立即运行转移作业
  5. 点击确定

系统会发起另一次转移。您可能需要刷新页面才能看到。这次传输将因违反 VPC Service Controls 政策而失败。

复制 BigQuery 数据集时违反了 VPC SC 规定。

调查 Cloud Storage VPC Service Controls 违规问题

使用转移摘要中显示的 vpcServiceControlsUniqueIdentifier 过滤审核日志。

检测到的违规行为是 RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER 出站流量违规行为,具体详情如下:

  • 主账号是指在数据传输服务中配置的服务账号(无论是手动触发还是运行安排的数据传输,被拒绝的主账号都将保持不变)。
  • 受影响的服务是 Cloud Storage
  • 请求的来源是配置了数据传输服务的项目:project-2
  • 目标项目是 Cloud Storage 对象所在的项目:project-1
principalEmail: "codelab-sa@project-2.iam.gserviceaccount.com"
egressViolations: [
0: {
servicePerimeter: "accessPolicies/987654321/servicePerimeters/perimeter-2"
source: "projects/[PROJECT2_NUMBER]"
sourceType: "Resource"
targetResource: "projects/[PROJECT1_NUMBER]"
targetResourcePermissions: [0: "storage.objects.get"]
}]
labels: {
method: "google.storage.objects.get"
project_id: "project-2"
service: "storage.googleapis.com"
}

解决 Cloud Storage 出站流量违规问题

如需修正出站流量违规问题,我们必须使用出站规则,允许从被拒绝的服务账号向包含 Cloud Storage 对象的项目发送流量。

用于允许 Codelab 服务账号的出站规则。

修改服务边界 perimeter-2 后,请重复此流程以再次触发转移。转移不会显示错误。

配置出站规则后运行数据传输的详细信息。

6. 将 BigQuery 数据集从 project-2 复制到 project-1

确认我们可以将数据从 project-1 中的 Cloud Storage 存储分区转移到 project-2 中的 BigQuery 数据集后,我们来从 project-2project-1 复制 BigQuery 数据集;同时,BigQuery API 由 VPC 服务控制保护。

如需创建和复制数据集,我们将使用 bq mk 命令,该命令使用 bq 工具。

project-1 中创建目标数据集

在复制数据集之前,必须先创建目标数据集。如需创建目标数据集,我们可以运行以下命令,该命令会在项目 project-1 中创建名为 copied_dataset 的数据集,并将 us 作为位置。

bq mk \
  --dataset \
  --location=us \
  project-1:copied_dataset

使用 VPC Service Controls 保护 project-2 中的 BigQuery 服务

修改边界 perimeter-2 的配置,并将 BigQuery API 添加为受保护服务,以及 BigQuery Data TransferCloud Storage 服务。

配置为保护 Cloud Storage API 的 VPC SC。

启动数据集复制

如需复制数据集,请运行以下 bq mk 命令,该命令会将项目 project-2 中的数据集 codelab_bqtransfer_dataset 复制到 project-1 中的数据集 copied_dataset,并覆盖数据集内容(如果有)。

bq mk \
  --transfer_config \
  --project_id=project-1 \
  --target_dataset=copied_dataset \
  --data_source=cross_region_copy \
  --display_name='Dataset from project-2 to project-1' \
  --params='{
     "source_dataset_id":"codelab_bqtransfer_dataset",
     "source_project_id":"project-2",
     "overwrite_destination_table":"true"
     }'

该命令将成功运行;同时,转移配置会成功创建,以启动复制数据集的操作。复制数据集本身将会失败,并会出现 VPC Service Controls 违规问题。

如需查找相应的 VPC Service Controls 违规详情,请使用以下日志查询检查 project-2(来源数据集项目)中的日志。日志查询会按 BigQuery 服务和要复制的数据集的资源名称 (codelab_bqtransfer_dataset) 过滤日志。

resource.labels.service="bigquery.googleapis.com"
protoPayload.metadata.resourceNames:"datasets/codelab_bqtransfer_dataset"

观察到的 VPC Service Controls 违规行为是从 project-2project-1 的出站违规行为。

egressViolations: [
  0: {
   servicePerimeter: "accessPolicies/987654321/servicePerimeters/perimeter-2"
   source: "projects/[PROJECT-2-NUMBER]"
   sourceType: "Resource"
   targetResource: "projects/[PROJECT-1-NUMBER]"
   targetResourcePermissions: [
     0: "bigquery.transfers.update"
     1: "bigquery.transfers.get"
     2: "bigquery.jobs.create"
     ]
   }
]
method: "bigquery.tables.getData"
service: "bigquery.googleapis.com"

修正所有 BigQuery 违规问题,然后重新开始数据集复制

如需解决出站流量违规问题,我们需要创建一个允许被拒绝的正文的出站规则。被拒绝的主账号是运行 mk 命令的主账号。

出站规则,用于允许访问所有 BigQuery 方法。

出站规则生效后,在边界网关 perimeter-2 上运行相同的命令即可复制数据集。这次,它应该会成功复制数据集,且不会违反 VPC Service Controls 限制。

7. 清理

虽然在 VPC Service Controls 处于闲置状态时,使用该服务无需另行付费,但最好还是清理本实验中使用的设置。您还可以删除虚拟机实例和/或 Cloud 项目,以避免产生费用。删除 Cloud 项目后,系统会停止对该项目中使用的所有资源计费。

  • 如需删除 Cloud Storage 存储分区,请完成以下步骤:
    • 在 Google Cloud 控制台中,前往 Cloud Storage 存储分区页面
    • 选中要删除的存储分区对应的复选框,然后点击删除
    • 在出现的叠加窗口中,确认要删除存储分区及其内容。删除 Cloud Storage 存储分区。
  • 如需删除 BigQuery 数据集,请完成以下步骤:
    • 在 Google Cloud 控制台中,前往 BigQuery 页面
    • 浏览器窗格中,展开您的项目,然后选择数据集。
    • 展开三点状菜单,然后点击删除
    • 删除数据集对话框中,在字段中输入 delete,然后点击删除删除 BigQuery 数据集。
  • 如需删除服务边界,请完成以下步骤:
    • 在 Google Cloud 控制台中,选择安全,然后在访问权限政策的范围级别(在本例中为文件夹级别)选择 VPC Service Controls
    • 在 VPC Service Controls 页面上,在与要删除的边界相对应的表行中,选择 Delete Icon
  • 如需删除访问权限级别,请完成以下步骤:
    • 在 Google Cloud 控制台中,在“文件夹”级别打开 Access Context Manager 页面。
    • 在网格中,找到您要删除的访问权限级别对应的行,选择三点状菜单,然后选择删除
  • 如需关闭项目,请完成以下步骤:
    • 在 Google Cloud 控制台中,前往要删除的项目的“IAM 和管理”设置页面。
    • 在“IAM 和管理设置”页面上,选择关停
    • 输入项目 ID,然后选择仍要关停

8. 恭喜!

在本 Codelab 中,您创建了 VPC Service Controls 边界,强制执行了该边界,并排查了该边界的问题。

了解详情

您还可以探索以下场景:

  • 在另一个边界中添加 project-1,该边界还会保护 BigQuery、BigQuery Data Transfer Service 和 Cloud Storage。
  • 从其他受支持的数据源执行 BigQuery 数据传输。
  • 根据其他属性(例如位置或设备政策)限制用户访问权限。

许可

此作品已获得 Creative Commons Attribution 2.0 通用许可授权。