本文介绍了尝试使用KMS解密Lambda函数中的密文会导致超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当使用AWS CLI从命令行解密密文时,密文被解密而没有问题:

When decrypting ciphertext from the command line using the AWS CLI, the ciphertext gets decrypted without issues:

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

尝试通过js脚本在本地执行此解密操作:

This decryption operation also works locally when attempting to do so from a js script:

#!/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函数的上下文中使用与上面几乎相同的完全相同的代码来执行此操作时,该函数的调用会导致超时:

However, when attempting to do so with almost the same exact code as above from within the context of an AWS Lambda function, the invocation of the function results in a timeout:

'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 的调用并尝试对 params 或其他任何东西进行 console.log 的调用,则将输出值没有问题.调用 kms.decrypt 似乎存在某种问题,并且没有超出超时的实际错误返回.
  • 在调用lambda函数的角色上附加的策略包含附加的策略 AWSLambdaVPCAccessExecutionRole ,以及以下附加的内联策略:
  • If I comment out the call to kms.decrypt and attempt to console.log the params or anything really, the values are output without issues. There seems to be some sort of issue with the kms.decrypt call, and no actual error beyond the timeout is returned.
  • The policy attached to the role under which the lambda function is invoked contains the attached policy AWSLambdaVPCAccessExecutionRole, and also the following attached inline policy:

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支持人员进行了深入交谈之后,我们得到了答案:

    After some thorough conversations with AWS support folks, whom have been very helpful, we have an answer:

    发生超时的主要原因是由于Lambda功能与KMS服务之间缺乏连接,原因是KMS服务在配置Lambda功能的VPC中没有端点.

    The primary reason why there was a timeout was due to a lack of connectivity from within the Lambda function to the KMS service, due to the KMS service not having an endpoint in the VPC where the Lambda function was configured.

    为了使VPC中的Lambda函数连接到中具有终结点的Amazon S3以外的任何服务,Lambda函数必须位于至少一个(但最好是两个)私有子网中/与之相关联,它们的路由表包括到NAT网关的目标路由0.0.0.0/16.

    In order for a Lambda function in a VPC to connect to any service other than Amazon S3, which does have an endpoint in the VPC, the Lambda function has to be situated in/associated with at least one, but preferably two private subnets, with their routing tables including a destination route of 0.0.0.0/16 to a NAT Gateway.

    将Lambda功能置于具有Internet网关的公共子网中是不可能.

    It is not possible to have the Lambda function be in a public subnet, with an Internet Gateway.

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

    Steps to getting a VPC-bound Lambda function to access KMS and all other services that don't have VPC endpoints:

    1. 创建或记录现有的专用子网,该子网具有到NAT网关的0.0.0.0/0路由表条目.
      • 如果您还没有如上所述的NAT网关,路由表和子网,则必须首先适当地创建它们并将它们彼此关联.

    如果遵循这两个步骤,则您应该能够从Lambda函数中调用 kms.encrypt 和其他请求,这些请求需要出站/出口Internet连接,因为这些服务没有端点在您的VPC中.

    If you follow those two steps, you should be able to invoke kms.encrypt and other requests from within your Lambda function, which require outbound/egress internet connectivity, due to those services not having endpoints within your VPC.

    这篇关于尝试使用KMS解密Lambda函数中的密文会导致超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-10 07:27