You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js无法与AWS RDS建立TLS连接问题求助

Node.js连接AWS RDS PostgreSQL报错:自签名证书链问题

问题详情

我用Node.js的pg库尝试连接AWS RDS PostgreSQL实例,代码如下:

const { Client } = require('pg')

const client = new Client({
  client: 'postgresql',
  connectionString: process.env.DATABASE_URL,
  ssl: { 
    rejectUnauthorized: true,
  },
})

client.connect((err) => {
  if (err) {
    console.error('connection error', err.stack)
  } else {
    console.log('connected')
  }
})

设置的环境变量:

export DATABASE_URL=postgres://myuser:mypassword@myrds.123456789.us-east-1.rds.amazonaws.com/postgres?ssl=true

连接失败,报错信息:

connection error Error: self signed certificate in certificate chain
    at TLSSocket.onConnectSecure (_tls_wrap.js:1497:34)
    at TLSSocket.emit (events.js:315:20)
    at TLSSocket._finishInit (_tls_wrap.js:932:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:706:12)

我本地用psql命令通过同一个URL能成功连接,而且RDS使用的是AWS信任的CA机构,系统已经信任该机构。我当前使用的是Node.js 14.16版本和pg@8.9版本。

已尝试的操作

根据AWS官方文档,我下载了全局CA证书包,修改代码后仍然报同样的错误:

const { Client } = require('pg')
const fs = require('fs')

const client = new Client({
  client: 'postgresql',
  connectionString: process.env.DATABASE_URL,
  ssl: { 
    rejectUnauthorized: true,
    ca: fs.readFileSync('global-bundle.pem').toString(),
  },
})

client.connect((err) => {
  if (err) {
    console.error('connection error', err.stack)
  } else {
    console.log('connected')
  }
})

解决方案

1. 移除多余的client配置项

pg库的Client构造函数并不需要client: 'postgresql'这个配置参数,这个多余字段会干扰配置的正确解析,导致SSL配置无法生效。移除后重新尝试连接。

2. 确保CA证书路径正确

确认global-bundle.pem文件的路径是否正确:

  • 如果用相对路径,确保文件在Node.js进程的当前工作目录下;
  • 建议用绝对路径避免解析问题,示例:
    ca: fs.readFileSync('/绝对路径/global-bundle.pem').toString()
    

3. 统一SSL配置方式

连接字符串中的?ssl=true会和代码中的ssl对象配置冲突,建议只保留一种配置方式:

  • 要么移除连接字符串中的ssl=true,完全依赖代码里的ssl对象配置;
  • 要么在连接字符串中指定CA证书,但更推荐代码中显式配置SSL参数。

修正后的代码示例

const { Client } = require('pg')
const fs = require('fs')
const path = require('path')

const client = new Client({
  connectionString: process.env.DATABASE_URL.replace('?ssl=true', ''), // 移除连接字符串中的ssl参数
  ssl: { 
    rejectUnauthorized: true,
    ca: fs.readFileSync(path.resolve(__dirname, 'global-bundle.pem')).toString(), // 使用绝对路径
  },
})

client.connect((err) => {
  if (err) {
    console.error('connection error', err.stack)
  } else {
    console.log('connected')
  }
})

额外说明

Node.js有独立的根CA存储,和系统信任存储不完全一致。即使系统已信任AWS的CA机构,Node.js可能无法自动识别,因此必须显式指定CA证书才能完成SSL验证。


内容的提问来源于stack exchange,提问作者pkaramol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 05:25:29