使用psql连接到启用了SSL模式的PostgreSQL

132

我正在尝试为PostgreSQL服务器配置ssl证书。我在数据目录中创建了一个证书文件(server.crt)和密钥(server.key),并更新SSL参数为"on"以启用安全连接。

我只想要服务器在客户端上通过服务器证书进行身份验证,而不需要在服务器端验证客户端的真实性。我使用psql作为客户端连接并执行命令。

我正在使用PostgreSQL 8.4和Linux。我尝试使用以下命令连接启用了SSL的服务器:

       psql "postgresql://localhost:2345/postgres?sslmode=require"

但是我正在变得

       psql: invalid connection option "postgresql://localhost:2345/postgres?sslmode"

我在这里做错了什么?我尝试启用SSL模式连接服务器的方式正确吗?仅对服务器进行身份验证而不验证客户端是否可以接受吗?


打算使用端口2345而不是默认的5432端口吗? - Erwin Brandstetter
是的,这是已配置的端口。 - Lolly
4
еҰӮжһңжӮЁеёҢжңӣиҝһжҺҘе…ҚеҸ—дёӯй—ҙдәәж”»еҮ»пјҢиҜ·дҪҝз”Ёsslmode=verify-fullиҖҢдёҚжҳҜд»…дҪҝз”ЁrequireгҖӮ - Bruno
9个回答

159

psql 版本低于9.2时不接受此类URL语法的选项。

使用SSL可以通过命令行上的 sslmode=value 选项或PGSSLMODE 环境变量来实现,但默认情况下为 prefer,将自动首先尝试SSL连接而不需要指定任何内容。

连接信息字符串示例(更新至psql 8.4

psql "sslmode=require host=localhost dbname=test"

阅读手册页面以获取更多选项。


我从这个链接中得到了这个连接字符串的语法。http://www.postgresql.org/docs/9.2/static/app-psql.html - Lolly
5
我也试过你给的选项了,命令是psql -h localhost -p 2345 -U thirunas -d postgres "sslmode=require" -f test_schema.ddl,但它显示出警告信息:sql: warning: extra command-line argument "sslmode=require" ignored - Lolly
2
@Bruno:我发现错误了。刚注意到文档版本的不同之处。但是即使仍然在第一个参数中,我也收到相同的警告。psql -h localhost "sslmode=require" -p 2345 -U thirunas -d postgres -f test_schema.ddl。警告:psql: warning: extra command-line argument "sslmode=require" ignored - Lolly
@annonymous:更新答案,仅使用可被 psql 8.4 接受的语法格式的 conninfo 字符串。 - Daniel Vérité
10
@Wave 和其他遇到这个问题的人,连接信息字符串(conninfo string) 代替了数据库名称 (-d)。你可以在 -d 选项后给出数据库名称,或将其作为命令行中第一个非选项参数。因此,"-d postgres“和"sslmode=require"应该被替换成 "dbname=postgres sslmode=require" 并放在psql [options]后面作为另一个选项,或者放在“psql [options] dbname=postgres sslmode=require”的命令中。许多其他选项也可以移动到conninfo字符串中。 - jla
显示剩余4条评论

39
psql --set=sslmode=require -h localhost -p 2345 -U thirunas \
-d postgres -f test_schema.ddl

另一个连接到Azure托管的Postgres数据库的安全示例:

psql --file=product_data.sql --host=hostname.postgres.database.azure.com --port=5432 \
--username=postgres@postgres-esprit --dbname=product_data \
--set=sslmode=verify-full --set=sslrootcert=/opt/ssl/BaltimoreCyberTrustRoot.crt.pem

15
这是不正确的。 --set=sslmode=require 定义了一个psql变量,在认证过程中根本没有涉及到它。它对于强制使用SSL什么也没做。 - Daniel Vérité
4
我可以确认,正如@DanielVérité所指出的那样,这并不起作用。使用具有不受信任证书的postgres服务器,并使用--set=sslmode=verify-full进行测试将不会发出警告。 - LEDfan

15

如果连接需要在SSL模式下进行,您可以使用以下CLI命令提供所有信息:

psql "sslmode=verify-ca sslrootcert=server-ca.pem sslcert=client-cert.pem sslkey=client-key.pem hostaddr=your_host port=5432 user=your_user dbname=your_db" 

这是Google Cloud推荐的方法,我可以确认它有效。来源:https://cloud.google.com/sql/docs/postgres/connect-admin-ip#connect-ssl - Elouan Keryell-Even
1
是的,它有效,当时谷歌没有这个建议,他们从我这里偷了过去:D只是开个玩笑)) - Sabuhi Shukurov
你是真正的MVP,Google请给这个人一个饼干!❤ - Elouan Keryell-Even
我不得不使用“host”而不是“hostaddr”,但除此之外,一切都很顺利。在我看来,这应该是被接受的答案。 - Tobias Gierke

11

在psql客户端v12中,我无法找到psql客户端中激活sslmode=verify-full选项的选项。

最终我使用了环境变量:

PGSSLMODE=verify-full PGSSLROOTCERT=server-ca.pem psql -h your_host -U your_user -W -d your_db

1
对于TLS认证,您还需要:PGSSLCERTPGSSLKEY,并且删除-W - Paweł Prażak
-W 避免了一次无用的连接尝试。请参阅文档并搜索 -W: `-W = --password ... psql将浪费一次连接尝试以确定服务器需要密码。在某些情况下,输入 -W 值得避免额外的连接尝试。 - questionto42
我可以确认在Ubuntu上,使用psql 13.4时,会得到以下警告信息:psql: warning: extra command-line argument "sslrootcert=ca.pem" ignored和psql: warning: extra command-line argument "sslmode=verify-full" ignored。另外一件事:加载的证书可以保持几分钟,您不需要再次加载。但是长时间后,我必须重新加载pem文件,否则我会收到以下错误:'psql: error: FATAL: password authentication failed for user "USER" FATAL: no pg_hba.conf entry for host "11.222.33.444", user "USER", database "db", SSL off'。通过使用环境变量,可以避免这个错误。 - questionto42

10
发现以下选项对于为自签名的Postgres实例提供所有文件非常有用:
psql "host={hostname} sslmode=prefer sslrootcert={ca-cert.pem} sslcert={client-cert.pem} sslkey={client-key.pem} port={port} user={user} dbname={db}"

4
根据Postgres PSQL文档,只有连接参数应该放在连接信息字符串中(这就是为什么在我们的示例中--username不在该字符串中的原因)。 使用以下命令连接到Postgres数据库:

psql "sslmode=require host=localhost port=2345 dbname=postgres" --username=some_user


我最初也是这么想的,但在重新阅读连接数据库部分后,我认为“另一种指定连接参数的方法是使用conninfo字符串,该字符串代替数据库名称使用。这种机制使您对连接具有非常广泛的控制能力。”的意思是您可以将任何参数放入“conninfo”字符串中。但我也认为文档在这里可以更加清晰明了。 - Austin A

4

在v8中有效的另一种模式是:

psql -h 主机名 -p 端口号 -U 用户名 "dbname=db sslmode=require"


3

1
您可以尝试将以下内容添加到连接字符串中:"Persist Security Info=True;SSL Mode=Require"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接