pg-connect-simple报自签名证书链错误,Fastify部署DO托管PG如何安全解决
问题根因
这个报错是因为DigitalOcean托管的PostgreSQL实例默认使用自签名SSL证书,connect-pg-simple底层依赖pg(node-postgres)库进行数据库连接,默认会对SSL证书链进行合法性校验,因为无法信任DO的自签名证书所以抛出错误。你之前设置的NODE_TLS_REJECT_UNAUTHORIZED = 0是直接关闭了所有SSL证书校验,确实存在严重的中间人攻击风险,生产环境绝对不能使用。
安全解决步骤
第一步:获取DigitalOcean Postgres的根CA证书
- 登录DigitalOcean控制台,进入你使用的托管PostgreSQL实例详情页
- 在【Connection Details】区域找到「Download CA certificate」按钮,下载根证书文件(通常命名为
ca-certificate.crt) - 将下载的证书文件上传到你的DO Droplet服务器,建议放到系统证书目录,比如
/etc/ssl/certs/do-postgres-ca.crt,确保运行Node服务的用户对该文件有读取权限
第二步:修改session配置,显式指定可信CA证书
你需要给pgSession传入包含正确SSL配置的数据库连接参数,指定使用DO的根证书进行校验,不需要关闭证书校验。修改后的代码如下:
const fs = require('fs'); const cookie = require('fastify-cookie'); const session = require('@fastify/session'); const csrf = require('fastify-csrf'); const pgSession = require('connect-pg-simple')(session); const fp = require('fastify-plugin'); const plugin = async (fastify) => { fastify.register(cookie); fastify.register(csrf, { sessionPlugin: 'fastify-session' }); // 构建pg连接配置,分环境处理SSL const pgConfig = { connectionString: process.env.DATABASE_URL, // 你的Postgres连接串,建议存在环境变量中 tableName: 'user_session', }; // 生产环境添加SSL配置 if (process.env.NODE_ENV !== 'development') { pgConfig.ssl = { // 读取DO的根CA证书内容 ca: fs.readFileSync('/etc/ssl/certs/do-postgres-ca.crt').toString(), // 不要设置rejectUnauthorized: false,保持证书校验开启 }; } fastify.register(session, { store: new pgSession(pgConfig), secret: process.env.SESSION_SECRET, saveUninitialized: false, cookie: { httpOnly: true, secure: process.env.NODE_ENV !== 'development', maxAge: 86400 * 1000, // 1天有效期 }, }); fastify.addHook('preHandler', (req, reply, next) => { if (!req.session) req.session.user = {}; next(); }); }; module.exports = fp(plugin);
可选优化
如果不想在服务器上单独存放证书文件,也可以将证书内容base64编码后存入环境变量,代码中直接读取解码即可:
// 环境变量DO_POSTGRES_CA存储base64编码后的证书内容 ca: Buffer.from(process.env.DO_POSTGRES_CA, 'base64').toString()
如果你的Fastify应用其他业务逻辑也用到了同一个Postgres数据库,建议把pg连接配置统一抽离成公共模块,避免业务连接和session连接的SSL配置不一致导致其他报错。
内容的提问来源于stack exchange,提问作者user616
相关产品推荐
相关产品推荐

