将 pgAdmin3 连接到 Heroku postgreSQL DB 时出现 SSL 错误

SSL error when connection pgAdmin3 to Heroku postgreSQL DB

尝试使用 pgAdmin3 连接到 Heroku PostgresSQL DB 时出现以下错误:

Error connecting to the server: SSL error: certificate verify failed

连接基于pg:credentials输出,定义如下:

[属性]:

[SSL]:

[SSH 隧道] 和 [高级] 保留默认值

因此根据 Heroku 指南启用了 SSL(设置为:[**require**])。

关于如何 provide/fix 错误消息引用的证书的任何想法?

很可能 pgAdmin 正在获取已在您的系统上配置的 CA 证书包,在这种情况下 require 将尝试根据该包验证服务器证书。

通常,这将是位于 Windows 下的 %APPDATA%\postgresql\ (C:\Users\YourUserName\AppData\Roaming\postgresql\) 或 [=51= 下的 ~/.postgresql/ 中的 root.crt 文件].

如果有这样的文件,请尝试将其暂时移开,以检查它是否可以更好地工作。


将其移开的问题是您不再针对任何东西验证任何远程 PostgreSQL 证书,但它仍然有效(require,它会因 verify-full 而失败) .

您可以通过将 root.crt 文件放在正确的位置并将服务器证书添加到受信任的证书列表来解决此问题。


找到远程 PostgreSQL 证书可能有点棘手,但是这个简单的 Python 应用程序应该可以让您做到这一点(根据需要替换 hostnameport):

import socket
import ssl
import struct


hostname = '...'
port = 5432

sock = socket.socket()
sock.connect((hostname, port))
# We first connect without encryption and tell the server
# we want to upgrade to SSL/TLS.
initiate_ssl_command = struct.Struct('!ii').pack(8, 80877103)
sock.sendall(initiate_ssl_command)
resp = sock.recv(1)
print "Response should be S: %s" % (resp,)

# We then initiate an SSL/TLS connection on this socket.
ssl_sock = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_NONE)
ssl_sock.do_handshake()
peer_cert = ssl_sock.getpeercert(True)
print ssl.DER_cert_to_PEM_cert(peer_cert)
ssl_sock.close()

(有关此代码功能的详细信息,请参阅 PostgreSQL 协议文档,尤其是 "SSL Session Encryption" section and the SSLRequest message,它与 STARTTLS 在其他协议(如 SMTP)中的功能类似。)

安全警告:在这里,你只是希望这个特定的连接没有被攻击,并且returns第一时间是正版证书。您将使用它作为后续连接的信任锚。 (这与接受第一次连接的 SSH 服务器密钥非常相似,如果它发生变化,它将标记对证书的更改。)

还值得注意的是,证书主题 DN 可能与您要连接的服务器的主题 DN 不匹配,因此您可能无法使用 PostgreSQL 的 verify-full 模式(这是唯一真正安全的模式,因为它还会验证主机名和信任锚)。

理想情况下,Heroku(或任何提供此服务的人)应该通过另一种安全方式为您提供该证书,并确保该证书中的主题 DN 与他们提供给您的主机名相匹配。 (我不确定目前是否是这种情况,也许可以从管理界面获得。)