脚本适用于 AWS EC2,但压缩后不适用于 AWS Lambda

Script works on AWS EC2, but not on AWS Lambda after zipping

我正在使用 M2Crypto 库创建一个简单的 AWS Lambda 函数。我遵循了从 here 创建部署包的步骤。 lambda 函数在 EC2 Linux 实例 (AMI) 上完美运行。

这是我的函数定义:

CloudOAuth.py

from M2Crypto import BIO, RSA, EVP
def verify(event, context):
  pem = "-----BEGIN PUBLIC KEY-----\n{0}\n-----END PUBLIC KEY-----".format("hello")
  bio = BIO.MemoryBuffer(str.encode(pem))
  print(bio)
  return 

部署包结构:

当我 运行 Lambda 时,出现以下问题,我还尝试从 /lib64 目录中包含 libcrypto.so.10,但没有帮助。

当 运行ning Lambda

时出现问题

/var/task/M2Crypto/_m2crypto.so: symbol sk_deep_copy, version libcrypto.so.10 not defined in file libcrypto.so.10 with link time reference`

Python: 2.7
M2Crypto: 0.27.0

我猜 M2Crypto 是使用与 Lambda 上不同版本的 OpenSSL 构建的。参见 the relevant code. If not (the upstream maintainer speaking here), please, file a bug at https://gitlab.com/m2crypto/m2crypto/issues

我只想在@mcepl 的回答中添加更多细节。最重要的是 AWS Lambda 上的 OpenSSL 版本和构建 M2Crypto 库的环境(在我的例子中是 ec2)应该匹配。

要检查 Lambda 上的 openssl 版本,请在您的处理程序中使用 print:

print(ssl.OPENSSL_VERSION)

要检查构建环境中的 openssl 版本,请使用:

$ openssl version

一旦它们匹配,它就起作用了。

不要犹豫,在您的构建环境中降级或升级 OpenSSL 以匹配 Lambda 环境。我不得不降级 ec2 上的 openssl 以匹配 lambda 运行时环境。

sudo yum -y downgrade openssl-devel-1.0.1k openssl-1.0.1k

希望它能帮助任何尝试使用 M2Crypto 的人:)

在此处复制 以解决类似问题:

AWS lambda runs code on an old version of amazon linux (amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2) as mentioned in the official documentation https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html

So to run a code that depends on shared libraries, it needs to be compiled in the same environment so it can link correctly.

What I usually do in such cases is that I create virtualenv using docker container. The virtualenv can than be packaged with lambda code.

Please note that if you need install anything using yum (in the docker container), you must use same release server as the amazon linux version:

yum --releasever=2017.03 install ...

virtualenv can be built using an EC2 instance as well instead of docker container (though, I find docker method easier). Just make sure that the AMI used for EC2 is same as the one used by lambda.