【问题标题】:SSL for PostgreSQL connection nodejs用于 PostgreSQL 连接 nodejs 的 SSL
【发布时间】:2014-04-13 15:33:10
【问题描述】:

我正在尝试连接到我的 Heroku PostgreSQL 数据库,但我不断收到 SSL 错误。有谁知道如何在连接字符串中启用 SSL?

postgres://user:pass@host:port/database;

到处都在寻找它,但它似乎不是一个非常受欢迎的话题。 顺便说一句,我正在运行 Nodejs 和 node-pg 模块及其连接池方法:

pg.connect(connString, function(err, client, done) {
  // Should work.
});

非常感谢您的评论。

【问题讨论】:

  • 添加ssl=true 作为URL 查询参数,如postgres://user:pass@host:port/database?ssl=true

标签: node.js postgresql ssl node-postgres


【解决方案1】:

你可以这样实现:

postgres://user:pass@host:port/database?ssl=true

【讨论】:

  • 执行此操作时出现以下错误 - The server does not support SSL connections。但是psql "sslmode=require" 有效。因此,我倾向于认为正在使用的"pg": "^4.3.0" npm 包有问题。有什么想法吗?
  • 如果我是正确的,pass 代表密码。那么如果我们在这里用纯文本写密码,那么密码有什么意义呢?无论如何,在这些连接字符串中以纯文本形式写入密码是多么合乎逻辑?
  • 这样的连接字符串通常以与任何其他机密相同的安全方式存储,因为正如您所指出的,它包含密码。在 Heroku 中,像这样的连接字符串是作为环境变量出现的。在某些时候,密码必须是明文才能被机器使用,但你绝对不想将它检查到源代码控制或类似的东西中。
【解决方案2】:

您也可以在从node-postgres 创建新客户端时使用以下代码:

var pg = require("pg");

var client = new pg.Client({
  user: "yourUser",
  password: "yourPass",
  database: "yourDatabase",
  port: 5432,
  host: "host.com",
  ssl: true
});

client.connect();

var query = client.query('CREATE TABLE people(id SERIAL PRIMARY KEY, name VARCHAR(100) not null)');

query.on('row', function(row) {
  console.log(row.name);
});

query.on('end', client.end.bind(client));

希望这会有所帮助!

【讨论】:

  • 我采纳了您的建议并添加了 ssl: true 属性。就这么简单吗?我如何确保我现在与数据库的连接确实安全?
  • 感谢您的帮助。我试图使用 pd_ident.conf 映射将我的用户名映射到 postgres 用户名,但我所要做的就是在客户端配置对象中显式添加用户。
【解决方案3】:

使用 Google Cloud PG 和 pg-promise 我也有类似的需求。 我得到的错误(使用?ssl=true)是connection requires a valid client certificate

没有记录pg-promise 的 SSL 连接,但它是基于 node-postgres 构建的。如链接中所述,ssl 配置参数可以不仅仅是true

const pgp = require('pg-promise')();
const fs = require('fs');

const connectionConf = {
    host: 'myhost.com',
    port: 5432,
    database: 'specific_db_name',
    user: 'my_App_user',
    password: 'aSecretePass',
    ssl: {
        rejectUnauthorized : false,
        ca   : fs.readFileSync("server-ca.pem").toString(),
        key  : fs.readFileSync("client-key.pem").toString(),
        cert : fs.readFileSync("client-cert.pem").toString(),
  }

};
const new_db = pgp(connectionConf);
new_db.any('SELECT * FROM interesting_table_a LIMIT 10')
    .then(res => {console.log(res);})
    .catch(err => {console.error(err);})
    .then(() => {new_db.$pool.end()});

【讨论】:

  • SSL 通过声明记录在 pg-promise 中,如果您使用的是 TypeScript ;) 请参阅类型 TConnectionParameters,它使用 TSSLConfig 进行 SSL 配置。使用 TypeScript 的美妙之处,呵呵,你可以更轻松地发现支持的东西 ;)
  • 如果有人想知道 ca 连接适用于 aws rds postgres db 和 knexjs,readFileSync 是必不可少的,其他解决方案说可以只使用 url 作为 url:postgres://[db-username ]:[your db password]@[endpoint]:[your db port number]/[db name]?sslca=config/amazon-rds-ca-cert.pem&sslmode=required 但您的证书路径似乎没有被读取以某种方式。
【解决方案4】:

对于寻找 TypeORM 解决方案的任何人,它也是 {ssl: true}

完整示例:

const connectionOptions: PostgresConnectionOptions = {
    name: `default`,
    type: `postgres`,
    url: process.env.DATABASE_URL,
    ssl: process.env.DATABASE_SSL === `true`
}

【讨论】:

    【解决方案5】:

    我也有同样的问题。 至于今天,pg >= 8.0.0有问题。 因此,如果您遇到此问题,请使用 pg 版本 7 及以下版本。

    yarn add pg@7
    

    【讨论】:

    • 带有 pg7 的弃用消息 - (node:42432) DeprecationWarning: 隐式禁用证书验证已被弃用,并将在 pg 8 中删除。指定 rejectUnauthorized: true 以要求有效的 CA 或 rejectUnauthorized: false 明确选择退出 MITM 保护。
    【解决方案6】:

    您还可以使用环境变量来设置连接。这是一个例子。

    (假设您有一个 Postgres DB 在端口 5432@localhost 上运行并且该 DB 支持 SSL 连接)

    .env

    PGHOST=localhost
    PGPORT=5432
    PGDATABASE=mydb
    PGUSER=pguser1
    PGPASSWORD=mypassword
    PGSSLMODE=require
    

    (确保将PGSSLMODE 设置为require,如上所示。)

    db.js

    require('dotenv').config()
    const { Pool } = require('pg')
    
    // pools will use environment variables for connection information
    const pool = new Pool()
    // const pool = new Pool({ ssl: true }); This works too in the absence of PGSSLMODE
    pool.on('error', function (err) {
        console.log('idle client error', err.message, err.stack)
    })
    
    module.exports = {
        pool,
        query: (text, params, callback) => {
            return pool.query(text, params, callback)
        }
    }
    

    server.js

    const express = require('express')
    const { pool } = require('./db')
    
    const app = express()
    const port = 3000
    
    app.get('/', async (req, res) => {
      console.log('Request received...')
      const result = await pool.query(`SELECT * FROM organization`);
      res.send(result)
    })
    
    app.listen(port, () => console.log(`Example app listening on port ${port}!`))
    

    注意:如果您的 Postgres 数据库不支持 SSL 连接,当您的应用程序尝试进​​行查询时,您将遇到以下错误:

    Error: The server does not support SSL connections
    at Socket.<anonymous> (node_modules/pg/lib/connection.js:87:35)
    

    参考资料:

    【讨论】:

      【解决方案7】:

      如果以上都不起作用。

      考虑我的情况,以前工作过,最近换过工作站 - 突然不再工作并出现上述错误。

      原因是我克隆了一个 GitHub 存储库(我自己的),它在切换计算机后调用了私有变量。 repo 没有.env 文件(显然),其中包含数据库连接字符串以及许多其他变量。因此,在我在本地创建 .env 文件之前,我在代码中对它的调用不再有效。

      TLDR

      // database_config.js
      const { Client } = require("pg");
      const client = new Client({
        connectionString: process.env.DATABASE_CONNECTION, // <--- not defined without .env file definition
        ssl: {
          rejectUnauthorized: false,
        },
      });
      
      client
      .connect()
      .then(() => console.log("connected to database"))
      .catch((err) => console.error(err));
      
      module.exports = client;
      

      解决方案

      // .env
      DATABASE_CONNECTION = your_connection_string
      

      【讨论】:

        【解决方案8】:
        const sequelize = new Sequelize(
            configuration.get("postgresConnectionString"),
            {
                logging: false,
                dialectOptions: {
                    ssl: {
                        ca: fs.readFileSync(path.join(__dirname, "/ssl/DigiCertGlobalRootG2.crt.pem")),
                        rejectUnauthorized: true,
                        require: true,
                    },
                },
            },
        );
        

        DigiCertGlobalRootG2.crt.pem:是选区的 2 个密钥的组合(BaltimoreCyber​​TrustRoot.crt.pem 即将到期)。一个具有多个密钥的文件 ----- 开始证书 ----- 巴尔的摩Cyber​​TrustRoot.crt.pem ----- 结束证书 ----- ----- 开始证书 ----- DigiCertGlobalRootG2.crt.pem -----结束证书----- 使用支持 SSL 的 Sequelize ORM 从 node.js 应用程序连接到 Azure postgress。
        DigiCertGlobalRootG2.crt.pem:你会从Azure portal得到它。

        注意:如果不使用任何密钥,则 ssl 配置如下:

        const sequelize = new Sequelize(
            configuration.get("postgresConnectionString"),
            {
                logging: false,
                dialectOptions: {
                    ssl: true,
                },
            },
        );
        

        注意:请检查connectionStringsslmode=require|| ssl_ca=required: https://docs.microsoft.com/en-us/azure/mysql/concepts-certificate-rotation结尾,基于此,请相应添加SSL配置 注:您觉得需要更改的内容,请告诉我

        【讨论】:

          猜你喜欢
          • 2016-12-24
          • 2023-01-29
          • 1970-01-01
          • 1970-01-01
          • 2019-06-12
          • 1970-01-01
          • 2012-12-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多