【问题标题】:Using psql to connect to PostgreSQL in SSL modeSSL模式下使用psql连接PostgreSQL
【发布时间】:2012-12-10 21:56:38
【问题描述】:

我正在尝试为 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?
  • 是的。这是配置的端口。
  • 如果您希望连接安全免受 MITM 攻击,请使用sslmode=verify-full,而不仅仅是require

标签: postgresql ssl ssl-certificate postgresql-8.4


【解决方案1】:

另一个适用于 v8 的模式是

psql -h host_name -p port -U user_name "dbname=db sslmode=require"

【讨论】:

    【解决方案2】:

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

    我最终使用了环境变量:

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

    【讨论】:

    • 对于 TLS 身份验证,您还需要:PGSSLCERTPGSSLKEY 并删除 -W
    • -W 避免了一次未使用的连接尝试。查看docs 并搜索-W-W = --password ... psql will waste a connection attempt finding out that the server wants a password. In some cases it is worth typing -W to avoid the extra connection attempt.
    • 我可以确认在 Ubuntu 上,使用 psql 13.4,我得到 psql: warning: extra command-line argument "sslrootcert=ca.pem" 被忽略和 psql: warning: extra command-line argument "sslmode =verify-full" 被忽略。另一件事:加载的证书可以保存几分钟,您不需要一次又一次。但经过较长时间后,我不得不再次加载 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。使用环境变量,可以避免此错误。
    【解决方案3】:

    好吧,如果连接需要在 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" 
    

    【讨论】:

    【解决方案4】:
    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
    

    【讨论】:

    • 这是不正确的。 --set=sslmode=require 定义了一个 psql 变量,它根本不参与认证过程。它没有强制使用 SSL。
    • 我可以确认这不起作用,正如@DanielVérité 指出的那样。使用具有不受信任证书并使用 --set=sslmode=verify-full 的 postgres 服务器进行测试不会抱怨。
    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:
      psql -h <host> -p <port> -U <user> -d <db>
      

      并更新/var/lib/pgsql/10/data/pg_hba.conf 以将身份验证方法更改为cert。查看以下链接了解更多信息:

      https://www.postgresql.org/docs/9.1/auth-pg-hba-conf.html

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

        • 一开始我也是这么想的,但是在重新阅读连接到数据库部分之后,我采取了指定连接参数的另一种方法是使用 conninfo 字符串,它被用来代替数据库名称。这种机制使您可以非常广泛地控制连接。 这意味着您可以将任何参数推入conninfo 字符串中。但我也认为这里的文档也可以更清楚。
        【解决方案8】:

        psql 低于 9.2 不接受这种类似 URL 的选项语法。

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

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

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

        阅读manual page 了解更多选项。

        【讨论】:

        • 我从这个链接得到了这个连接字符串语法。 postgresql.org/docs/9.2/static/app-psql.html
        • 我也试过你的选项psql -h localhost -p 2345 -U thirunas -d postgres "sslmode=require" -f test_schema.ddl,但它说sql: warning: extra command-line argument "sslmode=require" ignored
        • @annonymous 你说你得到了 9.2 文档的语法,但你也说你使用的是 8.4 版。 8.4 文档中未引用您使用的内容。尝试将“sslmode=require”也作为第一个参数。
        • @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
        • @Wave 和其他遇到此问题的人,使用 conninfo 字符串而不是数据库名称 (-d)。您可以在 -d 选项之后给出数据库名称,或者作为命令行上的第一个非选项参数。所以 -d postgres "sslmode=require" 应该是 psql [options] -d "dbname=postgres sslmode=require" [other options] 或 psql [options] "dbname=postgres sslmode=require"。您可以将许多其他选项移动到 conninfo 字符串中。
        猜你喜欢
        • 2016-12-24
        • 2020-04-07
        • 1970-01-01
        • 2019-06-12
        • 1970-01-01
        • 2018-12-29
        • 2015-12-25
        • 1970-01-01
        • 2014-04-13
        相关资源
        最近更新 更多