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

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证书

  1. 登录DigitalOcean控制台,进入你使用的托管PostgreSQL实例详情页
  2. 在【Connection Details】区域找到「Download CA certificate」按钮,下载根证书文件(通常命名为ca-certificate.crt)
  3. 将下载的证书文件上传到你的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 16:57:02