有许多 Heroku CLI Postgres 命令都返回相同的错误。例如:
$ heroku pg:bloat
psql: FATAL: no pg_hba.conf entry for host "...", user "...", database "...", SSL off
这些命令中至少有一个在过去有效,但现在不起作用。
否则,数据库似乎工作正常。我可以通过我的应用程序的界面访问它。
我没有看到在Heroku Postgres仪表板中切换SSL的方法。可能导致此问题的原因是什么,我该如何解决?
从外部应用程序连接到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。
享受!
我通过在 Heroku 上设置 PGSSLMODE 来解决它。 这告诉Postres默认为SSL。 在命令行上,这可以通过以下命令完成。
heroku config:set PGSSLMODE=require
该错误基本上表示您正在尝试在不使用 SSL 连接的情况下连接到数据库实例,但服务器设置为拒绝没有 SSL 连接的连接。
pg_hba.conf 文件驻留在服务器中,并包含允许的连接的详细信息。在您的情况下,在文件中找不到具有给定详细信息的匹配记录(在非 SSL 连接下(。
您可以通过强制连接遵循 SSL 协议来解决此问题。正如 Raj 已经提到的,您需要修改连接字符串以包含"sslmode=require"。这是关于相同的 heroku 文档。查看文档中的"外部连接"块。
在数据库配置中添加ssl option
解决了这个问题:
如果您使用续集作为您的 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,
},
});
您需要在连接字符串中设置sslmode=require
。当 JDBC 驱动程序为:
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':' + dbUri.getPort() +
dbUri.getPath() + "?sslmode=require";
您始终可以在配置变量中切换ssl_mode
,但我建议在连接字符串中执行此操作。
这适用于Nodejs。指定 PGSSLMODE config var:heroku config:set PGSSLMODE=no-verify 您可以通过带有 HerokuCLI 的终端执行此操作。
事实证明,像heroku pg:bloat
这样的命令使用 Postgres 的本地安装,并在后台psql
。我在 ssl 支持 (--with-openssl
( 下重新编译了我的 Postgres 安装,一切正常。
我认为在 Heroku 上 SSL 不是disabled
而是require
,这可能是此错误的原因。
这有助于解决我的问题。在 config.json 中添加ssl属性(续集(
{
"production": {
"ssl": {
"require": true,
"rejectUnauthorized": false
},
}
}
正如这个相关答案中所解释的,设置rejectUnauthorized: false
是一个坏主意,因为它允许您创建与数据库的非加密连接,从而可能使您暴露在 MITM 攻击(中间人攻击(中
。更好的解决方案是为您的 Postgre 客户端提供您希望它使用的 CA。在您的情况下,它可能是 Heroku CA,但在我的情况下,它是 AWS RDS 用于北弗吉尼亚区域 (us-east-1( 的 CA。我从此 AWS 页面下载了 CA,将其放在与我要用于创建连接的文件相同的目录中,然后将我的配置修改为:
{
...
dialectOptions: {
ssl: {
require: true,
ca: fs.readFileSync(`${__dirname}/us-east-1-bundle.pem`),
},
},
}
如果您使用Sequelize作为ORM,这是解决此问题所需的连接的配置。编辑数据库文件 (db.js(:正如 Heroku 在此回答中所解释的那样。
var connection = process.env.DATABASE_URL
isProduction ? connection : connection = connectionString;
const sequelize = new Sequelize(connection,{
logging: false, //Loging disabled
dialectOptions: {
ssl:{
require:true,
rejectUnauthorized: false
}
}
});
try {
sequelize.authenticate();
console.log('Database connected successfully!');
} catch (error) {
console.error('Unable to connect to the database:', error);
}
还要编辑您的 config.json 文件,如此处所述
将?sslmode=require
附加到连接 URL 对我有用。