Шифрование облачных функций с использованием ключей шифрования, управляемых клиентом (CMEK),Шифрование облачных функций с использованием ключей шифрования, управляемых клиентом (CMEK)

1. Введение

Обзор

Cloud Functions — это легковесное вычислительное решение для разработчиков, позволяющее создавать автономные функции, выполняющие одну задачу и реагирующие на события в облаке, без необходимости управления сервером или средой выполнения.

Для защиты облачных функций и связанных с ними данных в состоянии покоя вы можете использовать управляемые клиентом ключи шифрования (CMEK) в рамках сервиса управления ключами облака (Cloud Key Management Service) . Развертывание функции с использованием CMEK защищает связанные с ней данные с помощью ключа шифрования, который находится под вашим полным контролем. Этот тип шифрования позволяет соответствовать требованиям законодательства в определенных отраслях, например, в сфере финансовых услуг. Поскольку ключ принадлежит вам и не контролируется Google, никто (включая вас) не сможет получить доступ к данным, защищенным этими ключами шифрования, если ключи отключены или уничтожены.

Для облачных функций CMEK шифрует следующие данные:

  • Исходный код функции загружен для развертывания и хранится компанией Google в облачном хранилище, где используется в процессе сборки.
  • Результаты процесса сборки функции, включая образ контейнера, созданный из исходного кода вашей функции, а также каждый развернутый экземпляр функции.
  • Данные в состоянии покоя для внутренних каналов передачи событий (только 1-го поколения).

Более подробную информацию о том, какие данные шифруются, можно найти в документации Cloud Function CMEK .

Что вы построите

В этом практическом занятии показано, как развернуть облачную функцию (1-го или 2-го поколения), зашифрованную с помощью CMEK. В качестве примера используется общедоступная облачная функция, то есть функция, не требующая аутентификации. Вы можете вызывать аутентифицированную функцию с поддержкой CMEK так же, как и любую другую облачную функцию, требующую аутентификации.

Что вы узнаете

  • Как создать ключ CMEK на существующем симметричном брелке ключей
  • Как создать репозиторий реестра артефактов
  • Как настроить CMEK в облачной функции для первого и второго поколений

2. Настройка и требования

Предварительные требования

  • Вы вошли в облачную консоль.
  • Вы ранее развернули облачную функцию, запускаемую по HTTP-запросу (для проверки наличия соответствующих ролей и включенных API).

Активировать Cloud Shell

  1. В консоли Cloud нажмите «Активировать Cloud Shell» . 853e55310c205094.png .

55efc1aaa7a4d3ad.png

Если вы запускаете Cloud Shell впервые, вам будет показан промежуточный экран с описанием его возможностей. Если вам был показан промежуточный экран, нажмите «Продолжить» .

9c92662c6a846a5c.png

Подготовка и подключение к Cloud Shell займут всего несколько минут.

9f0e51b578fecce5.png

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Она предоставляет постоянный домашний каталог объемом 5 ГБ и работает в облаке Google, что значительно повышает производительность сети и аутентификацию. Большая часть, если не вся, ваша работа в этом практическом задании может быть выполнена с помощью браузера.

После подключения к 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].

3. Создайте новый брелок и ключ для Cloud Functions.

Убедитесь, что API Cloud KMS включен, выполнив следующую команду:

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. Создайте репозиторий Artifact Registry в формате Docker с поддержкой CMEK.

В этом разделе вы создадите репозиторий в формате Docker в Artifact Registry с включенной поддержкой CMEK . Этот ключ будет тем же ключом, который использовался для развертывания вашей облачной функции.

Во-первых, вам понадобится учетная запись службы для Реестра артефактов. Вы можете создать ее, выполнив следующую команду:

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

Для предоставления учетной записи службы реестра артефактов прав доступа к ключу используйте следующую команду: ( 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

Теперь вы можете создать репозиторий в формате 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-го поколения)

В этом разделе рассматривается создание учетных записей служб для функций второго поколения. Если вы создаете функцию первого поколения, перейдите к следующему разделу.

Необходимо предоставить доступ к ключу нескольким сервисным агентам, назначив им роль IAM «Шифрование/дешифрование криптографического ключа» ( roles/cloudkms.cryptoKeyEncrypterDecrypter ). Эти сервисные агенты используются для получения доступа к исходному коду, хранящемуся в Cloud Storage, для хранения образов функций в защищенном CMEK репозитории в Artifact Registry и для развертывания зашифрованной CMEK облачной функции.

Пошаговое руководство по использованию функций 2-го поколения

  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. Предоставьте агенту службы Реестра артефактов доступ к ключу:
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. Предоставьте агентам службы облачного хранилища доступ к ключу:
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-го поколения)

В этом разделе рассматривается создание учетных записей служб для функций первого поколения. Если вы ранее создавали учетные записи служб для функций второго поколения, перейдите к следующему разделу.

Необходимо предоставить доступ к ключу нескольким сервисным агентам, назначив им роль IAM «Шифрование/дешифрование криптографического ключа» ( 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. Предоставьте агенту службы Реестра артефактов доступ к ключу:
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. Предоставьте агентам службы облачного хранилища доступ к ключу:
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-го поколения).

В этом разделе рассматривается создание функций второго поколения. Инструкции по созданию функций первого поколения можно найти в следующем разделе.

Теперь, когда у вас настроен репозиторий Artifact Registry с включенным CMEK и предоставлен доступ 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.

Примечание: В приведенном ниже примере показано, как развернуть функцию, используя исходный код из текущего каталога. Убедитесь, что вы находитесь в том же каталоге, что и исходный код вашей функции.

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

Проверьте работу функций второго поколения.

Вы можете проверить свою функцию, выполнив команду curl:

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

curl $FUNCTION_URL

В результате чего получается следующее:

Hello World!

Пока ключ шифрования включен, функция будет возвращать вызывающей стороне успешный результат. Однако, как только ключ шифрования будет отключен, вызывающая сторона получит ошибку.

В следующем разделе вы увидите, что произойдет, если вызвать функцию после того, как клавиша будет отключена.

8. Создайте функцию, зашифрованную с помощью CMEK (1-го поколения).

В этом разделе рассматривается создание функций первого поколения. Если вы ранее создавали функции второго поколения, перейдите к следующему разделу.

Теперь, когда у вас настроен репозиторий Artifact Registry с включенным CMEK и предоставлен доступ Cloud Functions к вашему ключу, вы можете развернуть функцию, зашифрованную с помощью вашего ключа 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 functions describe $FUNCTION_NAME –region $REGION | grep kmsKeyName

Протестируйте функцию первого поколения.

Вы можете проверить свою функцию, выполнив команду 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".

В журналах облачной функции вы увидите следующее:

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

Кроме того, у вас не будет доступа к использованию образа контейнера для этой функции из реестра артефактов. Например, если вы попытаетесь развернуть этот образ контейнера в Cloud Run, вы получите ошибку о том, что образ не найден.

Полный список зашифрованных ресурсов см. в документации по функциям CMEK.

10. Поздравляем!

Поздравляем, вы завершили практическое занятие!

Что мы рассмотрели

  • Как создать ключ CMEK на существующем симметричном брелке ключей
  • Как создать репозиторий реестра артефактов
  • Как настроить CMEK в облачной функции

Для получения дополнительной информации

Более подробную информацию о Cloud Functions и CMEK вы найдете по следующим ссылкам: