1. 簡介
總覽
Cloud Functions 是一個輕量的運算解決方案,可讓開發人員建立獨立的單一用途函式來回應雲端事件,而不必管理伺服器或執行階段環境。
您可以使用 Cloud Key Management Service 客戶自行管理的加密金鑰 (CMEK),保護 Cloud Functions 和靜態相關資料。以 CMEK 部署函式時,系統會使用您全權控管的加密金鑰,保護與其相關聯的資料。這種加密方式可讓您滿足金融服務等特定產業的法規遵循要求。金鑰為您所有,且不是由 Google 控管,因此當金鑰停用或刪除時,任何人 (包括您自己) 都無法存取這些加密金鑰保護的資料。
以 Cloud Functions 來說,CMEK 會加密下列項目:
- 上傳並部署在 Cloud Storage 中的函式原始碼,供 Google 用於建構程序。
- 函式建構程序的結果,包括透過函式原始碼建構的容器映像檔,以及部署的函式的每個執行個體。
- 內部事件傳輸管道的靜態資料 (僅限第 1 代)。
如要進一步瞭解哪些資料會加密,請參閱 Cloud 函式 CMEK 說明文件。
建構項目
本程式碼研究室將說明如何部署使用 CMEK 加密的 Cloud 函式 (第 1 代或第 2 代)。本程式碼研究室會使用公開的 Cloud 函式 (即不需要驗證的函式) 進行示範。您可以叫用已驗證且已啟用 CMEK 的函式,就像其他需要驗證的 Cloud 函式一樣。
課程內容
- 如何在現有的對稱金鑰環中建立 CMEK 金鑰
- 如何建立 Artifact Registry 存放區
- 如何在第 1 代和第 2 代的 Cloud 函式中設定 CMEK
2. 設定和需求
必要條件
- 您已登入 Cloud 控制台
- 您先前已部署透過 HTTP 觸發的 Cloud 函式 (目的是確認您已啟用適當的角色和 API)
啟用 Cloud Shell
- 在 Cloud 控制台中,按一下「啟用 Cloud Shell」圖示
。
如果您是第一次啟動 Cloud Shell,系統會顯示中繼畫面,說明這項服務的內容。如果系統顯示中繼畫面,請按一下「繼續」。
佈建並連線至 Cloud Shell 只需幾分鐘的時間。
這個虛擬機器已載入所有必要的開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。在本程式碼研究室中,您的大部分作業都可透過瀏覽器完成。
連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的專案 ID。
- 在 Cloud Shell 中執行下列指令,確認您已通過驗證:
gcloud auth list
指令輸出
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- 在 Cloud Shell 中執行下列指令,確認 gcloud 指令知道您的專案:
gcloud config list project
指令輸出
[core] project = <PROJECT_ID>
如果尚未設定,請使用下列指令進行設定:
gcloud config set project <PROJECT_ID>
指令輸出
Updated property [core/project].
3. 為 Cloud Functions 建立新的金鑰環和金鑰
執行下列指令,確認 Cloud KMS API 已啟用:
gcloud services enable cloudkms.googleapis.com
首先,請建立環境變數,以納入本程式碼研究室中使用的金鑰環名稱、金鑰名稱、區域和其他變數。
KEYRING_NAME="keyring-functions" REGION="us-central1" KEY_NAME="key-encrypted-function" PROJECT_ID=$(gcloud config get-value project) PROJECT_NUMBER="$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')" USER_EMAIL="$(gcloud config list account --format "value(core.account)")"
接下來,建立金鑰環,這是 Cloud KMS 金鑰和金鑰版本的根資源。
gcloud kms keyrings create $KEYRING_NAME --location $REGION
最後,您現在可以在 Cloud KMS 的新金鑰環中建立對稱金鑰,
gcloud kms keys create $KEY_NAME --keyring $KEYRING_NAME --location $REGION --purpose "encryption"
4. 建立已啟用 CMEK 的 Docker 格式的 Artifact Registry 存放區
在本節中,您將在已啟用 CMEK 的 Artifact Registry 中建立 Docker 格式的存放區。這組金鑰會用於部署 Cloud 函式。
首先,您必須擁有 Artifact Registry 的服務帳戶。如要建立這個資料庫,請執行下列指令:
gcloud beta services identity create --service=artifactregistry.googleapis.com --project=$PROJECT_ID
執行下列指令,將 CryptoKey Encrypter/Decrypter IAM 角色 (roles/cloudkms.cryptoKeyEncrypterDecrypter
) 授予 Artifact Registry 服務帳戶,以取得金鑰的存取權:
gcloud kms keys add-iam-policy-binding \ $KEY_NAME --location $REGION --keyring=$KEYRING_NAME \ --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com \ --role roles/cloudkms.cryptoKeyEncrypterDecrypter
並將建立存放區的原則授予角色,例如:你目前的使用中帳戶您可以執行 gcloud auth list 來驗證目前使用中的帳戶。
gcloud kms keys add-iam-policy-binding \ $KEY_NAME --location $REGION --keyring=$KEYRING_NAME \ --member user:$USER_EMAIL \ --role roles/cloudkms.cryptoKeyEncrypterDecrypter
現在,您可以建立 Docker 格式的存放區,並啟用 CMEK 功能。
注意事項:區域必須與 CMEK 金鑰位於相同區域。
REPO_NAME=my-cmek-encrypted-repo KEY_FULLPATH=projects/"$PROJECT_ID"/locations/"$REGION"/keyRings/"$KEYRING_NAME"/cryptoKeys/"$KEY_NAME" gcloud artifacts repositories create $REPO_NAME \ --repository-format=docker \ --location=$REGION \ --kms-key=$KEY_FULLPATH \ --async
您可以執行下列指令,查看新的 Artifact Registry 存放區:
gcloud artifacts repositories describe $REPO_NAME --location=$REGION
5. 將金鑰 (第 2 代) 的存取權授予服務帳戶
本節說明如何建立第 2 代函式的服務帳戶。如要建立第 1 代函式,請繼續參閱下一節。
您必須授予 CryptoKey 加密者/解密者 IAM 角色 (roles/cloudkms.cryptoKeyEncrypterDecrypter
),將金鑰存取權授予多個服務代理。這些服務代理可用於存取儲存在 Cloud Storage 中的原始碼、將函式映像檔儲存在 Artifact Registry 中受 CMEK 保護的存放區,以及部署 CMEK 加密的 Cloud 函式。
第 2 代函式的步驟
- 將金鑰存取權授予 Cloud Run 服務代理:
CLOUDRUN_SA=service-$PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$CLOUDRUN_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
- 向 Eventarc 服務代理授予金鑰的存取權:
EVENTARC_SA=service-$PROJECT_NUMBER@gcp-sa-eventarc.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$EVENTARC_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
- 將金鑰存取權授予 Artifact Registry 服務代理:
AR_SA=service-$PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$AR_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
- 將金鑰存取權授予 Cloud Storage 服務代理:
STORAGE_SA=service-$PROJECT_NUMBER@gs-project-accounts.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$STORAGE_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
下一節將說明如何建立及部署 CMEK 加密函式。
6. 將金鑰的存取權授予服務帳戶 (第 1 代)
本節說明建立第 1 代函式的服務帳戶。如果先前已為第 2 代函式建立服務帳戶,請繼續參閱下一節。
您必須授予 CryptoKey 加密者/解密者 IAM 角色 (roles/cloudkms.cryptoKeyEncrypterDecrypter
),將金鑰存取權授予多個服務代理。這些服務代理可用於存取儲存在 Cloud Storage 中的原始碼、將函式映像檔儲存在 Artifact Registry 中受 CMEK 保護的存放區,以及部署 CMEK 加密的 Cloud 函式。
第 1 代函式的步驟
- 將金鑰存取權授予 Cloud Functions 服務代理:
FUNCTION_SA=service-$PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$FUNCTION_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
- 將金鑰存取權授予 Artifact Registry 服務代理:
AR_SA=service-$PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$AR_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
- 將金鑰存取權授予 Cloud Storage 服務代理:
STORAGE_SA=service-$PROJECT_NUMBER@gs-project-accounts.iam.gserviceaccount.com gcloud kms keys add-iam-policy-binding $KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION \ --member=serviceAccount:$STORAGE_SA \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
下一節將說明如何建立及部署 CMEK 加密函式。
7. 建立 CMEK 加密的函式 (第 2 代)
本節說明如何建立第 2 代函式。你可以前往下一節查看第 1 代操作說明。
現在,您已完成啟用 CMEK 的 Artifact Registry 存放區,並將金鑰存取權授予 Cloud Functions,現在可以部署使用 CMEK 金鑰加密的函式。
第 2 代函式須採取的步驟:
建立函式的原始碼
雖然本程式碼研究室使用的是 Node.js,但您還是可以使用任何支援的執行階段。
首先,建立目錄並以 cd 放入該目錄。
mkdir ~/cmek-function-2ndgen && cd $_
然後建立 package.json 檔案。
touch package.json echo '{ "dependencies": { "@google-cloud/functions-framework": "^2.1.0" } } ' > package.json
接著,建立 index.js 來源檔案。
touch index.js echo 'const functions = require("@google-cloud/functions-framework"); functions.http("helloWorld", (req, res) => { res.send(`Hello ${req.query.name || req.body.name || "World"}!`); });' > index.js
使用 CMEK 加密部署第 2 代 Cloud 函式
注意:以下範例說明如何使用目前目錄中的來源部署函式。確認您位於與函式原始碼相同的目錄中。
FUNCTION_NAME=protect-me-cmek-2ndgen ENTRY_POINT=helloWorld REPO_FULLPATH=projects/"$PROJECT_ID"/locations/"$REGION"/repositories/$REPO_NAME gcloud beta functions deploy $FUNCTION_NAME \ --gen2 \ --region $REGION \ --kms-key $KEY_FULLPATH \ --docker-repository $REPO_FULLPATH \ --source . \ --trigger-http \ --allow-unauthenticated \ --runtime nodejs16 \ --entry-point $ENTRY_POINT
您可以執行下列指令,從產生的輸出內容中查看 CMEK 金鑰
gcloud functions describe $FUNCTION_NAME –region $REGION |grep kmsKeyName
測試第 2 代函式
您可以使用 curl 來測試函式:
FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --region $REGION --format='get(serviceConfig.uri)')" curl $FUNCTION_URL
結果如下:
Hello World!
只要啟用加密金鑰,該函式就會將成功傳回給呼叫端。不過,加密金鑰停用後,呼叫端會收到錯誤訊息。
在下一節中,您將瞭解在金鑰停用後叫用函式時會發生的情況。
8. 建立 CMEK 加密的函式 (第 1 代)
本節說明如何建立第 1 代函式。如果先前已建立第 2 代函式,請繼續參閱下一節。
現在,您已完成啟用 CMEK 的 Artifact Registry 存放區,並將金鑰存取權授予 Cloud Functions,現在可以部署使用 CMEK 金鑰加密的函式。
第 1 代函式應採取的步驟:
建立第 1 代函式的原始碼
雖然本程式碼研究室使用的是 Node.js,但您還是可以使用任何支援的執行階段。
首先,建立目錄並以 cd 放入該目錄。
mkdir ~/cmek-function-1stgen && cd $_
接著,建立 package.json 檔案。
touch package.json echo '{ "name": "function-cmek-codelab", "version": "0.0.1" }' > package.json
接著,建立 index.js 來源檔案。
touch index.js echo "exports.helloWorld = (req, res) => { let message = req.query.message || req.body.message || 'Hello World!'; res.status(200).send(message); };" > index.js
使用 CMEK 加密部署第 1 代 Cloud 函式
注意:以下範例說明如何使用目前目錄中的來源部署函式。確認您位於與函式原始碼相同的目錄中。
FUNCTION_NAME=protect-me-cmek-1stgen ENTRY_POINT=helloWorld REPO_FULLPATH=projects/"$PROJECT_ID"/locations/"$REGION"/repositories/$REPO_NAME gcloud functions deploy $FUNCTION_NAME \ --region $REGION \ --kms-key $KEY_FULLPATH \ --docker-repository $REPO_FULLPATH \ --source . \ --trigger-http \ --allow-unauthenticated \ --runtime nodejs16 \ --entry-point $ENTRY_POINT
您可以執行下列指令,從產生的輸出內容中查看 CMEK 金鑰
gcloud functions describe $FUNCTION_NAME –region $REGION |grep kmsKeyName
測試第 1 代函式
您可以使用 curl 來測試函式:
FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --region $REGION --format='get(httpsTrigger.url)')" curl $FUNCTION_URL
結果如下:
Hello World!
只要啟用加密金鑰,該函式就會將成功傳回給呼叫端。不過,加密金鑰停用後,呼叫端會收到錯誤訊息。
在下一節中,您將瞭解在金鑰停用後叫用函式時會發生的情況。
9. 叫用已啟用加密金鑰的 CMEK 加密函式
在最後一節中,您會撤銷金鑰並再次叫用函式,查看產生的錯誤。
停用加密金鑰
您可以執行下列指令來停用金鑰。本程式碼研究室只會建立一個金鑰版本,因此會停用版本 1。
gcloud kms keys versions disable 1 \ --key=$KEY_NAME \ --keyring=$KEYRING_NAME \ --location=$REGION
畫面中應該會顯示以下資訊:
algorithm: GOOGLE_SYMMETRIC_ENCRYPTION createTime: '2023-04-11T03:30:49.111832653Z' generateTime: '2023-04-11T03:30:49.111832653Z' name: projects/dogfood-gcf-saraford/locations/us-central1/keyRings/myKeyRing/cryptoKeys/encrypted-function/cryptoKeyVersions/1 protectionLevel: SOFTWARE state: DISABLED
使用已停用的金鑰叫用函式
現在,請再次 curl
函式。
curl $FUNCTION_URL
這次您也不會收到 Hello World 回應。
在 Cloud 函式的記錄檔中,您會看到
User's CMEK key has been disabled. CMEK key: projects/<PROJECT-NAME>/locations/us-central1/keyRings/myKeyRing/cryptoKeys/encrypted-function
在 CMEK 金鑰停用時嘗試查看資源
在本節中,您將發現 CMEK 金鑰停用時,下列資源將無法使用:
- 函式原始碼
- 透過原始碼建構容器映像檔
例如,造訪 Cloud 函式的「來源」分頁時,擷取封存檔時會顯示錯誤。如果您嘗試直接在 Cloud Storage 中查看含有原始碼的 .zip 檔案,也會收到類似的錯誤。
此外,您將無法使用 Artifact Registry 中函式的容器映像檔。舉例來說,如果您嘗試將該容器映像檔部署至 Cloud Run,您會收到找不到映像檔的錯誤訊息。
10. 恭喜
恭喜,您已完成程式碼研究室!
涵蓋內容
- 如何在現有的對稱金鑰環中建立 CMEK 金鑰
- 如何建立 Artifact Registry 存放區
- 如何在 Cloud 函式中設定 CMEK
瞭解詳情
如要進一步瞭解 Cloud Functions 和 CMEK,請點選以下連結: