透過 Identity-Aware Proxy (IAP) 確保無伺服器應用程式安全無虞

1. 總覽

在本研究室中,您將部署員工入口網站,讓員工透過 Cymbal Eats 應用程式查看、更新及刪除訂單。您將使用Identity-Aware Proxy (IAP) 保護入口網站存取權,不必使用虛擬私人網路 (VPN)。IAP 可簡化零信任存取模式的導入作業,且比 VPN 更快,讓遠端工作者不論是在地端部署系統或雲端環境,都能透過單一控制點管理應用程式的存取權。

94b06525c85408ad.png

什麼是 Identity-Aware Proxy?

Identity-Aware Proxy (IAP) 是一項 Google Cloud 服務,可攔截傳送至應用程式的要求,使用 Google Identity 服務對發出請求的使用者進行身分驗證,並只允許已獲授權存取應用程式的使用者所傳送的要求。此外,這項功能還能修改要求標頭,加入已驗證使用者相關資訊。

學習目標

  • 如何設定無伺服器網路端點群組 (NEG)
  • 如何設定負載平衡器
  • 如何啟用 IAP 來限制存取權
  • 如何使用 IAP 限制存取權

2. 設定和需求

自學環境設定

  1. 登入 Google Cloud 控制台,然後建立新專案或重複使用現有專案。如果您還沒有 Gmail 或 Google Workspace 帳戶,請務必建立帳戶

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 「Project name」是這個專案參與者的顯示名稱。這是 Google API 不會使用的字元字串。您隨時可以更新。
  • 專案 ID 在所有 Google Cloud 專案中都是不重複的值,且無法變更 (設定後即無法變更)。Cloud 控制台會自動產生一個專屬字串,您通常不需要特別留意。在大多數程式碼研究室中,您都需要參照專案 ID (通常會標示為 PROJECT_ID)。如果您不喜歡系統產生的 ID,可以隨機產生另一組 ID。或者,您也可以自行嘗試,看看是否可用。這項設定在這個步驟後即無法變更,並會在專案期間維持不變。
  • 僅供參考,有些 API 會使用第三個值,也就是「專案編號」。如要進一步瞭解這三個值,請參閱說明文件
  1. 接下來,您需要在 Cloud 控制台中啟用帳單功能,才能使用 Cloud 資源/API。執行本程式碼研究室時,費用應該不會太高,甚至可能不收費。如要關閉資源,避免產生教學課程以外的費用,您可以刪除已建立的資源,或刪除整個專案。Google Cloud 新使用者可享有 $300 美元的免費試用期

環境設定

  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 服務 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 URL」連結

86416f68c0b8152a.png

3. 設定無伺服器網路端點群組 (NEG)

您將為員工 UI Cloud Run 服務建立無伺服器網路端點群組( 無伺服器 NEG)。無伺服器網路端點群組 (NEG) 可讓您搭配使用 Google Cloud 無伺服器應用程式和外部 HTTP(S) 負載平衡

2abe669e53c27186.png

  1. 為員工 UI 服務建立網路端點群組。
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].

建立後端服務並新增無伺服器網路端點群組

後端服務會定義 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.png

保留靜態 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 Proxy

  1. 建立目標 HTTPS Proxy,將要求轉送至您的網址對應
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. 建立轉送規則,將傳入要求轉送至 Proxy
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.png

  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 URL」連結

8505fde7e0784bf1.png

系統現在會顯示 Cloud Run 服務網址的存取權已遭到禁止。

5. 在負載平衡器上啟用 Cloud Identity-Aware Proxy (IAP)

透過 IAP,您可以為透過 HTTPS 存取的應用程式建立中央授權層。您可以使用應用程式層級存取權控管模型,而非網路層級防火牆。

d9740402a74370a8.png

品牌是 OAuth 同意畫面,其中包含使用者的品牌資訊。品牌可能只限內部或公開使用者。內部品牌可讓 OAuth 流程由專案所在的 Google Workspace 機構成員存取。公開品牌可讓任何網際網路使用者存取 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 憑證處於「ACTIVE」(啟用) 狀態
gcloud compute ssl-certificates list --format='value(MANAGED_STATUS)'
  1. 取得服務網址
echo https://$DOMAIN

輸出範例

https://34.102.234.98.nip.io
  1. 按一下服務網址,開啟員工入口網站。

352b600209c3fb33.png

  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.png

你現在應該可以存取員工入口網站了。

(選用) 部署所有依附元件,部署這些微服務可能需要約 20 分鐘。

unset ORDER_SERVICE_URL
unset INVENTORY_SERVICE_URL
unset MENU_SERVICE_URL

cd ~/cymbal-eats

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

7. 恭喜!

恭喜,您已完成程式碼研究室!

下一步:

探索其他 Cymbal Eats 程式碼研究室:

清除所用資源

如要避免系統向您的 Google Cloud 帳戶收取本教學課程所用資源的費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。

刪除專案

如要避免付費,最簡單的方法就是刪除您為了本教學課程所建立的專案。