29

AWS CLI を使用してコマンドラインから暗号文を復号化すると、暗号文は問題なく復号化されます。

$ aws kms decrypt --ciphertext-blob fileb://encrypted-secrets --output text --query Plaintext --region us-east-1 | base64 --decode > decryped-secrets

この復号化操作は、js スクリプトから実行しようとすると、ローカルでも機能します。

#!/usr/local/bin/node

const fs = require('fs');
const AWS = require('aws-sdk');
const kms = new AWS.KMS({region:'us-east-1'});

const secretPath = './encrypted-secrets';
const encryptedSecret = fs.readFileSync(secretPath);

const params = {
      CiphertextBlob: encryptedSecret
};

kms.decrypt(params, function(err, data) {
  if (err) {
    console.log(err, err.stack);
  } else {
    const decryptedScret = data['Plaintext'].toString();
    console.log('decrypted secret', decryptedScret);
  }
});

ただし、AWS Lambda 関数のコンテキスト内から上記とほぼ同じコードを使用してこれを実行しようとすると、関数の呼び出しでタイムアウトが発生します。

'use strict';

const zlib = require('zlib');
const mysql = require('mysql');
const fs = require('fs');
const AWS = require('aws-sdk');
const kms = new AWS.KMS({region:'us-east-1'});

const secretPath = './encrypted-secrets';
const encryptedSecret = fs.readFileSync(secretPath);

const params = {
    CiphertextBlob: encryptedSecret
};

exports.handler = (event, context, callback) => {
    kms.decrypt(params, (err, data) => {
       if (err) {
            console.log(err, err.stack);
            return callback(err);
        } else {
            const decryptedScret = data['Plaintext'].toString();
            console.log('decrypted secret', decryptedScret);
            return callback(null, `Successfully processed ${parsed.logEvents.length} log events.`);
        }
    });
};

タイムアウト ログ:

START RequestId: start-request-id-redacted Version: $LATEST
END RequestId: end-request-id-redacted
REPORT RequestId: report-requested-id-redacted  Duration: 10002.43 ms   Billed Duration: 10000 ms   Memory Size: 128 MB Max Memory Used: 18 MB  
2016-11-13T19:22:28.774Z task-id-redacted Task timed out after 10.00 seconds

ノート:

  • への呼び出しをコメントアウトして実際に何かkms.decryptを試みたconsole.log場合、値は問題なく出力されます。params呼び出しに何らかの問題があるようでkms.decrypt、タイムアウトを超えた実際のエラーは返されません。
  • ラムダ関数が呼び出されるロールにアタッチされたポリシーには、アタッチされたポリシーAWSLambdaVPCAccessExecutionRoleと、次のアタッチされたインライン ポリシーも含まれます。

policygen-lambda_basic_execution_and_kms_decrypt-201611131221:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "sid-redacted",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": [
                "arn:aws:kms:us-east-1:account-redacted:key/key-id-redacted"
            ]
        }
    ]
}
  • コードから識別情報を削除しました。
4

4 に答える 4

42

非常に助けになった AWS サポート担当者との徹底的な会話の後、私たちは答えを得ました。

タイムアウトが発生した主な理由は、Lambda 関数が設定された VPC に KMS サービスのエンドポイントがないため、Lambda 関数内から KMS サービスへの接続が不足していたためです。

VPC 内の Lambda 関数が、VPC 内にエンドポイントを持つAmazon S3 以外のサービスに接続するに Lambda 関数を少なくとも 1 つ、できれば 2 つのプライベート サブネットに配置/関連付ける必要があります。 NAT ゲートウェイへの 0.0.0.0/16 の宛先ルートを含むルーティング テーブル。

インターネット ゲートウェイを使用して、Lambda 関数をパブリック サブネットに配置することはできません。

KMS および VPC エンドポイントを持たない他のすべてのサービスにアクセスするための VPC バインド Lambda 関数を取得する手順:

  1. NAT ゲートウェイへの 0.0.0.0/0 のルーティング テーブル エントリを持つ、既存のプライベート サブネットを作成するかメモします。
    • 上記のように、NAT ゲートウェイ、ルーティング テーブル、およびサブネットをまだ持っていない場合は、最初にそれらを適切に作成して関連付ける必要があります。
  2. Lambda 関数を作成するときに、Lambda 関数を上記のプライベートサブネットにアタッチするか、Lambda 関数を編集してその設定を行います。

kms.encryptこれらの 2 つの手順に従うと、Lambda 関数内から呼び出しやその他のリクエストを実行できるようになります。これらのサービスには VPC 内にエンドポイントがないため、アウトバウンド/エグレス インターネット接続が必要です。

VPC 内で Lambda がどのように機能するかの視覚的な概要

于 2016-11-14T16:42:48.463 に答える