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"
]
}
]
}
AWSのサポート担当者との徹底的な会話の後、非常に役に立ちましたが、答えがあります。
タイムアウトが発生した主な理由は、Lambda関数が設定されたVPCにエンドポイントがないKMSサービスのために、Lambda関数内からKMSサービスへの接続の欠如によるものでした。
VPCのLambda関数がAmazon S3以外のanyサービスに接続するには、doesVPCにエンドポイントがあり、Lambda関数は少なくとも1つ、できれば2つのプライベートサブネットに配置/関連付けする必要があり、ルーティングテーブルには0.0.0.0/16の宛先ルートが含まれますa NAT Gateway。
インターネットゲートウェイを使用して、Lambda関数をパブリックサブネットにすることはnot可能です。
VPCにバインドされたLambda関数を取得してKMSおよびVPCエンドポイントを持たない他のすべてのサービスにアクセスする手順:
これらの2つの手順に従うと、VPC内にエンドポイントがないため、アウトバウンド/エグレスインターネット接続を必要とするkms.encrypt
およびその他のリクエストをLambda関数内から呼び出すことができるはずです。
EC2インスタンスにはデフォルトで独自のパブリックIPが付属しているため、インターネットへのアクセスを必要とするサービス(KMSなど)へのアクセスに問題はありません。
VPCに接続されたLambda関数にはパブリックIPがないため、インターネット経由でサービス(KMSなど)にアクセスするには、NAT zealoushackerの説明どおりに設定する必要があります。
Zealoushackerの優れた答えに追加するには、ラムダのセキュリティグループ設定に0.0.0.0と任意のポートを指すアウトバウンドルールがあることも確認する必要があります。
この例では、すでにプライベートサブネットで実行されていましたが、セキュリティグループはRDSデータベースに制限されていました。