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

۱. مقدمه

نمای کلی

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

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

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

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

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

آنچه خواهید ساخت

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

آنچه یاد خواهید گرفت

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

۲. تنظیمات و الزامات

پیش‌نیازها

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

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

  1. از کنسول ابری، روی فعال کردن پوسته ابری کلیک کنید 853e55310c205094.png .

55efc1aaa7a4d3ad.png

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

9c92662c6a846a5c.png

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

9f0e51b578fecce5.png

این ماشین مجازی مجهز به تمام ابزارهای توسعه مورد نیاز است. این ماشین یک دایرکتوری خانگی پایدار ۵ گیگابایتی ارائه می‌دهد و در فضای ابری گوگل اجرا می‌شود که عملکرد شبکه و احراز هویت را تا حد زیادی افزایش می‌دهد. بخش عمده‌ای از کار شما در این آزمایشگاه کد، اگر نگوییم همه، را می‌توان با یک مرورگر انجام داد.

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

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

۳. یک حلقه کلید و کلید جدید برای توابع ابری ایجاد کنید

با اجرای دستور زیر مطمئن شوید که 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"

۴. یک مخزن رجیستری مصنوعات با فرمت Docker و قابلیت CMEK ایجاد کنید

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

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

gcloud beta services identity create --service=artifactregistry.googleapis.com --project=$PROJECT_ID

از دستور زیر برای اعطای مجوز دسترسی به کلید به حساب سرویس Artifact Registry به نقش IAM رمزنگاری/رمزگشای CryptoKey ( roles/cloudkms.cryptoKeyEncrypterDecrypter ) استفاده کنید:

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

اکنون می‌توانید یک مخزن با فرمت داکر ایجاد کنید که 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

۵. به حساب‌های کاربری سرویس (Service Accounts) اجازه دسترسی به کلید (نسل دوم) را بدهید

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

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

۶. به حساب‌های کاربری سرویس (Service Accounts) اجازه دسترسی به کلید (نسل اول) را بدهید

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

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

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

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

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

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

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

اگرچه این آزمایشگاه کد از 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، نسل دوم عملکرد ابری را مستقر کنید

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

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 را توصیف می‌کنند. تابع grep kmsKeyName

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

می‌توانید تابع خود را با curl کردن آن آزمایش کنید:

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

curl $FUNCTION_URL

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

Hello World!

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

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

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

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

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

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

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

اگرچه این آزمایشگاه کد از 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، نسل اول عملکرد ابری را مستقر کنید

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

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 را توصیف می‌کنند. تابع grep kmsKeyName

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

می‌توانید تابع خود را با curl کردن آن آزمایش کنید:

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

curl $FUNCTION_URL

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

Hello World!

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

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

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

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

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

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

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 را دریافت نخواهید کرد.

در گزارش‌های مربوط به عملکرد ابری، موارد زیر را مشاهده خواهید کرد:

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

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

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

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

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

ac3307bb05d30e19.png

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

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

۱۰. تبریک

تبریک می‌گویم، شما codelab را تمام کردید!

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

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

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

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