رمزگذاری توابع ابری با استفاده از کلیدهای رمزگذاری مدیریت شده توسط مشتری (CMEK)

1. مقدمه

نمای کلی

Cloud Functions یک راه حل محاسباتی سبک برای توسعه دهندگان است تا عملکردهای تک منظوره و مستقلی ایجاد کنند که بدون نیاز به مدیریت سرور یا محیط زمان اجرا به رویدادهای Cloud پاسخ می دهد.

می‌توانید از کلیدهای رمزگذاری مدیریت‌شده توسط مشتری (CMEK) برای محافظت از عملکردهای Cloud و داده‌های مرتبط در حالت استراحت استفاده کنید. استقرار یک تابع با یک CMEK از داده های مرتبط با آن با استفاده از یک کلید رمزگذاری که تحت کنترل کامل شما است محافظت می کند. این نوع رمزگذاری به شما این امکان را می دهد که الزامات انطباق در صنایع خاصی مانند خدمات مالی را برآورده کنید. از آنجایی که کلید متعلق به شما است و توسط Google کنترل نمی شود، هیچ کس (از جمله شما) نمی تواند به داده های محافظت شده توسط این کلیدهای رمزگذاری در صورت غیرفعال شدن یا از بین رفتن کلیدها دسترسی داشته باشد.

برای توابع ابری، CMEK موارد زیر را رمزگذاری می کند:

  • کد منبع تابعی که برای استقرار آپلود شده و توسط Google در فضای ذخیره‌سازی ابری ذخیره می‌شود و در فرآیند ساخت استفاده می‌شود.
  • نتایج فرآیند ساخت تابع، از جمله تصویر ظرف ساخته شده از کد منبع تابع شما، هر نمونه از تابعی که مستقر شده است.
  • داده‌های در حالت استراحت برای کانال‌های انتقال رویداد داخلی (فقط نسل اول).

می‌توانید اطلاعات بیشتری در مورد اینکه چه داده‌هایی رمزگذاری شده‌اند را در مستندات Cloud Function CMEK بیابید.

چیزی که خواهی ساخت

این آزمایشگاه کد نحوه استقرار یک تابع ابری (اعم از نسل اول یا نسل دوم) را نشان می دهد که با استفاده از CMEK رمزگذاری شده است. این کد لبه از یک تابع عمومی Cloud استفاده می کند، یعنی تابعی که نیازی به احراز هویت ندارد، برای اهداف نمایشی. شما می توانید یک تابع تایید شده با CMEK فعال را مانند هر تابع Cloud دیگری که نیاز به احراز هویت دارد، فراخوانی کنید.

چیزی که یاد خواهید گرفت

  • نحوه ایجاد یک کلید CMEK بر روی حلقه کلید متقارن موجود
  • چگونه یک مخزن رجیستری آرتیفکت ایجاد کنیم
  • نحوه پیکربندی CMEK بر روی یک تابع ابری برای هر دو نسل 1 و 2

2. راه اندازی و الزامات

پیش نیازها

  • شما به کنسول Cloud وارد شده اید
  • شما قبلاً یک عملکرد ابری راه‌اندازی شده با HTTP را مستقر کرده‌اید (برای تأیید اینکه نقش‌ها و APIهای مناسب را فعال کرده‌اید)

Cloud Shell را فعال کنید

  1. از Cloud Console، روی Activate Cloud Shell کلیک کنید 853e55310c205094.png .

55efc1aaa7a4d3ad.png

اگر این اولین باری است که Cloud Shell را راه اندازی می کنید، با یک صفحه میانی روبرو می شوید که آن را توصیف می کند. اگر با یک صفحه میانی مواجه شدید، روی Continue کلیک کنید.

9c92662c6a846a5c.png

تهیه و اتصال به Cloud Shell فقط باید چند لحظه طول بکشد.

9f0e51b578fecce5.png

این ماشین مجازی با تمام ابزارهای توسعه مورد نیاز بارگذاری شده است. این یک فهرست اصلی 5 گیگابایتی دائمی ارائه می‌کند و در Google Cloud اجرا می‌شود، که عملکرد و احراز هویت شبکه را بسیار افزایش می‌دهد. بسیاری از کارهای شما، اگر نه همه، در این کد لبه با مرورگر قابل انجام است.

پس از اتصال به Cloud Shell، باید ببینید که احراز هویت شده اید و پروژه به ID پروژه شما تنظیم شده است.

  1. برای تایید احراز هویت، دستور زیر را در 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`
  1. دستور زیر را در 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. یک مخزن رجیستری با فرمت Docker با قابلیت CMEK ایجاد کنید

در این بخش، یک مخزن با فرمت Docker در Artifact Registry ایجاد خواهید کرد که دارای CMEK فعال است . این کلید همان کلیدی است که برای استقرار Cloud Function شما استفاده می شود.

ابتدا به حساب سرویس برای رجیستری Artifact نیاز دارید. با اجرای این دستور می توانید آن را ایجاد کنید:

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 حساب فعال فعلی خود را تأیید کنید.

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 جدید خود را با اجرای این دستور مشاهده کنید:

gcloud artifacts repositories describe $REPO_NAME --location=$REGION

5. به حساب‌های خدمات دسترسی به کلید اعطا کنید (نسل دوم)

این بخش ایجاد حساب های سرویس برای توابع نسل دوم را پوشش می دهد. اگر در حال ایجاد یک تابع نسل اول هستید، لطفاً به بخش بعدی بروید.

شما باید با اعطای نقش CryptoKey Encrypter/Decrypter IAM ( roles/cloudkms.cryptoKeyEncrypterDecrypter ) به چندین عامل سرویس اجازه دسترسی به کلید را بدهید. این عوامل سرویس برای دسترسی به کد منبع ذخیره شده در Cloud Storage، ذخیره تصاویر تابع در مخزن محافظت شده با CMEK در Artifact Registry و برای استقرار یک Cloud Function رمزگذاری شده با CMEK استفاده می شوند.

مراحل توابع نسل دوم

  1. به عامل سرویس 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
  1. به عامل سرویس 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
  1. به عامل سرویس رجیستری Artifact به کلید دسترسی بدهید:
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
  1. به عوامل سرویس 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. به حساب‌های خدمات دسترسی به کلید اعطا کنید (نسل اول)

این بخش ایجاد حساب های سرویس برای توابع نسل اول را پوشش می دهد. اگر قبلاً حساب های خدماتی را برای یک تابع نسل دوم ایجاد کرده اید، لطفاً به بخش بعدی بروید.

شما باید با اعطای نقش CryptoKey Encrypter/Decrypter IAM ( roles/cloudkms.cryptoKeyEncrypterDecrypter ) به چندین عامل سرویس اجازه دسترسی به کلید را بدهید. این عوامل سرویس برای دسترسی به کد منبع ذخیره شده در Cloud Storage، ذخیره تصاویر تابع در مخزن محافظت شده با CMEK در Artifact Registry و برای استقرار یک Cloud Function رمزگذاری شده با CMEK استفاده می شوند.

مراحل توابع نسل اول

  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
  1. به عامل سرویس رجیستری Artifact به کلید دسترسی بدهید:
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
  1. به عوامل سرویس 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 (نسل دوم)

این بخش ایجاد توابع نسل دوم را پوشش می دهد. برای دستورالعمل های نسل اول می توانید به بخش بعدی بروید.

اکنون که یک مخزن رجیستری مصنوع دارید که با CMEK فعال است و به Cloud Functions اجازه دسترسی به کلید خود را داده‌اید، اکنون می‌توانید تابعی را که با استفاده از کلید CMEK رمزگذاری شده است، اجرا کنید.

مراحل توابع نسل دوم:

کد منبع را برای تابع ایجاد کنید

اگرچه این کد لبه از Node.js استفاده می کند، شما می توانید از هر زمان اجرا پشتیبانی شده استفاده کنید.

ابتدا یک دایرکتوری و سی دی در آن دایرکتوری ایجاد کنید.

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 اجرا کنید

توجه: مثال زیر نحوه استقرار یک تابع را با استفاده از منابع دایرکتوری فعلی نشان می دهد. مطمئن شوید که در همان دایرکتوری کد منبع تابع خود هستید.

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 $FUNCTION_NAME –region $REGION | را توصیف می‌کنند grep kmsKeyName

تابع نسل دوم را تست کنید

می توانید عملکرد خود را با حلقه کردن آن آزمایش کنید:

FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --region $REGION --format='get(serviceConfig.uri)')"

curl $FUNCTION_URL

که منجر به موارد زیر می شود:

Hello World!

تا زمانی که کلید رمزگذاری فعال باشد، عملکرد موفقیت را به تماس گیرنده بازمی گرداند. با این حال، هنگامی که کلید رمزگذاری غیرفعال شود، تماس گیرنده خطایی دریافت می کند.

در بخش بعدی، می‌بینید که چه اتفاقی می‌افتد وقتی که تابع را پس از غیرفعال شدن کلید فراخوانی می‌کنید.

8. ایجاد یک تابع رمزگذاری شده با CMEK (نسل اول)

این بخش ایجاد توابع نسل اول را پوشش می دهد. اگر قبلاً یک تابع نسل دوم ایجاد کرده اید، لطفاً به بخش بعدی بروید.

اکنون که یک مخزن رجیستری مصنوع دارید که با CMEK فعال است و به Cloud Functions اجازه دسترسی به کلید خود را داده‌اید، اکنون می‌توانید تابعی را که با استفاده از کلید CMEK رمزگذاری شده است، اجرا کنید.

مراحل برای توابع نسل اول:

کد منبع را برای تابع نسل اول ایجاد کنید

اگرچه این کد لبه از Node.js استفاده می کند، شما می توانید از هر زمان اجرا پشتیبانی شده استفاده کنید.

ابتدا یک دایرکتوری و سی دی در آن دایرکتوری ایجاد کنید.

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 اجرا کنید

توجه: مثال زیر نحوه استقرار یک تابع را با استفاده از منابع دایرکتوری فعلی نشان می دهد. مطمئن شوید که در همان دایرکتوری کد منبع تابع خود هستید.

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 $FUNCTION_NAME –region $REGION | را توصیف می‌کنند grep kmsKeyName

تابع نسل اول را تست کنید

می توانید عملکرد خود را با حلقه کردن آن آزمایش کنید:

FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --region $REGION --format='get(httpsTrigger.url)')"

curl $FUNCTION_URL

که منجر به موارد زیر می شود:

Hello World!

تا زمانی که کلید رمزگذاری فعال باشد، عملکرد موفقیت را به تماس گیرنده بازمی گرداند. با این حال، هنگامی که کلید رمزگذاری غیرفعال شود، تماس گیرنده خطایی دریافت می کند.

در بخش بعدی، می‌بینید که چه اتفاقی می‌افتد وقتی که تابع را پس از غیرفعال شدن کلید فراخوانی می‌کنید.

9. یک تابع رمزگذاری شده با CMEK را فراخوانی کنید که در آن کلید رمزگذاری غیرفعال شده است.

در این بخش آخر، کلید را باطل می‌کنید و دوباره Function را فراخوانی می‌کنید تا خطای حاصل را مشاهده کنید.

کلید رمزگذاری را غیرفعال کنید

برای غیرفعال کردن کلید می توانید این دستور را اجرا کنید. از آنجایی که این لبه کد فقط یک نسخه از کلید را ایجاد می کند، نسخه 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 Function، خواهید دید

User's CMEK key has been disabled. CMEK key: projects/<PROJECT-NAME>/locations/us-central1/keyRings/myKeyRing/cryptoKeys/encrypted-function

وقتی کلید CMEK غیرفعال است، سعی کنید منابع را مشاهده کنید

در این بخش، با غیرفعال شدن کلید CMEK، منابع زیر را در دسترس نمی‌بینید:

  • کد منبع تابع
  • ساخت تصویر کانتینر از کد منبع شما

به عنوان مثال، بازدید از برگه منبع برای عملکرد Cloud یک خطا را هنگام واکشی بایگانی نشان می دهد. اگر بخواهید فایل .zip حاوی کد منبع را مستقیماً در فضای ذخیره‌سازی ابری مشاهده کنید، خطای مشابهی دریافت خواهید کرد.

ac3307bb05d30e19.png

علاوه بر این، به استفاده از تصویر ظرف برای عملکرد از Artifact Registry دسترسی نخواهید داشت. به عنوان مثال، اگر بخواهید آن تصویر کانتینر را در Cloud Run مستقر کنید، با خطای یافت نشدن تصویر مواجه خواهید شد.

لطفاً برای فهرست کامل منابع رمزگذاری شده به اسناد توابع CMEK مراجعه کنید.

10. تبریک می گویم

تبریک می گویم، شما نرم افزار کد را تمام کردید!

آنچه را پوشش داده ایم

  • نحوه ایجاد یک کلید CMEK بر روی حلقه کلید متقارن موجود
  • چگونه یک مخزن رجیستری آرتیفکت ایجاد کنیم
  • نحوه پیکربندی CMEK در یک تابع ابری

برای اطلاعات بیشتر

اطلاعات بیشتر در مورد Cloud Functions و CMEK را می توانید در لینک های زیر بیابید: