当我在NodeJS 11.7.0
上本地运行该功能时,当我在AWS Lambda NodeJS 8.10
中运行该功能时,但是我最近尝试在AWS Lambda NodeJS 10.x
中运行该功能并获得此响应以及Cloud Watch中的此错误。
关于如何更正此问题的任何想法?
回复
{
"success": false,
"error": "Error: Could not find openssl on your system on this path: openssl"
}
Cloudwatch错误
ERROR (node:8) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
功能
...
const util = require('util');
const pem = require('pem');
...
return new Promise((fulfill) => {
require('./certs').get(req, res, () => {
return fulfill();
});
}).then(() => {
const createCSR = util.promisify(pem.createCSR);
//This seems to be where the issue is coming from
return createCSR({
keyBitsize: 1024,
hash: HASH,
commonName: id.toString(),
country: 'US',
state: 'Maryland',
organization: 'ABC', //Obfuscated
organizationUnit: 'XYZ', //Obfuscated
});
}).then(({ csr, clientKey }) => {
...
}).then(async ({ certificate, clientKey }) => {
...
}, (err) => {
return res.status(404).json({
success: false,
error: err,
});
});
...
我尝试过
"pem": "^1.14.3",
和"pem": "^1.14.2",
答案 0 :(得分:6)
我尝试了@Kris White记录的answer,但无法使其正常工作。每次执行都会导致错误Could not find openssl on your system on this path: /opt/openssl
。我尝试了几种不同的途径和方法,但是都没有奏效。完全有可能我只是没有正确地复制OpenSSL可执行文件。
由于我需要一个可行的解决方案,因此我使用了@Wilfred Dittmer提供的answer。由于未使用Docker,因此对其进行了一些修改。我启动了Amazon Linux 2服务器,在其上构建了OpenSSL,将程序包转移到我的本地计算机上,并通过Serverless进行了部署。
创建一个包含以下内容的名为create-openssl-zip.sh
的文件。该脚本将创建Lambda Layer OpenSSL软件包。
#!/bin/bash -x
# This file should be copied to and run inside the /tmp folder
yum update -y
yum install autoconf bison gcc gcc-c++ libcurl-devel libxml2-devel -y
curl -sL http://www.openssl.org/source/openssl-1.1.1d.tar.gz | tar -xvz
cd openssl-1.1.1d
./config --prefix=/tmp/nodejs/openssl --openssldir=/tmp/nodejs/openssl && make && make install
cd /tmp
rm -rf nodejs/openssl/share nodejs/openssl/include
zip -r lambda-layer-openssl.zip nodejs
rm -rf nodejs openssl-1.1.1d
然后,请按照下列步骤操作:
curl -F "file=@create-openssl-zip.sh" https://file.io
curl
,您还可以使用File.io网站手动上传脚本。https://file.io/a1B2c3
tmp
导航到cd /tmp
目录。curl {FILE_IO_URL} --output create-openssl-zip.sh
下载先前上传的bash脚本。
FILE_IO_URL
替换为File.io返回并在步骤3中复制的URL。sudo bash ./create-openssl-zip.sh
执行bash脚本。该脚本可能需要一段时间才能完成。您可能需要确认一个或多个软件包安装提示。curl -F "file=@lambda-layer-openssl.zip" https://file.io
。curl {FILE_IO_URL} --output lambda-layer-openssl.zip
。
FILE_IO_URL
替换为File.io返回并在步骤13中复制的URL。curl
,您还可以通过将复制的URL粘贴到您喜欢的浏览器的地址栏中来手动下载文件。build-lambda-layer-openssl
EC2实例,因为不再需要它。为完整起见,这是我的serverless.yml
文件的一部分:
functions:
functionName:
# ...
layers:
- { Ref: OpensslLambdaLayer }
layers:
openssl:
name: ${self:provider.stage}-openssl
description: Contains openssl command line utility for lambdas that need it
package:
artifact: 'path\to\lambda-layer-openssl.zip'
compatibleRuntimes:
- nodejs10.x
- nodejs12.x
retain: false
...这是我在代码文件中配置PEM的方式:
import * as pem from 'pem';
process.env.LD_LIBRARY_PATH = '/opt/nodejs/openssl/lib';
pem.config({
pathOpenSSL: '/opt/nodejs/openssl/bin/openssl',
});
// other code...
答案 1 :(得分:1)
PEM NPM文档说:
设置openssl位置 在某些系统中,默认名称可能无法提供openssl可执行文件,或者它不包含在$ PATH中。在这种情况下,您可以在加载了pem模块之后将自己的可执行文件位置定义为一次性操作:
所以我认为它无法在系统中找到OpenSSL路径,您可以尝试以编程方式配置它:
#Replicate data frame
UserID <- c(1, 1, 1, 1, 2, 2)
SessionID <- c(1.1, 1.1, 1.1, 1.1, 2.1, 2.1)
TimeStamp <- c(1, 2, 3, 4, 5, 6)
PagePath <-
c(
"google.com",
"google.com/products",
"google.com/info",
"google.com/purchase",
"google.com",
"google.com/info"
)
PageViews <- c(1, 1, 1, 1, 1, 1)
df <- data.frame(UserID, SessionID, TimeStamp, PagePath, PageViews)
在使用AWS Lambda时,只需尝试打印var pem = require('pem')
pem.config({
pathOpenSSL: '/usr/local/bin/openssl'
})
,您将了解路径路径env变量中是否包含OpenSSL。
您还可以通过运行以下代码
来检查“ OpenSSL”process.env.path
更新
正如@hoangdv在他的答案中提到的openssl似乎已在node10.x运行时中删除,我认为他是对的。另外,我们对文件系统具有只读访问权限,因此我们无法做很多事情。
@Seth McClaine,您可以尝试使用const exec = require('child_process').exec;
exec('which openssl',function(err,stdopt,stderr){
console.log(err ? err : stdopt);
})
npm模块。在此基础上构建的模块之一是“ https://github.com/jfromaniello/selfsigned”,它将使您的任务更加轻松
答案 2 :(得分:1)
https://github.com/lambci/git-lambda-layer/issues/13#issue-444697784(公告电子邮件)
似乎openssl
已在nodejs10.x
运行时中删除。
我再次检查了lambci/lambda:build-nodejs10.x
码头工人镜像,并确认了这一点。也许您需要更改运行时版本或找到另一种createCSR
的方式。
which: no openssl in (/var/lang/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin)
答案 3 :(得分:0)
您可以做的是使用openssl库创建一个lambda层。 使用lambdaci / lambda:build-nodejes10.x,您可以编译openssl库并从安装中创建一个zip文件。然后,您可以将zip文件用作lambda的图层。
创建一个名为create-openssl-zip.sh
的文件,并确保将其chmod u + x。
#!/bin/bash -x
# This file should be run inside the lambci/lambda:build-nodejs10.x container
yum update -y
yum install autoconf bison gcc gcc-c++ libcurl-devel libxml2-devel -y
curl -sL http://www.openssl.org/source/openssl-1.1.1d.tar.gz | tar -xvz
cd openssl-1.1.1d
./config --prefix=/var/task/nodejs/openssl --openssldir=/var/task/nodejs/openssl && make && make install
cd /var/task/
rm -rf nodejs/openssl/share
rm -rf nodejs/openssl/include
zip -r lambda-openssl-layer.zip nodejs
cp lambda-openssl-layer.zip /opt/layer/
然后运行:
docker run -it -v `pwd`:/opt/layer lambci/lambda:build-nodejs10.x /opt/layer/create-openssl-zip.sh
这将在docker容器中运行脚本,完成后,您在当前目录中会有一个名为lambda-openssl-layer.zip
的文件。
将此lambda上载到s3存储桶并创建lambda层。 在原始的lambda上,添加此层并修改代码,以使PEM库知道在何处查找OpenSSL库,如下所示:
PEM.config({
pathOpenSSL: '/opt/nodejs/openssl/bin/openssl'
})
最后,将一个名为LD_LIBRARY_PATH
的额外环境变量添加到您的lambda中,其值为/opt/nodejs/openssl/lib
否则它将失败并显示:
/opt/nodejs/openssl/bin/openssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
答案 4 :(得分:0)
我联系了AWS支持有关此问题,结果发现openssl库仍在Node10x映像上,而不是命令行实用程序上。但是,将其从标准AMI上抓取并将其用作Lambda层是很容易的。
步骤:
process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'] + ':/opt';
该图层将为您解压缩,并且由于您事先将其设置为可执行文件,因此它应该可以正常工作。底层的openssl库在那里,因此只需复制cli就可以了。