使用psql以SSL模式连接到PostgreSQL


77

我正在尝试为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

是。这是配置的端口。
棒棒糖2012年

2
如果您想确保连接不受MITM攻击的侵害,请使用sslmode=verify-full,而不仅仅是require
布鲁诺

Answers:


111

psql 9.2以下的版本不接受选项的这种类似URL的语法。

可以通过sslmode=value命令行中的选项或PGSSLMODE环境变量来驱动SSL的使用,但是默认值为prefer,将首先自动尝试SSL连接而不指定任何内容。

带conninfo字符串的示例(已针对psql 8.4更新

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

阅读手册页以了解更多选项。


我从此链接获得了此连接字符串语法。 postgresql.org/docs/9.2/static/app-psql.html
棒棒糖2012年

2
我也尝试过您的选择, 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

@annonymous是指您已获得9.2文档的语法,但同时还表示您正在使用8.4版。8.4文档中未引用您所使用的内容。尝试也将“ sslmode = require”作为第一个参数。
布鲁诺

1
@布鲁诺:我错了。刚刚注意到文档中的版本差异。但是在第一个参数中仍然有它,我得到同样的警告。psql -h localhost "sslmode=require" -p 2345 -U thirunas -d postgres -f test_schema.ddl。警告psql: warning: extra command-line argument "sslmode=require" ignored
棒棒糖2012年

4
@Wave和其他遇到此问题的人,使用conninfo字符串代替数据库名称(-d)。您可以在-d选项之后或在命令行上将其作为第一个非选项参数来提供数据库名称。因此,-d postgres“ sslmode = require”应该是psql [options] -d“ dbname = postgres sslmode = require” [其他选项]或psql [options]“ dbname = postgres sslmode = require”。您可以将许多其他选项移到conninfo字符串中。
2015年

26
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

3
这是不正确的。--set=sslmode=require定义身份验证过程中根本不涉及的psql变量。它并没有强制SSL。
DanielVérité20年

6

发现以下选项可用于为自签名的postgres实例提供所有文件

psql "host={hostname} sslmode=prefer sslrootcert={ca-cert.pem} sslcert={client-cert.pem} sslkey={client-key.pem} port={port} user={user} dbname={db}"

3

在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
帕维尔Prażak

2

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

根据postgres psql文档,只有连接参数应该放在conninfo字符串中(这就是为什么在我们的示例中,--username不在该字符串内)


我起初也这么认为,但是在重新阅读了“连接数据库”部分后,我采取了另一种指定连接参数的方法是在conninfo字符串中,该字符串用于代替数据库名称。此机制使您可以非常广泛地控制连接。作为含义,您可以使用conninfo字符串中的任何参数。但是我也认为文档也可以在这里变得更加清晰。
奥斯汀


1

好吧,如果在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" 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.