Heroku Postgres:“psql:致命:主机没有 pg_hba.conf 条目”

Posted

技术标签:

【中文标题】Heroku Postgres:“psql:致命:主机没有 pg_hba.conf 条目”【英文标题】:Heroku Postgres: "psql: FATAL: no pg_hba.conf entry for host" 【发布时间】:2020-05-19 18:23:40 【问题描述】:

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

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

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

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

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

【问题讨论】:

【参考方案1】:

我从外部应用程序连接到 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。

享受吧!

【讨论】:

【参考方案2】:

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

heroku config:set PGSSLMODE=require

【讨论】:

这导致我出现错误“错误:自签名证书”有什么想法吗?【参考方案3】:

您需要在连接字符串中设置sslmode=require。 JDBC驱动时的一个例子:

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

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

【讨论】:

【参考方案4】:

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

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

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

【讨论】:

我无法将字符串传递给 Heroku 命令,尽管当我将连接字符串传递给本地 psql 命令时确实解决了问题。【参考方案5】:

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

【讨论】:

使用 asdf-vm 安装 Postgres 时,可以添加一个文件 ~/.asdf-postgres-configure-options,其内容为 export POSTGRES_EXTRA_CONFIGURE_OPTIONS="--with-openssl"。这将在asdf install 期间使用。见here。【参考方案6】:

在数据库配置中添加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,
  ,
);

【讨论】:

【参考方案7】:

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

【讨论】:

【参考方案8】:

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

【讨论】:

【参考方案9】:

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


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

【讨论】:

【参考方案10】:

正如this related answer 中所解释的,设置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`),
    ,
  ,

【讨论】:

以上是关于Heroku Postgres:“psql:致命:主机没有 pg_hba.conf 条目”的主要内容,如果未能解决你的问题,请参考以下文章

psql:致命:用户“postgres”的身份验证失败

psql:致命:用户的 PAM 身份验证失败

psql:致命:用户 windows 8 的密码验证失败

psql:致命:数据库“<用户>”不存在

psql: 致命错误: 用户 "ASUS" Password 认证失败

psql: 致命错误: 对用户"user1"的对等认证失败