了解如何使用 VPC Service Controls 设置服务边界。本教程使用有效使用 VPC Service Controls 边界所需的网络设置,例如防火墙、Private Service Connect 和 DNS 配置。然后演示如何允许或拒绝服务,以及如何为特定服务的许可名单创建精细的例外情况。
目标
- 使用其他网络控制来配置 VPC Service Controls 边界以缓解渗漏路径。
- 允许或拒绝从边界内或边界外的请求访问边界内的服务。
- 允许或拒绝边界内的请求访问边界外的服务。
- 同时使用“限制资源服务使用”组织政策和 VPC Service Controls。
费用
本教程使用 Google Cloud 的以下收费组件:
如需根据您的预计使用量来估算费用,请使用价格计算器。
完成本教程后,您可以删除所创建的资源以避免继续计费。如需了解详情,请参阅清理。
准备工作
本教程需要您的组织下的项目。如果您还没有 Google Cloud 组织,请参阅创建和管理组织。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
Enable the Compute Engine, Access Context Manager, and Cloud DNS APIs.
-
In the Google Cloud console, activate Cloud Shell.
Make sure that you have the following role or roles on the organization: Access Context Manager Admin, Organization Policy Administrator
Check for the roles
-
In the Google Cloud console, go to the IAM page.
Go to IAM - Select the organization.
-
In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.
- For all rows that specify or include you, check the Role colunn to see whether the list of roles includes the required roles.
Grant the roles
-
In the Google Cloud console, go to the IAM page.
前往 IAM - 选择组织。
- 点击 授予访问权限。
-
在新的主账号字段中,输入您的用户标识符。 这通常是 Google 账号的电子邮件地址。
- 在选择角色列表中,选择一个角色。
- 如需授予其他角色,请点击 添加其他角色,然后添加其他各个角色。
- 点击保存。
-
Make sure that you have the following role or roles on the project: Compute Admin, DNS Administrator, IAP-Secured Tunnel User, Service Account User, Service Directory Editor
Check for the roles
-
In the Google Cloud console, go to the IAM page.
Go to IAM - Select the project.
-
In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.
- For all rows that specify or include you, check the Role colunn to see whether the list of roles includes the required roles.
Grant the roles
-
In the Google Cloud console, go to the IAM page.
前往 IAM - 选择项目。
- 点击 授予访问权限。
-
在新的主账号字段中,输入您的用户标识符。 这通常是 Google 账号的电子邮件地址。
- 在选择角色列表中,选择一个角色。
- 如需授予其他角色,请点击 添加其他角色,然后添加其他各个角色。
- 点击保存。
-
设置 VPC Service Controls 边界
如需为 VPC 网络实现 VPC Service Controls 边界,您必须实现网络控制以拒绝流向外部服务的流量。以下各部分详细介绍了您必须在边界内的 VPC 网络中实现的网络配置以及示例边界配置。
准备 VPC 网络
在本部分中,您将为 VPC 网络设置与 Google API 和服务的专用连接,以减少到互联网的网络出站流量路径。
在 Cloud Shell 中,设置变量:
gcloud config set project PROJECT_ID gcloud config set compute/region REGION gcloud config set compute/zone ZONE
请替换以下内容:
- PROJECT_ID:您将在其中创建的项目的 ID 创建资源
- REGION:靠近您位置的区域,例如
us-central1
- ZONE:靠近您位置的可用区,例如
us-central1-a
创建启用了专用 Google 访问通道的 VPC 网络和子网:
gcloud compute networks create restricted-vpc --subnet-mode=custom gcloud compute networks subnets create restricted-subnet \ --range=10.0.0.0/24 \ --network=restricted-vpc \ --enable-private-ip-google-access
创建 Private Service Connect 端点和配置为使用 vpc-sc 软件包的转发规则:
gcloud compute addresses create restricted-psc-endpoint \ --global \ --purpose=PRIVATE_SERVICE_CONNECT \ --addresses=10.0.1.1 \ --network=restricted-vpc gcloud compute forwarding-rules create restrictedpsc \ --global \ --network=restricted-vpc \ --address=restricted-psc-endpoint \ --target-google-apis-bundle=vpc-sc
配置 Cloud DNS 服务器政策,以将对 Google Cloud API 的查询重定向到 Private Service Connect 端点:
gcloud dns managed-zones create restricted-dns-zone \ --description="Private DNS Zone to map Google API queries to the Private Service Connect endpoint for Google APIs" \ --dns-name="googleapis.com." \ --networks=restricted-vpc \ --visibility=private gcloud dns record-sets create googleapis.com \ --rrdatas=10.0.1.1 \ --type=A \ --ttl=300 \ --zone=restricted-dns-zone gcloud dns record-sets create *.googleapis.com \ --rrdatas="googleapis.com." \ --type=CNAME \ --ttl=300 \ --zone=restricted-dns-zone
以低优先级配置防火墙规则以拒绝所有出站流量:
gcloud compute firewall-rules create deny-all-egress \ --priority=65534 \ --direction=egress \ --network=restricted-vpc \ --action=DENY \ --rules=all \ --destination-ranges=0.0.0.0/0
配置优先级更高的防火墙规则,以允许流量到达您的 Private Service Connect 端点使用的 IP 地址:
gcloud compute firewall-rules create allow-psc-for-google-apis \ --priority=1000 \ --direction=egress \ --network=restricted-vpc \ --action=ALLOW \ --rules=tcp:443 \ --destination-ranges=10.0.1.1
这些防火墙规则会广泛拒绝出站流量,然后选择性地允许流向 Private Service Connect 端点的出站流量。此配置拒绝 出站流量 默认网域 通常可通过专用 Google 访问通道访问 该 隐式防火墙规则
创建 VPC Service Controls 边界
在本部分中,您将创建 VPC Service Controls 边界。
在 Cloud Shell 中,创建访问权限政策作为创建 VPC Service Controls 边界的前提条件:
gcloud access-context-manager policies create \ --organization=ORGANIZATION_ID --title "Access policy at organization node"
输出类似于以下内容:
"Create request issued Waiting for operation [operations/accessPolicies/123456789/create/123456789] to complete...done."
组织节点上只能有一个访问权限政策容器。如果已在组织中创建政策,则输出类似于以下内容:
"ALREADY_EXISTS: Policy already exists with parent ContainerKey{containerId=organizations/123456789012, numericId=123456789012}"
如果您看到此消息,请继续执行下一步。
创建 VPC Service Controls 边界以限制 Cloud Storage 和 Compute Engine 服务。
export POLICY_ID=$(gcloud access-context-manager policies list \ --organization=ORGANIZATION_ID \ --format="value(name)") gcloud access-context-manager perimeters create demo_perimeter \ --title="demo_perimeter" \ --resources=projects/$(gcloud projects describe PROJECT_ID --format="value(projectNumber)") \ --restricted-services="storage.googleapis.com,compute.googleapis.com" \ --enable-vpc-accessible-services \ --policy=$POLICY_ID \ --vpc-allowed-services="RESTRICTED-SERVICES"
验证边界外的流量是否允许服务
以下部分演示了 VPC Service Controls 边界如何允许或拒绝从边界外发出的请求,以及如何通过配置访问权限级别和入站流量政策来选择性地允许通往服务的入站流量。
如需模拟来自边界外的流量,您可以在 Cloud Shell 中运行命令。Cloud Shell 是您自己的项目和边界外的资源。即使请求具有足够的 Identity and Access Management 权限,边界也会允许或拒绝请求。
本教程使用 Compute Engine API、Cloud Storage API 和 Cloud Resource Manager API,但同样的概念也适用于其他服务。
验证边界是否拒绝流向受限服务的外部流量
在本部分中,您将验证边界是否拒绝流向受限服务的外部流量。
上图演示了如何拒绝已获授权的客户端访问边界内配置为受限的服务,但允许该客户端访问未配置为受限的服务。
在以下步骤中,您将验证此概念,方法是使用 Cloud Shell 尝试在 VPC 网络内创建虚拟机,但由于 VPC Service Controls 边界的配置而失败。
在 Cloud Shell 中,运行以下命令以在 VPC 网络内创建虚拟机。
gcloud compute instances create demo-vm \ --machine-type=e2-micro \ --subnet=restricted-subnet \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --no-address
输出类似于以下内容:
"ERROR: (gcloud.compute.instances.create) Could not fetch resource: - Request is prohibited by organization's policy."
由于 Cloud Shell 位于边界外,并且 Compute Engine 配置了
--restricted-services
标志,因此请求失败。在 Cloud Shell 中,运行以下命令以访问
--restricted-services
标志中未配置的 Resource Manager 服务。gcloud projects describe PROJECT_ID
成功的响应会返回项目的详细信息。此响应表明您的边界允许外部流量进入 Cloud Resource Manager API。
您已证明,边界会拒绝流向
--restricted-services
中配置的服务的外部流量,并允许流向--restricted-services
中未明确配置的服务的外部流量。
以下部分介绍了用于访问边界内受限服务的例外情况模式。
验证访问权限级别是否允许边界的例外情况
在本部分中,您将验证访问权限级别是否允许边界的例外情况。如果您希望为外部流量创建例外以访问边界内所有受限服务,并且不需要为每项服务或其他属性创建精细例外,则访问权限级别会非常有用。
上图演示了访问权限级别如何允许已获授权的客户端访问边界内所有受限服务。
在以下步骤中,您将通过创建访问权限级别和 然后向 Compute Engine 服务发出成功的请求这个 即使您将 Compute Engine 配置为受限也是如此。
在 Cloud Shell 中,创建一个 YAML 文件来描述访问权限级别的配置,并将其应用于您的边界。本示例将为您当前用于运行教程的用户身份创建一个访问权限级别。
export USERNAME=$(gcloud config list account --format "value(core.account)") cat <<EOF > user_spec.yaml - members: - user:$USERNAME EOF
gcloud access-context-manager levels create single_user_level \ --title="single-user access level" \ --basic-level-spec=user_spec.yaml \ --policy=$POLICY_ID gcloud access-context-manager perimeters update demo_perimeter \ --add-access-levels=single_user_level \ --policy=$POLICY_ID
在 Cloud Shell 中,再次运行以下命令以尝试创建虚拟机:
gcloud compute instances create demo-vm \ --machine-type=e2-micro \ --subnet=restricted-subnet \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --no-address
这一次,请求起作用。您的边界将阻止外部流量使用受限的服务,但您配置的访问权限级别允许例外情况。
验证入站流量政策是否允许边界的精细例外情况
在本部分中,您将验证入站流量政策是否允许边界的精细例外。与粗粒度访问权限级别相比,精细入站流量政策可以配置有关流量来源的更多属性,并允许访问单个服务或方法。
上图演示了入站流量政策如何允许已获授权的客户端仅访问边界内的指定服务,而不允许访问其他受限服务。
在以下步骤中,您将验证此概念,方法是将访问权限级别替换为入站流量政策,仅允许已获授权的客户端访问 Compute Engine 服务,但不允许访问其他受限服务。
在 Cloud Shell 标签页中,运行以下命令以移除访问权限级别。
gcloud access-context-manager perimeters update demo_perimeter \ --policy=$POLICY_ID \ --clear-access-levels
在 Cloud Shell 标签页中,创建允许您的用户身份仅进入 Compute Engine 服务的入站流量政策,并将该政策应用于您的边界。
cat <<EOF > ingress_spec.yaml - ingressFrom: identities: - user:$USERNAME sources: - accessLevel: '*' ingressTo: operations: - methodSelectors: - method: '*' serviceName: compute.googleapis.com resources: - '*' EOF
gcloud access-context-manager perimeters update demo_perimeter \ --set-ingress-policies=ingress_spec.yaml \ --policy=$POLICY_ID
在 Cloud Shell 标签页中,运行以下命令以在边界内创建 Cloud Storage 存储桶。
gcloud storage buckets create gs://PROJECT_ID-01
输出类似于以下内容:
"ERROR: (gcloud.storage.buckets.create) HTTPError 403: Request is prohibited by organization's policy."
Cloud Shell 是边界外的客户端,因此 VPC Service Controls 边界会阻止 Cloud Shell 与边界内的受限服务通信。
从 Cloud Shell 标签页中,运行以下命令以向边界内的 Compute Engine 服务发出请求。
gcloud compute instances describe demo-vm --zone=ZONE
成功的响应会返回
demo-vm
的详细信息。此响应表明您的边界允许满足入站流量政策条件的外部流量进入 Compute Engine 服务。
验证边界内流量允许的服务
以下部分演示了 VPC Service Controls 边界如何允许或拒绝来自边界内部的服务请求,以及如何通过出站流量政策有选择地允许出站流量通往外部服务。
为了演示边界内外流量之间的差异,以下部分同时使用了边界外的 Cloud Shell 和您在边界内创建的 Compute Engine 实例。您从边界内 Compute Engine 实例上的 SSH 会话运行的命令使用附加服务账号的身份,而从边界外的 Cloud Shell 运行的命令使用您自己的身份。在遵循本教程的推荐设置时,边界允许或拒绝请求,即使请求具有足够的 IAM 权限也可以成功。
本教程使用 Compute Engine API、Cloud Storage API 和 Cloud Resource Manager API,但同样的概念也适用于其他服务。
验证边界是否允许内部流量传输到边界内的受限服务
在本部分中,您将验证边界是否允许来自边界内网络端点的流量(如果在 VPC 可访问服务中配置了该服务)。
上图演示了边界如何允许来自边界内的网络端点的流量到达配置为 VPC 可访问服务的受限服务。您未配置为 VPC 可访问服务的服务无法从边界内的网络端点访问。
在以下步骤中,您将通过与边界内的 Compute Engine 实例建立 SSH 连接,然后向服务发出请求来验证此概念。
在 Cloud Shell 中,创建一个防火墙规则,通过允许来自 IAP for TCP 转发服务使用的 35.235.240.0/20 IP 地址范围的入站流量,允许 SSH 流量进入您的 VPC 网络:
gcloud compute firewall-rules create demo-allow-ssh \ --direction=INGRESS \ --priority=1000 \ --network=restricted-vpc \ --action=ALLOW \ --rules=tcp:22 \ --source-ranges=35.235.240.0/20
启动与此实例的 SSH 会话:
gcloud compute ssh demo-vm --zone=ZONE
通过确认命令行提示符已更改为显示实例的主机名,验证您是否已成功连接到
demo-vm
实例:username@demo-vm:~$
如果上一个命令失败,您可能会看到类似于以下内容的错误消息。
"[/usr/bin/ssh] exited with return code [255]"
在这种情况下,Compute Engine 实例可能尚未完成启动。请稍等片刻,然后重试。
在边界内的 SSH 会话中,使用在 VPC 可访问服务许可名单中配置的 Google Cloud 服务来验证边界在内部允许的服务。例如,尝试使用 Compute Engine 服务的任何命令。
gcloud compute instances describe demo-vm --zone=ZONE
成功的响应会返回
demo-vm
的详细信息。此响应表明您的边界允许内部流量进入 Compute Engine API。从边界内的 SSH 会话中,验证您的 VM 不允许未包含在 VPC 可访问服务许可名单中的服务。例如,以下命令使用未在 VPC 可访问服务许可名单中配置的 Resource Manager 服务。
gcloud projects describe PROJECT_ID
输出类似于以下内容:
"ERROR: (gcloud.projects.list) PERMISSION_DENIED: Request is prohibited by organization's policy."
您的 Compute Engine 实例和其他网络端点只能请求在 VPC 可访问服务许可名单中配置的服务。但是,来自边界外的无服务器资源或服务流量可能会请求该服务。如果您想阻止在您的项目中使用服务,请参阅受限服务资源使用政策。
验证边界是否拒绝进入边界外的受限服务的内部流量
在本部分中,您将验证边界是否阻止来自 外的 Google Cloud 服务 边界。
上图演示了内部流量为何无法与边界外的受限服务通信。
在以下步骤中,您将通过尝试将内部流量发送到边界内的受限服务和边界外的受限服务来验证此概念。
从边界内的 SSH 会话中,运行以下命令以在边界内创建存储桶。此命令之所以有效,是因为在
restricted-services
和accessible-services
中同时配置了 Cloud Storage 服务。gcloud storage buckets create gs://PROJECT_ID-02
成功的响应会创建存储桶。此响应表明您的边界允许内部流量进入 Cloud Storage 服务。
从边界内的 SSH 会话中,运行以下命令以从边界外的存储桶读取数据。此公共存储桶允许以只读权限访问
allUsers
,但边界会拒绝流量从边界内流向边界外的受限服务。gcloud storage cat gs://solutions-public-assets/vpcsc-tutorial/helloworld.txt
输出类似于以下内容:
"ERROR: (gcloud.storage.objects.describe) HTTPError 403: Request is prohibited by organization's policy."
此响应表明您可以在边界内使用受限服务,但边界内的资源无法与边界外的受限服务通信。
验证出站流量政策是否允许边界例外情况
在本部分中,您将验证出站流量政策是否允许边界的例外。
上图演示了当您使用出站流量政策授予较小范围例外时,内部流量如何与特定的外部资源通信。
在以下步骤中,您将通过创建出站流量政策,然后访问该出站流量政策允许的边界外的 Cloud Storage 公共存储桶来验证此概念。
点击 Cloud Shell 中的
打开新标签页,以打开新的 Cloud Shell 会话。在后续步骤中,您将在边界内具有 SSH 会话的第一个标签页,与边界外 Cloud Shell 中的第二个标签页之间切换,其中命令行提示符以username@cloudshell
开头。在 Cloud Shell 标签页中,创建出站流量政策,以允许
demo-vm
(使用google.storage.objects.get
方法)的附加服务账号身份的出站流量通往外部项目中的公共存储桶。使用出站流量政策更新边界。export POLICY_ID=$(gcloud access-context-manager policies list \ --organization=ORGANIZATION_ID \ --format="value(name)") export SERVICE_ACCOUNT_EMAIL=$(gcloud compute instances describe demo-vm \ --zone=ZONE) \ --format="value(serviceAccounts.email)"
cat <<EOF > egress_spec.yaml - egressFrom: identities: - serviceAccount:$SERVICE_ACCOUNT_EMAIL egressTo: operations: - methodSelectors: - method: 'google.storage.objects.get' serviceName: storage.googleapis.com resources: - projects/950403849117 EOF
gcloud access-context-manager perimeters update demo_perimeter \ --set-egress-policies=egress_spec.yaml \ --policy=$POLICY_ID
返回到与边界内虚拟机的 SSH 会话对应的标签页,其中命令行提示符以
username@demo-vm
开头。从边界内的 SSH 会话向 Cloud Storage 存储桶发出另一个请求,并验证其能否正常工作。
gcloud storage cat gs://solutions-public-assets/vpcsc-tutorial/helloworld.txt
输出类似于以下内容:
"Hello world! This is a sample file in Cloud Storage that is viewable to allUsers."
此响应表明,您的边界和出站流量政策允许从特定身份到特定 Cloud Storage 存储桶的内部流量。
通过边界内的 SSH 会话,您还可以测试出站政策例外未明确允许的其他方法。例如,以下命令需要您的边界拒绝的
google.storage.buckets.list
权限。gcloud storage ls gs://solutions-public-assets/vpcsc-tutorial/*
输出类似于以下内容:
"ERROR: (gcloud.storage.cp) Request is prohibited by organization's policy."
此响应表明您的边界拒绝来自外部存储桶中列出对象的内部流量,表明出站流量政策仅允许明确指定的方法。
如需查看在服务边界外共享数据的常见模式,请参阅使用入站和出站规则实现安全数据交换。
(可选)配置受限服务资源使用政策
您可能还需要满足内部要求或合规性要求 仅允许单独获批的 API 可在您的环境中使用在这种情况下,您还可以配置受限服务资源使用组织政策服务。通过在项目中应用该组织政策,您可以限制可在该项目中创建的服务。但该组织政策不会阻止此项目中的服务与其他项目中的服务进行通信。相比之下,VPC Service Controls 则允许您定义边界来防止与边界外的服务发生通信。
例如,如果您定义了一个组织政策以在项目中允许 Compute Engine 并拒绝 Cloud Storage,则该项目中的虚拟机无法创建 Cloud Storage 存储桶。但是,虚拟机可以向其他项目中的 Cloud Storage 存储桶发出请求,因此 Cloud Storage 服务仍然可能发生数据渗漏。以下步骤展示了如何实现和测试此场景:
- 切换至 Cloud Shell 标签页,其中命令行提示符以
username@cloudshell
开头。 在 Cloud Shell 标签页中,创建一个 YAML 文件来描述组织政策服务,以仅允许使用 Compute Engine 服务并拒绝所有其他服务,然后将其应用于您的项目。
cat <<EOF > allowed_services_policy.yaml constraint: constraints/gcp.restrictServiceUsage listPolicy: allowedValues: - compute.googleapis.com inheritFromParent: true EOF
gcloud resource-manager org-policies set-policy allowed_services_policy.yaml \ --project=PROJECT_ID
返回到与边界内虚拟机的 SSH 会话对应的标签页,其中命令行提示符以
username@demo-vm
开头。从边界内的 SSH 会话中,运行以下命令以查看您之前在此项目中创建的相同存储桶。
gcloud storage buckets describe gs://PROJECT_ID
输出类似于以下内容:
"ERROR: (gcloud.storage.buckets.create) HTTPError 403: Request is disallowed by organization's constraints/gcp.restrictServiceUsage constraint for 'projects/123456789' attempting to use service 'storage.googleapis.com'."
此响应表明组织政策服务拒绝您项目内的 Cloud Storage 服务,无论您的边界配置如何。
在边界内的 SSH 会话中,运行以下命令以查看出站流量政策允许的边界外存储桶。
gcloud storage cat gs://solutions-public-assets/vpcsc-tutorial/helloworld.txt
输出类似于以下内容:
"Hello world! This is a sample file in Cloud Storage that is viewable to allUsers."
如果响应成功,系统会返回外部存储桶中
helloworld.txt
的内容。此响应表明,您的边界和出站流量政策允许内部流量在特定有限的条件下到达外部存储桶,但组织政策服务拒绝您项目中的 Cloud Storage 服务,无论您的边界配置如何。无论受限服务资源使用组织政策服务如何允许边界外的服务,您的项目之外的服务可能仍会用于渗漏。拒绝与 Cloud Storage 或其他 Google 服务的通信 在边界外, 服务资源用量受限 仅凭组织政策服务是不够的,您必须配置 VPC Service Controls 边界。VPC Service Controls 可缓解数据渗漏路径,受限服务资源使用是一种合规性控制,用于防止在您的环境中创建未获批准的服务。结合使用这些控件可以阻止一系列渗透路径,并有选择地允许批准的服务在您的环境中内部使用。
清理
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
虽然 VPC Service Controls 边界不会产生任何额外费用,但应该进行清理,以避免组织中存在杂乱和未使用的资源。
- 在 Google Cloud 控制台顶部的项目选择器中,选择您在本教程中使用的组织。
在 Google Cloud 控制台中,转到 VPC Service Controls 页面。
在边界列表下,选择要删除的边界,然后点击删除。
在该对话框中,再次点击删除以确认删除。
后续步骤
- 了解启用 VPC Service Controls 的最佳实践。
- 了解 VPC Service Controls 支持哪些服务。
- 了解如何启用 VPC 可访问服务。
- 了解 Private Service Connect 的配置以访问 Google API。
如需查看更多参考架构、图表、教程和最佳实践,请浏览 Cloud Architecture Center。