Heroku Postgres:"psql: FATAL: no pg_hba.conf entry for host"

Heroku Postgres: "psql: FATAL: no pg_hba.conf entry for host"

有许多 Heroku CLI Postgres 命令都 return 相同的错误。例如:

$ heroku pg:bloat
psql: FATAL:  no pg_hba.conf entry for host "...", user "...", database "...", SSL off

这些命令中至少有一个在过去有效,但现在无效。

数据库在其他方面似乎工作正常。我可以通过我的应用程序界面访问它。

我没有看到在 Heroku Postgres 仪表板中切换 SSL 的方法。是什么原因造成的,我该如何解决?

您需要在连接字符串中设置 sslmode=require。当 JDBC 驱动程序为:

时的示例
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':' + dbUri.getPort() + 
dbUri.getPath() + "?sslmode=require";

您始终可以在配置变量中切换 ssl_mode,但我建议在连接字符串中进行切换。

该错误基本上表明您正在尝试在不使用 SSL 连接的情况下连接到数据库实例,但服务器设置为拒绝没有 SSL 连接的连接。

pg_hba.conf 文件驻留在服务器中,包含允许连接的详细信息。在您的情况下,在具有给定详细信息的文件中找不到匹配的记录(在非 SSL 连接下)。

您可以通过强制连接遵循 SSL 协议来解决此问题。正如 Raj 已经提到的,您需要修改连接字符串以包含 'sslmode=require'。 Here's 与此相关的 heroku 文档。查看文档中的 'external connections' 块。

事实证明,像 heroku pg:bloat 这样的命令在后台使用 Postgres 的本地安装和 psql。我使用 ssl 支持 (--with-openssl) 重新编译了我的 Postgres 安装,一切正常。

我认为在 Heroku 上 SSL 不是 disabled 而是 require,这可能是这个错误的原因。

我在从外部应用程序连接到 Postgres 时遇到错误。该修复与您使用的语言有关。在 Java 你需要链接 ?sslmode=require 来查询字符串,在 NodeJS (我的情况)你应该添加 rejectUnauthorized: false 如下 -

const client = new Client({
  connectionString: process.env.DATABASE_URL,
  ssl: {
    rejectUnauthorized: false
  }
});

参考https://devcenter.heroku.com/articles/heroku-postgresql了解更多详情。

Enjoy!

这有助于解决我的问题。添加 ssl 属性 in config.json (Sequelize)

{
  "production": {
    "ssl": {
      "require": true,
      "rejectUnauthorized": false
    },
  }
}

在数据库配置中添加 ssl option 在我这边解决了这个问题:

如果您使用 sequelize 作为 ORM

const config = {
  ...
  production: {
    use_env_variable: 'DATABASE_URL',
    dialect: 'postgresql',
    logging: false,
        dialectOptions: {
      ssl: {      /* <----- Add SSL option */
        require: true,
        rejectUnauthorized: false 
      }
    },
  },
  ...
}

如果您没有使用任何 ORM:

const pool = new Pool({
  connectionString:DATABASE_URL ,
  ssl: {    /* <----- Add SSL option */
    rejectUnauthorized: false,
  },
});

我通过在 Heroku 上设置 PGSSLMODE 来解决它。这告诉 Postres 默认使用 SSL。在命令行上,这可以通过以下命令完成。

heroku config:set PGSSLMODE=require

这适用于 Nodejs。指定 PGSSLMODE 配置变量:heroku config:set PGSSLMODE=no-verify 你可以通过带有 Heroku CLI 的终端来完成。

中所述,设置 rejectUnauthorized: false 是个坏主意,因为它允许您创建与数据库的非加密连接,因此可能使您暴露于 MITM 攻击(人-中间攻击)。

更好的解决方案是为您的 Postgre 客户端提供您希望它使用的 CA。在您的情况下,它可能是 Heroku CA,但在我的情况下,它是 AWS RDS 在北弗吉尼亚地区 (us-east-1) 使用的 CA。我从 this AWS page 下载了 CA,将它放在与我想用来创建连接的文件相同的目录中,然后将我的配置修改为:

{
  ...
  dialectOptions: {
    ssl: {
      require: true,
      ca: fs.readFileSync(`${__dirname}/us-east-1-bundle.pem`),
    },
  },
}