Безсерверная структура и служба управления ключами (KMS) - PullRequest
0 голосов
/ 11 февраля 2019

В основном я использую serverless framework без сервера для функции, которая позволяет мне отправлять / получать электронные письма через mailgun.

Для этого у меня есть файл config.js, настроенный в моембезсерверная папка.Это config.js содержит все мои ключи API, адрес электронной почты, логин и т. Д. Для моей функции «mailgun».

Я хочу использовать Google Cloud KMS для шифрования ресурса config.js, так как боюсь, что мой чувственныйданные украдены и использованы не по назначению.Зашифрованный файл config.js.enc. google_key_management_service

Но serverless deploy не расшифровывает мои config.js.enc.Это приводит к ошибке ресурса / синтаксиса ...

Какие-либо решения / идеи, как я могу заставить KMS работать для моего config.js файла в моей serverless инфраструктуре?

Я также добавил теги AWS,потому что они имеют аналогичный KMS, как Google Cloud.Но на самом деле я думаю, что настоящая проблема связана с платформой serverless, которая заставляет зашифрованные файлы работать при развертывании без сервера с помощью команды sls deploy, но я могу ошибаться.

1 Ответ

0 голосов
/ 11 февраля 2019

Бессерверная структура, по-видимому, включает в себя собственные интеграции AWS SSM :

functions:
  myfunc:
    # other config
    environment:
      TWITTER_ACCESS_TOKEN: ${ssm:myFunc}

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

Вам нужны секреты?

Всегда важно спросить - действительно ли они мне нужны?секреты?Не могли бы вы использовать облачный провайдер IAM (или даже кросс-облачный OIDC ) вместо введения секретов в мое приложение?По возможности старайтесь использовать решение IAM, предоставляемое различными облаками.Очевидно, что есть еще несколько случаев, когда требуется секрет.

Зашифрованные переменные среды

Перед запуском функции вы шифруете секреты открытого текста локально в зашифрованный текст (зашифрованные строки).Вот пример с gcloud, но вы также можете использовать API или другие инструменты, такие как HashiCorp Vault :

$ gcloud kms encrypt \
    --ciphertext-file=- \
    --plaintext-file=/path/to/my/secret \
    --key=my-kms-key \
    --key-ring=my-kms-keyring \
    --location=us-east4 \ 
    | base64

Это выведет зашифрованную строку в кодировке base64, которую вы затем сохранитев вашем config.js:

CiQAePa3VBJLbunLSqIJT+RS4nYiKdIaW6U69Y...

При запуске настройте ваше приложение на:

  1. Base64, декодируйте строку
  2. Расшифруйте зашифрованный текст с помощью Cloud KMS
  3. Сохраняйте открытый текст в памяти до тех пор, пока вам необходим секрет

Я не уверен, какой язык (языки) вы используете, но вот пример nodejs.Вы можете найти гораздо больше примеров на GitHub по адресу sethvargo / secrets-in-serverless :

const cryptoKeyID = process.env.KMS_CRYPTO_KEY_ID;

const kms = require('@google-cloud/kms');
const client = new kms.v1.KeyManagementServiceClient();

let username;
client.decrypt({
  name: cryptoKeyID,
  ciphertext: process.env.DB_USER,
}).then(res => {
  username = res[0].plaintext.toString().trim();
}).catch(err => {
  console.error(err);
});

let password;
client.decrypt({
  name: cryptoKeyID,
  ciphertext: process.env.DB_PASS,
}).then(res => {
  password = res[0].plaintext.toString().trim();
}).catch(err => {
  console.error(err);
});

exports.F = (req, res) => {
  res.send(`${username}:${password}`)
}

Облачное хранилище Google

Поскольку вы находитесь в GCP, другойВариант - использовать Google Cloud Storage (GCS) напрямую для хранения секретов.Это приведет к удалению вашей связи из безсерверной инфраструктуры.

  1. Создание корзины:

    $ gsutil mb gs://${GOOGLE_CLOUD_PROJECT}-serverless-secrets
    
  2. Создание корзины частной:

    $ gsutil defacl set private gs://${GOOGLE_CLOUD_PROJECT}-serverless-secrets
    $ gsutil acl set -r private gs://${GOOGLE_CLOUD_PROJECT}-serverless-secrets
    
  3. Запишите некоторые секреты в ведро.Несмотря на то, что они передаются в виде открытого текста, они зашифрованы в состоянии покоя, и доступ строго контролируется с помощью IAM.

    $ gsutil -h 'Content-Type: application/json' cp - gs://${GOOGLE_CLOUD_PROJECT}-serverless-secrets/app1 <<< '{"username":"my-user", "password":"s3cr3t"}'
    

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

Наконец, прочитайте из корзины при запуске функции (на этот раз пример Python):

import os
import json
from google.cloud import storage

blob = storage.Client() \
    .get_bucket(os.environ['STORAGE_BUCKET']) \
    .get_blob('app1') \
    .download_as_string()

parsed = json.loads(blob)

username = parsed['username']
password = parsed['password']

def F(request):
    return f'{username}:{password}'
...