VPC Service Controls 基本教程 II - 排查出站流量违规问题

1. 简介

VPC Service Controls (VPC-SC) 是 Google Cloud 中的组织级安全控制措施,使企业客户能够降低数据渗漏风险。借助 VPC Service Controls,客户端可以限制对授权 IP、客户端上下文和设备参数的访问,同时从互联网和其他服务连接到多租户服务,从而实现对多租户服务的零信任式访问,从而减少有意和无意的损失。如 VPC Service Controls 基本教程 I 中所述,您可以使用 VPC Service Controls 创建边界,以保护您明确指定的服务的资源和数据。

本教程的目标是:

  • 了解 VPC Service Controls 的基础知识
  • 更新服务边界并使用试运行模式对其进行测试
  • 使用 VPC Service Controls 保护两项服务
  • 排查 Cloud Storage 中的对象时 VPC Service Controls 出站流量违规问题

2. 设置和要求

对于本教程,我们需要以下前提条件:

  • GCP 组织。
  • 组织下的文件夹。
  • 同一组织中的 2 个 GCP 项目放置在该文件夹下。
  • 组织级层所需的权限
  • 两个项目的结算账号。
  • VPC Service Controls 基本教程 I VPC Service Controls 和 Access Context Manager 设置。

dbec101f41102ca2.png

资源设置

  1. 按照“Resources-setup”中的说明设置资源VPC Service Controls 基本教程 I
  2. 验证您是否拥有管理 Cloud Storage 所需的权限
  3. 在本教程中,我们将开始使用 CLI 而不是 Cloud 控制台。在其中一个开发环境中,设置 gcloud CLI:
  • Cloud Shell:如需使用已设置 gcloud CLI 的在线终端,请激活 Cloud Shell。

点击 Cloud 控制台右上角的图标,激活 Cloud Shell。该会话可能需要几秒钟来完成初始化。如需了解详情,请参阅 Cloud Shell 指南

a0ceb29950db4eac.png

  • 本地 shell:如需使用本地开发环境,请安装初始化 gcloud CLI。

费用

您需要在 Cloud 控制台中启用结算功能,才能使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有的话)。若要关闭资源以避免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除项目。Google Cloud 新用户有资格加入 300 美元的免费试用计划

唯一会产生费用的资源是虚拟机实例和 Cloud Storage 对象。您可以使用价格计算器了解虚拟机实例的估算费用。您可以在此价格表中找到 Cloud Storage 的估算费用。

3. 创建存储分区和对象

如前所述,我们将重复使用上一个教程中创建的资源。继续创建 Cloud Storage 存储分区。在本教程中,我们将开始使用 gcloud CLI 而不是控制台。

  1. 在 Google 控制台中,选择“ProjectX”。在此项目中,我们将创建 Storage 存储分区和对象。
  2. 通过运行以下命令,确保将 Cloud Shell 设置为使用 ProjectX:
gcloud config set project PROJECT_ID
  1. 在开发环境中,运行以下命令:
gcloud storage buckets create gs://BUCKET_NAME --location=us-central1
  1. 创建一个存储对象,以便我们可以从位于 ProjectZ 的虚拟机实例中读取它。我们会创建一个 .txt 文件。
nano hello.txt 

根据需要在文本文件中添加任何内容。

  1. 将对象上传到存储分区。
gcloud storage cp /home/${USER}/hello.txt gs://BUCKET_NAME
  1. 验证对象是否已上传到存储分区(通过列出该对象)。
gcloud storage ls gs://BUCKET_NAME

您必须看到控制台中列出的 hello.txt 文件。

4. 保护 Cloud Storage API

在上一个 Codelab 中,我们创建了一个边界并保护了 Compute Engine API。在此 Codelab 中,我们将修改试运行模式边界并添加 Cloud Storage。这将帮助我们在审核日志中显示 VPC Service Controls 违规行为,从而确定边界保护的影响,但在我们实施该边界之前,资源仍然可供访问。

  1. 在 Google 控制台中,选择您的组织; 访问 VPC Service Controls。确保您在组织范围内。
  2. 打开 Cloud Shell 并更新试运行边界“SuperProtection”在上一个实验中创建的:
gcloud access-context-manager perimeters dry-run update SuperProtection --policy=POLICY --add-restricted-services=storage.googleapis.com
  1. 通过描述边界来验证 Cloud Storage API 是否已更新
gcloud access-context-manager perimeters dry-run describe SuperProtection --policy=POLICY 

在输出中,您会看到 Cloud Storage API 列在受限服务下方

与 Compute Engine API 搭配使用,但带有“-vpcAccessibleServices: {}"”标签:

2025ddc01a2e9a81

5. 验证 Cloud Storage API 是否受到保护

在试运行模式下,验证“SuperProtection”边界通过列出项目(在 ProjectZ 中创建的虚拟机实例)到托管 Storage 存储分区的 ProjectX,向我们显示拒绝事件

  1. 在 Cloud 控制台中,前往项目选择器并选择“ProjectZ”,然后前往“Compute Engine”>“虚拟机实例
  2. 点击 SSH 按钮以连接到虚拟机实例并访问其命令行。

5ca02149b78c11f9

  1. 列出我们之前上传的 hello.txt 文件。
gcloud storage ls gs://BUCKET_NAME

由于 Cloud Storage API 在试运行模式下受到保护,因此您应该能够列出资源,但 ProjectZ 审核日志中必须显示错误消息。

  1. 前往 ProjectZ 中的 Logs Explorer API,查找 VPC Service Controls 上一条错误消息。您可以使用此过滤条件来获取我们要查找的日志:
protoPayload.status.details.violations.type="VPC_SERVICE_CONTROLS"
"(Dry Run Mode) Request is prohibited by organization's policy. vpcServiceControlsUniqueIdentifier:UNIQUE_ID"

此过滤条件将显示最近一次在试运行模式下属于 Cloud Storage 的违规问题。以下是日志的示例。当我们尝试列出位于 ProjectX 的存储分区中的内容时,可以验证违规行为是否属于出站流量。

egressViolations: [
0: {
servicePerimeter: "accessPolicies/POLICY/servicePerimeters/SuperProtection"
source: "projects/PROJECTX_ID"
sourceType: "Network"
targetResource: "projects/PROJECTZ_ID"
}
]
resourceNames: [
0: "projects//buckets/BUCKET_NAME"
]
securityPolicyInfo: {
organizationId: "ORGANIZATION_ID"
servicePerimeterName: "accessPolicies/POLICY/servicePerimeters/SuperProtection"
}
violationReason: "NETWORK_NOT_IN_SAME_SERVICE_PERIMETER"
vpcServiceControlsUniqueId: "UNIQUE_ID"
}
methodName: "google.storage.objects.list"
  1. 由于我们已验证对 Cloud Storage 的 API 调用会产生 VPC Service Controls 违规行为,因此我们将使用新配置强制执行边界。打开 Cloud Shell 并强制执行试运行边界:
gcloud access-context-manager perimeters dry-run enforce SuperProtection --policy=POLICY --async
  1. 使用 SSH 连接到虚拟机实例并再次列出存储分区,以验证试运行边界是否已正确实施。
gcloud storage ls gs://BUCKET_NAME

我们将在虚拟机 CLI 中看到 VPC Service Control 违规问题,而不是 Storage 对象列表:

ERROR: (gcloud.storage.ls) User [PROJECT_NUMBER-compute@developer.gserviceaccount.com] does not have permission to access b instance [BUCKET_NAME] (or it may not exist): Request is prohibited by organization's policy. vpcServiceControlsUniqueIdentifier:"UNIQUE_ID"

我们使用 VPC Service Controls 阻止从边界外的资源读取数据或将数据复制到边界外,从而成功阻止了数据渗漏。

6. 排查列表遭拒问题。

我们将对虚拟机实例 CLI 中收到的拒绝事件进行问题排查。我们来看一下审核日志,并查找 VPC Service Controls 唯一 ID。

  1. 转到项目选择器,然后选择“ProjectZ”。
  2. 在日志浏览器中使用以下查询,在审核日志中查找 VPC Service Controls 唯一 ID:
resource.type="audited_resource"
protoPayload.metadata."@type"="type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"

这将显示所有 VPC Service Controls 审核日志。我们会查找最后一个错误日志。由于 API 调用是从虚拟机实例进行的,因此主账号必须是 Compute Engine 服务账号“PROJECT_NUMBER-compute@developer.gserviceaccount.com"

由于我们已有 VPC Service Controls 唯一 ID,因此我们可以使用该 ID 直接使用此过滤条件来获取所需的日志:

protoPayload.metadata.vpcServiceControlsUniqueId="UNIQUE_ID"
  1. 点击 VPC Service Controls 标题,然后选择“排查拒绝问题”这将打开 VPC Service Controls 问题排查工具。

此 API 将在易用的界面中显示违规原因,以及违规是否属于入站流量或出站流量或其他有用信息。

在本练习中,我们将寻找以下内容:

authenticationInfo: {
principalEmail: "PROJECT_ID-compute@developer.gserviceaccount.com"
egressViolations: [
0: {
servicePerimeter: "accessPolicies/POLICY/servicePerimeters/SuperProtection"
source: "projects/PROJECTZ_ID"
sourceType: "Network"
targetResource: "projects/PROJECTX_ID"
}
violationReason: "NETWORK_NOT_IN_SAME_SERVICE_PERIMETER"

这些信息足以让我们知道,我们需要创建一条出站规则,让 Compute Engine 服务账号访问从 ProjectZ 到 ProjectX 的存储分区。此外,我们可以看到该网络不在同一边界内,因此我们需要允许 VPC 与服务进行通信,并跨服务边界共享数据。

  1. 激活 Cloud Shell,然后使用文本编辑器创建包含出站规则的 .yaml 文件。
nano egresstorage.yaml 
- egressTo:
    operations:
    - serviceName: storage.googleapis.com
      methodSelectors:
      - method: \"*\"
    resources:
    - projects/PROJECTX_ID
 egressFrom:
    identities:
    - serviceAccount:PROJECT_ID-compute@developer.gserviceaccount.com
  1. 更新用于保护 ProjectZ 的入站流量政策
gcloud access-context-manager perimeters update SuperProtection --set-egress-policies=egresstorage.yaml --policy=POLICY 

现在,我们可以再次尝试从虚拟机实例访问存储分区。

  1. 在 Cloud 控制台中,前往项目选择器并选择“ProjectZ”,然后前往“Compute Engine”>“虚拟机实例
  2. 点击 SSH 按钮以连接到虚拟机实例并访问其命令行。
  3. 进入虚拟机 CLI 后,尝试列出存储分区中的对象。
gcloud storage ls gs://BUCKET_NAME/

您会收到以下错误消息:

ERROR: (gcloud.storage.ls) User [PROJECT_ID-compute@developer.gserviceaccount.com] does not have permission to access b instance [BUCKET_NAME] (or it may not exist): PROJECT_ID-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission 'storage.objects.list' denied on resource (or it may not exist).
  1. 我们需要为 Compute Engine 服务账号授予对象读取器权限,才能列出 Storage 存储分区中的对象。
gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME --member=serviceAccount:PROJECT_ID-compute@developer.gserviceaccount.com --role=roles/storage.objectViewer
  1. 再次尝试列出虚拟机实例的 CLI 中的 hello.txt 文件。
gcloud storage ls gs://BUCKET_NAME/
.
.
gs://BUCKET_NAME/hello.txt

现在,我们能够在没有 VPC Service Controls 权限违规的情况下列出对象,但是,如果要下载该文件,该怎么办?我们来试试看。

gcloud storage cp gs://BUCKET_NAME/hello.txt /home/${USER}

我们将获得以下输出

Copying gs://BUCKET_NAME/hello.txt to file:///home/${USER}
 Completed files 1/1 | 54.0B/54.0B  

7. 清理

虽然不使用 VPC Service Controls 时无需单独付费,但最佳做法是清理本实验室中使用的设置。您还可以删除虚拟机实例和/或 Cloud 项目,以避免产生费用。删除 Cloud 项目后,系统即会停止对该项目中使用的所有资源计费。

  1. 如需删除虚拟机实例,请选中虚拟机实例名称左侧的复选框,然后点击删除

da0abf0894fe03cd.png

  1. 如需删除边界,请完成以下步骤:
  • 在 Google Cloud 控制台中,点击安全,然后点击“组织”范围内的 VPC Service Controls
  • 在“VPC Service Controls”页面中与要删除的边界对应的表行中,点击“删除图标”
  1. 如需删除访问权限级别,请完成以下步骤:
  • 在 Google Cloud 控制台中,打开“文件夹”范围内的 Access Context Manager 页面。
  • 在网格中,在您要删除的访问权限级别所对应行中,点击“删除图标”,然后点击删除
  1. 如需删除 Storage 对象和存储分区,请完成以下步骤:
  • 在 Google Cloud 控制台中,打开 Cloud Storage 存储分区页面
  • 选中所创建存储分区旁边的复选框。
  • 点击删除
  • 在打开的窗口中,确认您要删除存储分区。
  • 点击删除
  1. 如需关停项目,请完成以下步骤:

8. 恭喜!

在此 Codelab 中,您更新了 VPC Service Controls 试运行边界,实施该边界并对其进行问题排查。

了解详情

许可

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