使用 Identity-Aware Proxy (IAP) 保护无服务器应用

1. 概览

在本实验中,您将部署员工门户,让员工可以通过 Cymbal Eats 应用查看、更新和删除订单。您将使用 Identity Aware Proxy (IAP) 保护门户访问,而不使用虚拟专用网 (VPN)。对于本地和云端环境中的远程工作者来说,IAP 可简化零信任访问模型的实现过程,而且所需时间比 VPN 更少,并且只需使用一个用于管理应用访问权限的控制点即可。

94b06525c85408ad

什么是 Identity-Aware Proxy?

Identity-Aware Proxy (IAP) 是一项 Google Cloud 服务,用于拦截发送到您应用的请求、对使用 Google Identity Service 发出请求的用户进行身份验证,并且仅当请求来自有权访问应用的用户时,才允许其通过。此外,它还可以修改请求标头,以包含经过身份验证的用户的相关信息。

学习内容

  • 如何配置无服务器网络端点组 (NEG)
  • 如何配置负载平衡器
  • 如何启用 IAP 以限制访问
  • 如何使用 IAP 限制访问

2. 设置和要求

自定进度的环境设置

  1. 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时对其进行更新。
  • 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常您不在乎这是什么在大多数 Codelab 中,您都需要引用项目 ID(它通常标识为 PROJECT_ID)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且该 ID 在项目期间会一直保留。
  • 此外,还有第三个值,即某些 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档
  1. 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。如需关停资源,以免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除整个项目。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。

环境设置

  1. 创建与项目和资源相关的环境变量
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export REGION=us-east1
export ORDER_SERVICE_URL=order-service
export INVENTORY_SERVICE_URL=inventory-service
export MENU_SERVICE_URL=menu-service
  1. 启用 IAP 和 Cloud Resource Manager Service API
gcloud services enable \
    iap.googleapis.com \
    cloudresourcemanager.googleapis.com \
    cloudidentity.googleapis.com \
    compute.googleapis.com
  1. 克隆示例应用代码库并导航到该目录
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/employee-ui
  1. 使用设置脚本部署员工门户。请等待脚本运行完毕,然后再继续下一步
./setup.sh

输出示例

...
Done.
Service [employee-ui-service] revision [employee-ui-service-00001-quw] has been deployed and is serving 100 percent of traffic.
Service URL: https://employee-ui-service-gbtuuy5eda-uk.a.run.app
  1. 点击 Service 网址 链接

86416f68c0b8152a

3. 配置无服务器网络端点组 (NEG)

您将为员工界面 Cloud Run 服务创建一个无服务器网络端点组(无服务器 NEG)。借助无服务器 NEG,您可以将 Google Cloud 无服务器应用与外部 HTTP(S) 负载均衡搭配使用。

2abe669e53c27186

  1. 为员工界面服务创建网络端点组。
gcloud compute network-endpoint-groups create employee-ui-iap-neg \
    --project $PROJECT_ID \
    --region=$REGION \
    --network-endpoint-type=serverless  \
    --cloud-run-service=employee-ui-service

输出示例

Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/regions/us-east1/networkEndpointGroups/employee-ui-iap-neg].
Created network endpoint group [employee-ui-iap-neg].

创建后端服务并添加无服务器 NEG

后端服务定义 Cloud Load Balancing 分配流量的方式。后端服务配置包含一组值,例如用于连接到后端的协议、各种分发和会话设置、健康检查和超时。这些设置可让您对负载平衡器的行为进行精细控制。

  1. 创建后端服务
gcloud compute backend-services create employee-ui-iap-backend \
        --global 

输出示例

Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/backendServices/employee-ui-iap-backend].
NAME: employee-ui-iap-backend
BACKENDS:
PROTOCOL: HTTP
  1. 将无服务器 NEG 作为后端添加到后端服务
gcloud compute backend-services add-backend employee-ui-iap-backend \
    --global \
    --network-endpoint-group=employee-ui-iap-neg \
    --network-endpoint-group-region=$REGION

输出示例

Updated [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/backendServices/employee-ui-iap-backend].
  1. 创建网址映射以将传入请求路由到后端服务
gcloud compute url-maps create employee-ui-iap-url-map \
    --default-service employee-ui-iap-backend
Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/urlMaps/employee-ui-iap-url-map].
NAME: employee-ui-iap-url-map
DEFAULT_SERVICE: backendServices/employee-ui-iap-backend

4. 配置负载平衡器组件

下图显示了负载平衡器使用无服务器 NEG 后端将请求定向到无服务器 Cloud Run 服务。

335f4674737a6514

保留静态 IP 地址

  1. 预留静态 IPv4 地址并存储域名
gcloud compute addresses create employee-ui-iap-ip \
    --network-tier=PREMIUM \
    --ip-version=IPV4 \
    --global

输出示例

Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/addresses/employee-ui-iap-ip].
  1. 存储 nip.io 域名
export DOMAIN=$(gcloud compute addresses list --filter employee-ui-iap-ip --format='value(ADDRESS)').nip.io

创建 Google 管理的 SSL 证书资源

  1. 创建 Google 管理的 SSL 证书资源
gcloud compute ssl-certificates create employee-ui-iap-cert \
    --description=employee-ui-iap-cert \
    --domains=$DOMAIN \
    --global

输出示例

Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/sslCertificates/employee-ui-iap-cert].
NAME: employee-ui-iap-cert
TYPE: MANAGED
CREATION_TIMESTAMP: 2022-04-18T06:39:37.474-07:00
EXPIRE_TIME:
MANAGED_STATUS: PROVISIONING

34.102.234.98.nip.io: PROVISIONING

创建目标 HTTPS 代理

  1. 创建目标 HTTPS 代理以将请求路由到您的网址映射
gcloud compute target-https-proxies create employee-ui-iap-http-proxy \
    --ssl-certificates employee-ui-iap-cert \
    --url-map employee-ui-iap-url-map

输出示例

Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/targetHttpsProxies/employee-ui-iap-http-proxy].
NAME: employee-ui-iap-http-proxy
SSL_CERTIFICATES: employee-ui-iap-cert
URL_MAP: employee-ui-iap-url-map
CERTIFICATE_MAP:

配置转发规则

  1. 创建转发规则以将传入请求路由到代理
gcloud compute forwarding-rules create employee-ui-iap-forwarding-rule \
    --load-balancing-scheme=EXTERNAL \
    --network-tier=PREMIUM \
    --address=employee-ui-iap-ip \
    --global \
    --ports=443 \
    --target-https-proxy employee-ui-iap-http-proxy

输出示例

Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-18147-25762/global/forwardingRules/employee-ui-iap-forwarding-rule].

限制进入 Cloud Run 服务的入站流量

限制入站流量,使其仅接受内部请求和通过 HTTP(S) 负载均衡传入的请求。

26cb0b2a9162e7ab

  1. 更新服务以仅允许来自内部请求的入站流量以及通过 HTTP(S) 负载平衡器的请求
gcloud run services update employee-ui-service \
    --ingress internal-and-cloud-load-balancing \
    --region $REGION

输出示例

OK Deploying... Done.                            
  OK Creating Revision...
  OK Routing traffic...
Done.
Service [employee-ui-service] revision [employee-ui-service-00001-quw] has been deployed and is serving 100 percent of traffic.
Service URL: https://employee-ui-service-gbtuuy5eda-uk.a.run.app
  1. 点击 Service 网址 链接

8505fde7e0784bf1

现在,对 Cloud Run 服务网址的访问会显示为“已禁止”。

5. 在负载平衡器上启用 Cloud Identity-Aware Proxy (IAP)

借助 IAP,您可以为通过 HTTPS 访问的应用建立一个中央授权层。您可以使用应用级访问权限控制模型,而不是网络级防火墙。

d9740402a74370a8.png

品牌是指包含用户品牌信息的 OAuth 同意屏幕。品牌可能仅限内部或公众用户查看。内部品牌允许与项目属于同一 Google Workspace 组织的成员访问 OAuth 流程。公开品牌可让任何有权访问互联网的人都能访问 OAuth 流程。

  1. 创建品牌
export USER_EMAIL=$(gcloud config list account --format "value(core.account)")

gcloud alpha iap oauth-brands create \
    --application_title="Cymbal Eats" \
    --support_email=$USER_EMAIL

输出示例

Created [462858740426].
applicationTitle: Cymbal Eats
name: projects/462858740426/brands/462858740426
orgInternalOnly: true

创建 IAP OAuth 客户端

  1. 使用上一步中的品牌名称创建客户
gcloud alpha iap oauth-clients create \
    projects/$PROJECT_ID/brands/$PROJECT_NUMBER \
    --display_name=cymbal-eats-employee-ui

输出示例

Created [462858740426-tkpv8n03opijg7erd3s9ccued2pfllsd.apps.googleusercontent.com].
displayName: cymbal-eats-employee-ui
name: projects/462858740426/brands/462858740426/identityAwareProxyClients/462858740426-tkpv8n03opijg7erd3s9ccued2pfllsd.apps.googleusercontent.com
secret: [secret-removed]
  1. 存储客户端名称、ID 和密钥
export CLIENT_NAME=$(gcloud alpha iap oauth-clients list \
    projects/$PROJECT_NUMBER/brands/$PROJECT_NUMBER --format='value(name)' \
    --filter="displayName:cymbal-eats-employee-ui")

export CLIENT_ID=${CLIENT_NAME##*/}

export CLIENT_SECRET=$(gcloud alpha iap oauth-clients describe $CLIENT_NAME --format='value(secret)')
  1. 在 Cloud 控制台中,从项目下拉菜单中选择项目
  2. 前往 Cloud 控制台中的 OAuth 同意屏幕

bcb460f3ab5241f4.png

  1. 点击“用户类型”下的“设为外部”
  2. 选择“测试”作为“发布”状态

27fd7de6e7b7ef21.png

  1. 点击“确认”

6. 使用 IAP 限制访问

使用 IAP 限制对后端服务的访问,然后验证应用无法访问。

  1. 在后端服务上启用 IAP
gcloud iap web enable --resource-type=backend-services \
    --oauth2-client-id=$CLIENT_ID \
    --oauth2-client-secret=$CLIENT_SECRET \
    --service=employee-ui-iap-backend

验证 IAP 配置

  1. 验证 SSL 证书是否处于活跃状态
gcloud compute ssl-certificates list --format='value(MANAGED_STATUS)'
  1. 获取服务网址
echo https://$DOMAIN

输出示例

https://34.102.234.98.nip.io
  1. 点击服务网址以打开员工门户。

352b600209c3fb33

  1. 使用您的实验凭据登录。

f7e0318388aa0739.png

  1. 关闭浏览器

授予用户访问员工门户的权限

  1. 为上一步创建的用户的 'roles/iap.httpsResourceAccessor' 角色添加 IAM 政策绑定
gcloud iap web add-iam-policy-binding \
    --resource-type=backend-services \
    --service=employee-ui-iap-backend \
    --member=user:$USER_EMAIL \
    --role='roles/iap.httpsResourceAccessor'

输出示例

Updated IAM policy for backend service [projects/462858740426/iap_web/compute/services/employee-ui-iap-backend].

测试服务访问权限

确认已授予员工门户访问权限

  1. 获取服务网址
echo https://$DOMAIN

输出示例

https://34.102.234.98.nip.io
  1. 点击服务网址以打开员工门户。

86416f68c0b8152a

您现在应该能够访问员工门户。

(可选)部署所有依赖项,部署这些微服务可能需要大约 20 分钟。

unset ORDER_SERVICE_URL
unset INVENTORY_SERVICE_URL
unset MENU_SERVICE_URL

cd ~/cymbal-eats

./setup.sh
./get-site-urls.sh

7. 恭喜!

恭喜,您已完成此 Codelab!

后续步骤:

探索其他 Cymbal Eats Codelab:

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

若要避免产生费用,最简单的方法是删除您为本教程创建的项目。