尝试使用KMS解密Lambda函数中的密文会导致超时

时间:2016-11-13 19:36:15

标签: amazon-web-services aws-lambda aws-sdk aws-kms aws-sdk-nodejs

使用AWS CLI从命令行解密密文时,密文会被解密而不会出现问题:

testScoreAndLabel.rdd

当尝试从js脚本执行此操作时,此解密操作也可在本地运行:

val testMetrics = new BinaryClassificationMetrics(testScoreAndLabel.rdd)

但是,当尝试使用与AWS Lambda函数的上下文几乎完全相同的代码时,调用该函数会导致超时:

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

超时日志:

#!/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);
  }
});

注意:

  • 如果我将对'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调用似乎存在某种问题,并且不会返回超时后的实际错误。
  • 附加到调用lambda函数的角色的策略包含附加的策略params,以及以下附加的内联策略:

kms.decrypt

AWSLambdaVPCAccessExecutionRole
  • 我已经从代码中删除了任何识别信息。

3 个答案:

答案 0 :(得分:33)

在与AWS支持人员进行了彻底的对话之后,我们得到了答案:

超时的主要原因是由于KMS服务在配置Lambda函数的VPC中没有端点,因此Lambda函数内部缺少连接到KMS服务。

为了让VPC中的Lambda函数连接到除Amazon S3之外的任何服务,其中 在VPC中有一个端点,Lambda函数必须位于至少一个但优选地两个私有子网中/与其相关联,其路由表包括到NAT网关的0.0.0.0/16的目的地路由。

使用Internet网关将Lambda函数置于公有子网中

获取VPC绑定的Lambda函数以访问KMS以及所有其他没有VPC端点的服务的步骤:

  1. 创建或记录现有的私有子网,其具有0.0.0.0/0的路由表条目到NAT网关。
    • 如果您还没有NAT网关,路由表和子网,如上所述,您必须首先相互创建并相互关联。
  2. 在创建Lambda函数时将Lambda函数附加到上面的私有子网,或者编辑Lambda函数以使其具有该配置。
  3. 如果您遵循这两个步骤,您应该能够从Lambda函数中调用kms.encrypt和其他请求,这些请求需要出站/出站互联网连接,因为这些服务在您的VPC中没有端点。< / p>

    Visual overview of how Lambda works within a VPC

答案 1 :(得分:4)

EC2实例默认带有自己的公共IP,因此访问任何需要访问互联网的服务(例如KMS)都没有问题。

附加到您的VPC的Lambda函数没有公共IP,因此要通过互联网(例如KMS)访问服务,您需要像zealoushacker所描述的那样设置NAT。

答案 2 :(得分:3)

为了增加zealoushacker的优秀答案,你还应该检查你的lambda&#39;安全组设置具有指向0.0.0.0和任何端口的出站规则。

在我们的案例中,我们已经在私有子网中运行,但是将安全组限制在我们的RDS数据库中。