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 数据传输 入站流量 违规问题。此 Codelab 的目标如下:

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

2. 资源设置和要求

准备工作

在此 Codelab 中,我们假设您已了解以下内容:

设置

我们的初始设置如下:

Codelab 初始设置示意图

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

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

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

保护 Data Transfer Service 的 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 Service Controls 保护 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. 所选服务账号必须具有 Cloud Storage 的必需权限,才能访问托管存储分区的项目;project-1 在此 Codelab 中。
    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 地址进行访问应会失败,并导致 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 出站流量违规行为,详细信息如下:

  • 正文是在 Data Transfer Service 中配置的服务账号(无论是手动触发还是运行预定数据传输,被拒绝的正文都将是同一个)。
  • 受影响的服务是 Cloud Storage
  • 请求的来源是配置了 Data Transfer Service 的项目: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 数据集后,我们来将 BigQuery 数据集project-2 复制到 project-1;同时,BigQuery API 受 VPC Service Controls 保护。

如需创建和复制数据集,我们将使用 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 数据传输Cloud Storage 服务。

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

启动数据集复制

如需复制数据集,请运行以下 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 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 边界、强制执行了该边界并对其进行了问题排查。

了解详情

您还可以探索以下场景:

  • 在另一个也保护 BigQuery、BigQuery Data Transfer Service 和 Cloud Storage 的安全边界中添加 project-1
  • 从其他支持的来源执行 BigQuery 数据传输。
  • 根据位置或设备政策等其他属性限制用户访问权限。

许可

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