usar test services porque expresiones example aws amazon-web-services aws-lambda aws-sdk aws-kms aws-sdk-nodejs

amazon-web-services - test - serverless



Intentar descifrar el texto cifrado dentro de una funciĆ³n Lambda utilizando los resultados de KMS en el tiempo de espera (3)

Al descifrar el texto cifrado de la línea de comandos mediante la CLI de AWS, el texto cifrado se descifra sin problemas:

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

Esta operación de descifrado también funciona localmente cuando se intenta hacerlo desde un script 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); } });

Sin embargo, al intentar hacerlo con casi el mismo código exacto que el anterior en el contexto de una función de AWS Lambda, la invocación de la función produce un tiempo de espera:

''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.`); } }); };

registro de tiempo de espera:

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

Notas:

  • Si hago un comentario sobre la llamada a kms.decrypt y kms.decrypt de kms.decrypt los params o algo realmente, los valores se emiten sin problemas. Parece que hay algún tipo de problema con la llamada kms.decrypt , y no se devuelve ningún error real más allá del tiempo de espera.
  • La política asociada a la función bajo la cual se invoca la función lambda contiene la política adjunta AWSLambdaVPCAccessExecutionRole , y también la siguiente política en línea adjunta:

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" ] } ] }

  • He redactado cualquier información de identificación del código.

Después de algunas conversaciones exhaustivas con la gente de soporte de AWS, que ha sido de gran ayuda, tenemos una respuesta:

La razón principal por la que hubo un tiempo de espera se debió a una falta de conectividad desde la función Lambda al servicio KMS, debido a que el servicio KMS no tenía un punto final en la VPC donde estaba configurada la función Lambda.

Para que una función Lambda en una VPC se conecte a cualquier servicio que no sea Amazon S3, que tenga un punto final en la VPC, la función Lambda debe estar ubicada en / asociada con al menos una, pero preferiblemente dos subredes privadas, con sus tablas de enrutamiento, incluida una ruta de destino de 0.0.0.0/16 a una puerta de enlace NAT.

No es posible tener la función Lambda en una subred pública, con una puerta de enlace de Internet.

Pasos para obtener una función Lambda vinculada a VPC para acceder a KMS y a todos los demás servicios que no tienen puntos finales de VPC:

  1. Cree o tome nota de una subred privada existente, que tiene una entrada de la tabla de enrutamiento para 0.0.0.0/0 a una puerta de enlace NAT.
    • Si aún no tiene una puerta de enlace NAT, una tabla de enrutamiento y la subred, como se especificó anteriormente, primero deberá crearlas y asociarlas entre sí de manera apropiada.
  2. Adjunte la función Lambda a las subredes privadas anteriores, cuando cree la función Lambda, o edite la función Lambda para tener esa configuración.

Si sigue estos dos pasos, debería poder invocar kms.encrypt y otras solicitudes desde su función Lambda, que requieren conectividad de Internet de salida / egreso, debido a que esos servicios no tienen puntos finales dentro de su VPC.


Las instancias de EC2 vienen con su propia IP pública de manera predeterminada, por lo que no tienen problemas para acceder a los servicios que requieren acceso a Internet (como KMS).

Las funciones Lambda adjuntas a su VPC no tienen una IP pública, por lo que para acceder a un servicio a través de Internet (como KMS), necesita una configuración de NAT tal como lo describe zealoushacker.


Para agregar a la excelente respuesta de zealoushacker, también debe verificar que la configuración del grupo de seguridad lambda tenga una regla de salida que apunte a 0.0.0.0 y cualquier puerto.

En nuestro caso, ya estábamos ejecutando en subredes privadas, pero teníamos grupos de seguridad restringidos a nuestra base de datos RDS.