我正在尝试设置我的 postgres 服务器以进行 SSL 连接。我正确设置了 postgresql.conf 和 pg_hba.conf。我在 postgres 数据目录中创建了一个密钥和自签名证书 (server.crt 和 server.key),并将 server.crt 复制到 root.crt。
我还使用服务器上的 root.crt 在另一台主机上设置了证书和密钥,以签署客户端证书。当我使用 openssl 测试证书时,一切正常。但是,当我尝试连接到 postgres 服务器时,它失败了:
psql -h <HOSTNAME> -U <USER> -d <DB>
psql: SSL error: certificate verify failed
或者:
openssl s_client -connect <HOSTNAME>:5432 -state -msg -showcerts -debug
CONNECTED(00000003)
SSL_connect:before/connect initialization
write to 080ACFE0 [080AD570] (145 bytes => 145 (0x91))
0000 - 80 8f 01 03 01 00 66 00-00 00 20 00 00 39 00 00 ......f... ..9..
...
0080 - 04 fd be bd 49 e7 1d 99-f5 bb 7e 24 2e fe 34 e8 ....I.....~$..4.
0090 - d7 .
>>> SSL 2.0 [length 008f], CLIENT-HELLO
01 03 01 00 66 00 00 00 20 00 00 39 00 00 38 00
...
be bd 49 e7 1d 99 f5 bb 7e 24 2e fe 34 e8 d7
SSL_connect:SSLv2/v3 write client hello A
read from 080ACFE0 [080B2AD0] (7 bytes => 0 (0x0))
18357:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:226:
最后,如果我设置 openssl 在服务器端提供服务并从客户端主机进行连接,它可以正常工作:
openssl s_client -connect <HOSTNAME>:4433 -state -msg -showcerts -debug
知道为什么 postgres 拒绝我的证书吗?对于我当前的设置,服务器是运行 postgres 8.1 的 FreeBSD 4.7,客户端是运行 postgres 9.0 的 CentOS 4。不确定这是否是其中的原因...
答案1
PostgreSQL 不会开始 SSL 协商,直到您发送指示它这样做的数据包为止。s_client 期望它在该数据包之前执行 SSL。请参阅http://www.postgresql.org/docs/9.0/static/protocol-flow.html#AEN84524有关 SSL 在 PostgreSQL 中的工作原理的文档。
仔细检查根证书是否位于客户端的正确位置,以及 postgres 是否可以正确读取。也许需要运行 strace 以确保它确实被读取。这是迄今为止最常见的无法正常工作的原因。
正如之前提到的,你应该尽快放弃 8.1,因为它已经过期了。但这应该不会对此产生重大影响。
答案2
删除旧的 ~/.postgresql 解决了这个问题。尝试使用strace
psql 检查调用open
。