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 设置。
资源设置
- 按照“Resources-setup”中的说明设置资源VPC Service Controls 基本教程 I
- 验证您是否拥有管理 Cloud Storage 所需的权限。
- 在本教程中,我们将开始使用 CLI 而不是 Cloud 控制台。在其中一个开发环境中,设置 gcloud CLI:
- Cloud Shell:如需使用已设置 gcloud CLI 的在线终端,请激活 Cloud Shell。
点击 Cloud 控制台右上角的图标,激活 Cloud Shell。该会话可能需要几秒钟来完成初始化。如需了解详情,请参阅 Cloud Shell 指南。
费用
您需要在 Cloud 控制台中启用结算功能,才能使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有的话)。若要关闭资源以避免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除项目。Google Cloud 新用户有资格加入 300 美元的免费试用计划。
唯一会产生费用的资源是虚拟机实例和 Cloud Storage 对象。您可以使用价格计算器了解虚拟机实例的估算费用。您可以在此价格表中找到 Cloud Storage 的估算费用。
3. 创建存储分区和对象
如前所述,我们将重复使用上一个教程中创建的资源。继续创建 Cloud Storage 存储分区。在本教程中,我们将开始使用 gcloud CLI 而不是控制台。
- 在 Google 控制台中,选择“ProjectX”。在此项目中,我们将创建 Storage 存储分区和对象。
- 通过运行以下命令,确保将 Cloud Shell 设置为使用 ProjectX:
gcloud config set project PROJECT_ID
- 在开发环境中,运行以下命令:
gcloud storage buckets create gs://BUCKET_NAME --location=us-central1
- 创建一个存储对象,以便我们可以从位于 ProjectZ 的虚拟机实例中读取它。我们会创建一个 .txt 文件。
nano hello.txt
根据需要在文本文件中添加任何内容。
- 将对象上传到存储分区。
gcloud storage cp /home/${USER}/hello.txt gs://BUCKET_NAME
- 验证对象是否已上传到存储分区(通过列出该对象)。
gcloud storage ls gs://BUCKET_NAME
您必须看到控制台中列出的 hello.txt 文件。
4. 保护 Cloud Storage API
在上一个 Codelab 中,我们创建了一个边界并保护了 Compute Engine API。在此 Codelab 中,我们将修改试运行模式边界并添加 Cloud Storage。这将帮助我们在审核日志中显示 VPC Service Controls 违规行为,从而确定边界保护的影响,但在我们实施该边界之前,资源仍然可供访问。
- 在 Google 控制台中,选择您的组织; 访问 VPC Service Controls。确保您在组织范围内。
- 打开 Cloud Shell 并更新试运行边界“SuperProtection”在上一个实验中创建的:
gcloud access-context-manager perimeters dry-run update SuperProtection --policy=POLICY --add-restricted-services=storage.googleapis.com
- 通过描述边界来验证 Cloud Storage API 是否已更新
gcloud access-context-manager perimeters dry-run describe SuperProtection --policy=POLICY
在输出中,您会看到 Cloud Storage API 列在受限服务下方
与 Compute Engine API 搭配使用,但带有“-vpcAccessibleServices: {}"
”标签:
5. 验证 Cloud Storage API 是否受到保护
在试运行模式下,验证“SuperProtection”边界通过列出项目(在 ProjectZ 中创建的虚拟机实例)到托管 Storage 存储分区的 ProjectX,向我们显示拒绝事件
- 在 Cloud 控制台中,前往项目选择器并选择“ProjectZ”,然后前往“Compute Engine”>“虚拟机实例。
- 点击 SSH 按钮以连接到虚拟机实例并访问其命令行。
- 列出我们之前上传的 hello.txt 文件。
gcloud storage ls gs://BUCKET_NAME
由于 Cloud Storage API 在试运行模式下受到保护,因此您应该能够列出资源,但 ProjectZ 审核日志中必须显示错误消息。
- 前往 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"
- 由于我们已验证对 Cloud Storage 的 API 调用会产生 VPC Service Controls 违规行为,因此我们将使用新配置强制执行边界。打开 Cloud Shell 并强制执行试运行边界:
gcloud access-context-manager perimeters dry-run enforce SuperProtection --policy=POLICY --async
- 使用 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。
- 转到项目选择器,然后选择“ProjectZ”。
- 在日志浏览器中使用以下查询,在审核日志中查找 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"
- 点击 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 与服务进行通信,并跨服务边界共享数据。
- 激活 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
gcloud access-context-manager perimeters update SuperProtection --set-egress-policies=egresstorage.yaml --policy=POLICY
现在,我们可以再次尝试从虚拟机实例访问存储分区。
- 在 Cloud 控制台中,前往项目选择器并选择“ProjectZ”,然后前往“Compute Engine”>“虚拟机实例。
- 点击 SSH 按钮以连接到虚拟机实例并访问其命令行。
- 进入虚拟机 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).
- 我们需要为 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
- 再次尝试列出虚拟机实例的 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 项目后,系统即会停止对该项目中使用的所有资源计费。
- 如需删除虚拟机实例,请选中虚拟机实例名称左侧的复选框,然后点击删除。
- 如需删除边界,请完成以下步骤:
- 在 Google Cloud 控制台中,点击安全,然后点击“组织”范围内的 VPC Service Controls。
- 在“VPC Service Controls”页面中与要删除的边界对应的表行中,点击“删除图标”
- 如需删除访问权限级别,请完成以下步骤:
- 在 Google Cloud 控制台中,打开“文件夹”范围内的 Access Context Manager 页面。
- 在网格中,在您要删除的访问权限级别所对应行中,点击“删除图标”,然后点击删除。
- 如需删除 Storage 对象和存储分区,请完成以下步骤:
- 在 Google Cloud 控制台中,打开 Cloud Storage 存储分区页面。
- 选中所创建存储分区旁边的复选框。
- 点击删除。
- 在打开的窗口中,确认您要删除存储分区。
- 点击删除。
- 如需关停项目,请完成以下步骤:
- 在 Google Cloud 控制台中,前往 IAM 和要删除的项目的“管理设置”页面。
- 在 IAM &管理员设置页面,点击关停。
- 输入项目 ID,然后点击仍然关停。
8. 恭喜!
在此 Codelab 中,您更新了 VPC Service Controls 试运行边界,实施该边界并对其进行问题排查。
了解详情
- 请参阅 VPC Service Controls 文档。
- 请参阅 Access Context Manager 文档。
- 请参阅 VPC-SC 问题排查工具文档。
- 请参阅“入站和出站规则”文档。
- 请参阅试运行文档
- 请参阅 Cloud Storage 文档。
许可
此作品已获得 Creative Commons Attribution 2.0 通用许可授权。