我正在尝试使用NodeJS lambda连接到Amazon PostgreSQL RDS。
Lambda与RDS实例位于同一VPC中,据我所知,安全组已设置为允许Lambda访问RDS。 lambda是通过API网关调用的,而我使用的是knex js作为查询生成器。当lambda尝试连接到数据库时,它将引发“无法获取本地发行者证书”错误,但是连接参数正是我期望的参数。
我知道这种连接是可能的,因为我已经在其他环境中实现了该连接,而没有收到证书问题。我已经比较了两种环境,但找不到立即的区别。
连接代码如下:
import AWS from 'aws-sdk';
import { types } from 'pg';
import { Moment } from 'moment';
import knex from 'knex';
const TIMESTAMP_OID = 1114;
// Example value string: "2018-10-04 12:30:21.199"
types.setTypeParser(TIMESTAMP_OID, (value) => value && new Date(`${value}+00`));
export default class Database {
/**
* Gets the connection information through AWS Secrets Manager
*/
static getConnection = async () => {
const client = new AWS.SecretsManager({
region: '<region>',
});
if (process.env.databaseSecret == null) {
throw 'Database secret not defined';
}
const response = await client
.getSecretValue({ SecretId: process.env.databaseSecret })
.promise();
if (response.SecretString == undefined) {
throw 'Cannot find secret string';
}
return JSON.parse(response.SecretString);
};
static knexConnection = knex({
client: 'postgres',
connection: async () => {
const secret = await Database.getConnection();
return {
host: secret.host,
port: secret.port,
user: secret.username,
password: secret.password,
database: secret.dbname,
ssl: true,
};
},
});
}
任何有关如何解决此问题甚至从何处着手的指导都将不胜感激。
答案 0 :(得分:0)
我知道这很旧,但今天刚遇到这个。使用节点 10 和旧版本的 pg 库运行效果很好。使用 pg 版本 8.x 更新到节点 16 导致此错误(已简化):
<块引用>UNABLE_TO_GET_ISSUER_CERT_LOCALLY
在过去,您确实可以将 ssl
参数设置为 true
或 'true'
,它会与默认的 AWS RDS 证书一起使用。现在,看来我们至少需要告诉 node/pg 忽略证书验证(因为它是自己生成的)。
使用 ssl: 'no-verify'
有效,启用 ssl 并告诉 pg 忽略证书链的验证。
答案 1 :(得分:0)
首先,绕过 ssl 验证不是一个好主意,这样做会使您容易受到中间人攻击并跳过 TLS 握手中的关键步骤.
您可以做的是以编程方式从 Amazon 下载 ca 证书链包,并将其放置在 lambda 的根目录中,与处理程序一起放置。
wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem -P path/to/handler
注意:您可以在 buildspec.yaml 或打包上传到 aws 的 zip 文件的脚本中执行此操作
然后在你的代码postgres客户端配置中将ssl配置选项设置为pem文件的内容,像这样:
let pgClient = new postgres.Client({
user: 'postgres',
host: 'rds-cluster.cluster-abc.us-west-2.rds.amazonaws.com',
database: 'mydatabase',
password: 'postgres',
port: 5432,
ssl: {
ca: fs.readFileSync(path.resolve('rds-combined-ca-bundle.pem'), "utf-8")
}
})