Postgres - python 多个 SSL 连接

2024-04-19

我在使用 psycopg2 和 SSL 建立两个并发 Postgres 数据库连接(一个到主数据库,一个到从数据库)时遇到问题。两个连接分别工作,即:

import psycopg2
dsnMaster='dbname=... sslcert=path/to/master/cert'
psycopg2.connect(dsnMaster, connection_factory=None, async=False)

有效,也是如此

import psycopg2
dsnSlave='dbname=... sslcert=path/to/slave/cert'
psycopg2.connect(dsnSlave, connection_factory=None, async=False

但同时加入两者

import psycopg2
dsnMaster='dbname=... sslcert=path/to/master/cert'
psycopg2.connect(dsnMaster, connection_factory=None, async=False)
dsnSlave='dbname=... sslcert=path/to/slave/cert'
psycopg2.connect(dsnSlave, connection_factory=None, async=False)

第二次连接总是失败SSL error: block type is not 01。 psycopg 似乎使用了之前连接的证书。

我尝试 .close() 第一个连接(如此处所示,但没有 ssl使用 psycopg2 动态更改 python 中的数据库 (postgresql) https://stackoverflow.com/questions/13719674/change-database-postgresql-in-python-using-psycopg2-dynamically),并且还尝试了各种 psycopg.extensionsisolation_level 选项,但没有成功。

提前致谢!


我相信我已经将问题追溯到 libq...PostgreSQL C 库。

我也注意到我无法对 2 个不同的连接使用不同的 ssl 客户端证书。第一个连接总是成功,而第二个连接总是失败SSL error: certificate verify failed

在服务器日志上我得到could not accept SSL connection: tlsv1 alert unknown ca

这告诉我第二个连接可能尝试使用第一个连接中的 ssl 证书,而不是使用被告知要使用的 ssl 证书。

考虑这段代码

import psycopg2
conn1 = psycopg2.connect('host=server1... sslcert=path/to/cert1')
conn2 = psycopg2.connect('host=server2... sslcert=path/to/cert2')

连接 2 似乎使用 cert1 而不是 cert2

我认为 psycopg2 有问题...也许它正在缓存客户端 ssl 证书...

我继续构建了 psycopg2 的调试版本并安装了它。我再次尝试了我的代码并获得了大量的调试信息。这是我得到的调试信息。 (我只是发布相关信息)

[98940] psyco_connect: dsn = 'dbname=testdb user=testdb host=server1 sslrootcert=root1.crt sslkey=cert1.key sslcert=cert1.crt sslmode=verify-full', async = 0
[98940] connection_setup: init connection object at 0x103093048, async 0, refcnt = 1
[98940] con_connect: connecting in SYNC mode
[98940] conn_connect: new postgresql connection at 0x10047ff90
[98940] conn_connect: server standard_conforming_strings parameter: on
[98940] conn_connect: server requires E'' quotes: NO
[98940] conn_connect: using protocol 3
[98940] conn_connect: client encoding: UTF8
[98940] clear_encoding_name: UTF8 -> UTF8
[98940] conn_connect: DateStyle ISO, MDY
[98940] connection_setup: good connection object at 0x103093048, refcnt = 1
# ... Got a good 1st connection here
# ... (Tons more lines of output before the 2nd connection)
[98940] psyco_connect: dsn = 'dbname=testdb user=testdb host=server2 sslrootcert=root2.crt sslkey=cert2.key sslcert=cert2.crt sslmode=verify-full', async = 0
[98940] connection_setup: init connection object at 0x103093170, async 0, refcnt = 1
[98940] con_connect: connecting in SYNC mode
[98940] conn_connect: new postgresql connection at 0x100682d30
[98940] conn_connect: PQconnectdb(dbname=testdb user=testdb host=server2 sslrootcert=root2.crt sslkey=cert2.key sslcert=cert2.crt sslmode=verify-full) returned BAD
[98940] connection_init: FAILED
[98940] conn_close: PQfinish called
[98940] connection_dealloc: deleted connection object at 0x103093170, refcnt = 0

如果我切换两个连接,结果是相同的...第一个连接成功,但第二个连接失败。因此,第二个连接的 dsn 是正确的,因为如果先执行,连接就会成功。

检查 psycopg2 的来源,它只是调用PQconnectdb来自 libq C 库...并且它使用正确的参数调用它。 您可以查看以下文档PQconnectdb at http://www.postgresql.org/docs/9.4/static/libpq-connect.html#LIBPQ-PQCONNECTDB http://www.postgresql.org/docs/9.4/static/libpq-connect.html#LIBPQ-PQCONNECTDB

这告诉我 psycopg2 正在调用PQconnectdb正确地使用正确的参数和PQconnectdb只是在第二次连接时没有使用正确的证书。

更重要的是我也用其他程序做了一些测试。我测试了 Navicat for PostgreSQL(Mac 版本)——同样的问题。第一次连接成功,第二次连接验证证书失败。当我重新启动 Navicat 时,它再次发生...无论我尝试什么顺序,第一个连接成功,第二个连接失败。

PgAdmin 也会发生同样的情况(目前最新版本是 1.20)。第一次连接成功,第二次连接失败。

我怀疑任何连接 PostgreSQL 的软件或模块只要使用 libq 来连接都会遇到同样的问题。事实上,我什至测试了PHP,并得到了相同的结果

root@test:~# php -a
Interactive mode enabled

php > // Test with server 1 first
php > $conn = pg_connect('host=server1 user=testdb dbname=testdb sslcert=cert1.crt sslmode=verify-full sslkey=cert1.key sslrootcert=root1.crt');
php > $conn2 = pg_connect('host=server2 user=testdb dbname=testdb sslcert=cert2.crt sslmode=verify-full sslkey=cert2.key sslrootcert=root2.crt');
PHP Warning:  pg_connect(): Unable to connect to PostgreSQL server: SSL error: certificate verify failed in php shell code on line 1
php > quit
root@test:~# php -a
Interactive mode enabled

php > // Test with server 2 first
php > $conn2 = pg_connect('host=server2 user=testdb dbname=testdb sslcert=cert2.crt sslmode=verify-full sslkey=cert2.key sslrootcert=root2.crt');
php > $conn = pg_connect('host=server1 user=testdb dbname=testdb sslcert=cert1.crt sslmode=verify-full sslkey=cert1.key sslrootcert=root1.crt');
PHP Warning:  pg_connect(): Unable to connect to PostgreSQL server: SSL error: certificate verify failed in php shell code on line 1
php > quit
root@test:~# php -a
Interactive mode enabled

php > // Test using the same certificate
php > $conn = pg_connect('host=server1 user=testdb dbname=testdb sslcert=cert1.crt sslmode=verify-full sslkey=cert1.key sslrootcert=root1.crt');
php > $conn2 = pg_connect('host=server2 user=testdb dbname=testdb sslcert=cert1.crt sslmode=verify-full sslkey=cert1.key sslrootcert=root1.crt');
php > // No problems. Both connect just fine now

我的建议是使用 PostgreSQL 提交错误报告。不确定这是否是提交此类错误报告的正确位置http://www.postgresql.org/support/submitbug/ http://www.postgresql.org/support/submitbug/

在此之前,我能够想出一个适合我的解决方案......现在的解决方案是简单地为两台服务器使用相同的证书。如果你能做到这一点,它适用于两个连接,并且你可以有 2 个单独的连接到 2 个单独的服务器...(只要两个连接可以使用相同的客户端证书进行连接)

对我来说,我只是在两台服务器上使用了相同的服务器 ssl 证书、私钥和根证书...我只是使用通配符作为通用名称并自己签署了证书(但如果您愿意,您可以使用商业通配符证书)然后,我生成了一个客户端证书并将该证书用于两个连接。

这可能不是您正在寻找的答案,但这似乎是您可以使用客户端证书身份验证通过 SSL 与 2 个不同服务器建立 2 个连接的唯一方法。无论您使用什么编程语言或软件,都是如此。

所以,你的代码现在变成这样:

import psycopg2
dsnMaster='dbname=... sslcert=path/to/master/cert'
psycopg2.connect(dsnMaster, connection_factory=None, async=False)

# Here, the dsnSlave simply uses the same cert as the master
# Other connection details like the host and dbname can be different
dsnSlave='dbname=... sslcert=path/to/master/cert'
psycopg2.connect(dsnSlave, connection_factory=None, async=False)

这是我在 python 中运行的实际代码

root@test:~# python3
Python 3.4.0 (default, Jun 19 2015, 14:20:21) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import psycopg2
>>> dsn1 = 'host=server1 user=testdb dbname=testdb sslcert=cert1.crt sslmode=verify-full sslkey=cert1.key sslrootcert=root1.crt'
>>> conn1 = psycopg2.connect(dsn1)
>>> dsn2 = 'host=server2 user=testdb dbname=testdb sslcert=cert1.crt sslmode=verify-full sslkey=cert1.key sslrootcert=root1.crt'
>>> conn2 = psycopg2.connect(dsn2)
>>> # YAY, no issues and both connections work
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Postgres - python 多个 SSL 连接 的相关文章

  • 存储为 np.arrays 的不同数据集的分组堆积条形图

    我正在研究一个平衡问题 我想比较一些数据 我想通过创建不同年份的堆叠条形图来做到这一点 每年 我想要两个不同数据集的堆叠条形图 我正在尝试创建一种 分组堆积条形图 我设法创建了我想要比较的 2 个堆叠条形图 但它们仍然位于两个不同的图中 我
  • C++ 相当于 Python getattr

    在Python中 有一个名为getattr的函数 它看起来像这样 class MyObject def init self self xyz 4 obj MyObject getattr obj xyz 其中对 getattr 的调用将返回
  • Python Numpy TypeError:输入类型不支持 ufunc 'isfinite'

    这是我的代码 def topK dataMat sensitivity meanVals np mean dataMat axis 0 meanRemoved dataMat meanVals covMat np cov meanRemov
  • Python:我可以修改元组吗?

    我有一个 2 D 元组 实际上我以为 它是一个列表 但错误说它是一个元组 但无论如何 该元组的形式为 浮点数 val prod id 现在我有一个字典 其中包含 key gt prod id 和 value prod name 现在 我想将
  • python列表理解和extend() [重复]

    这个问题在这里已经有答案了 深入学习 Python 2 7 1 但未能理解这一点 几个小时 gt gt gt a 1 2 gt gt gt b 3 4 gt gt gt gt gt gt a extend b 0 gt gt gt a 1
  • 为什么 Dash 在上传文件时会出现解析错误?

    上传 Excel 或 CSV 会导致错误 我遵循了 Dash 演示 但是当我尝试扩展它来执行绘图之类的操作时 它就不起作用了 我不想只显示一张桌子 Dash Table 函数已更新 因此之前使用 Dash Table Experiments
  • 使用 Python 连接从 FTP 检索文件

    我构建了这个简单的工具来暴力破解并连接到 ftp 服务器 import socket import ftplib from ftplib import FTP port 21 ip 192 168 1 108 file1 passwords
  • 在 python 中返回 self [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个代表对象的类 我有很多方法可以修改这个对象状态 没有明显的返回或显然没有任何返回 在 C 中 我会将所有这些方法声明为void
  • python 正则表达式中括号的奇怪行为

    我正在编写一个 python 正则表达式 它可以在文本文档中查找引用的字符串 从黑匣子中记录的航空公司飞行员的引用 我首先尝试编写具有以下规则的正则表达式 返回引号之间的内容 如果以 single 打开 则仅在以 single 关闭时返回
  • scipy 的 curve_fit 函数的尺寸问题

    我对 python 中的曲线拟合以及一般的 python 都很陌生 目前 我正在尝试使用 scipy 中的 curve fit 模块来拟合 4 个光谱峰 简而言之 我的文本文件中有两列数据 所以我的第一步是将数据导入到两个数组中 一个包含
  • PostgreSQL:存在与左连接

    我多次听说 postgres 处理exists查询速度更快左连接 http archives postgresql org pgsql performance 2002 12 msg00185 php http archives postg
  • OpenCV 在使用 anaconda 的 Linux 上无法与 python 正常工作。收到 cv2.imshow() 未实现的错误

    这就是我得到的确切错误 我的操作系统是 Ubuntu 16 10 OpenCV 错误 未指定错误 该功能未实现 使用 Windows GTK 2 x 或 Carbon 支持重新构建库 如果您使用的是 Ubuntu 或 Debian 请安装
  • 有没有更快的方法将数字转换为名称?

    以下代码定义了映射到数字的名称序列 它的设计目的是获取一个号码并检索一个特定的名称 该类通过确保名称存在于其缓存中来进行操作 然后通过索引到其缓存中来返回名称 问题在这 如何在不存储缓存的情况下根据数字计算出名称 该名称可以被认为是一个以
  • Python - Map/Reduce - 如何在使用 DISCO 计数单词示例中读取 JSON 特定字段

    我正在按照 DISCO 示例来计算文件中的单词数 将单词数作为 Map Reduce 作业 http discoproject org doc disco start tutorial html 我对此工作没有任何问题 但是我想尝试从包含
  • Kivy:滚动缩放

    有没有办法在桌面 kivy 应用程序上放大图像 例如使用鼠标滚轮缩放 这里似乎讨论过 https github com kivy kivy issues 3563 https github com kivy kivy issues 3563
  • 如何使用Django模板作为组件?

    我有 5 个模板 index html detail html tag html login html register html and a 基本 html 所有 5 个模板都会扩展基本 html 索引 html 详细信息 html 标签
  • 如何通过pygit2获取当前签出的Git分支名称?

    这个问题应该与 如何获取Git中当前的分支名称 https stackoverflow com questions 6245570 how to get current branch name in git 获取 git 当前分支 标签名称
  • 对二进制数的字符串表示进行按位运算 python 2.7

    我想对二进制数的两个字符串表示执行按位或 但我不知道如何将字符串转换为原始二进制 a 010110 b 100000 a b 应该产生 110110 然后我想计算 on 位的数量 这应该返回 4 您可以使用内置的将字符串转换为二进制int
  • 如何在Python中检查元组是否包含元素?

    我试图找到可用的方法 但找不到 没有contains 我应该使用index 我只想知道该项目是否存在 不需要它的索引 You use in if element in thetuple whatever you want to do
  • 交响二阶颂歌

    我有一个简单的二阶 ODE 的齐次解 当我尝试使用 Sympy 求解初始值时 它返回相同的解 它应该替代 y 0 和 y 0 并产生一个没有常数的解 但事实并非如此 这是建立方程的代码 它是一个弹簧平衡方程 k 弹簧常数 m 质量 我在其他

随机推荐

  • Android Facebook SDK v3.0 SSO LoginButton 返回 null GraphUser

    所以我有一个简单的登录按钮 可以在我的 oncreate 中执行此操作 mLoginButton LoginButton findViewById R id connect facebook button mLoginButton setA
  • C++ 使用对正在定义的变量的引用

    根据标准 不考虑 以下代码是否有效 C bool f T r if r return true return false T x f x x T 众所周知 要在该项目使用的 GCC 版本中进行编译 4 1 2 和 3 2 3 甚至不让我开始
  • 错误:EMFILE:打开的文件太多,请注意,除非我使用 sudo

    描述 最近我遇到了一个问题 我无法奔跑yarn start in element web目录 我得到这些errors https pastebin ubuntu com p 93v6Yx58DT 原本我以为这与element web本身所以
  • 如何以编程方式精确查找 PPI

    我正在尝试找出 iOS 中的 PPI 每英寸像素 我找不到任何直接的方法来查询它 就像我们查询显示尺寸一样 UIScreen mainScreen bounds 有一个方法 https stackoverflow com a 7922666
  • Xcode 升级到 4.5 后应用程序崩溃。将保留对象分配给 unsafe_unretained 变量

    在我的班级里 我有一个dispatch queue t属性声明如下 property nonatomic assign dispatch queue t queue 然后在我的 init 方法中我这样做 id initWithServerU
  • 在詹金斯管道的多个步骤中定义和访问变量

    我是从这个帖子来到这里的在 Jenkins Pipeline 的 shell 脚本部分定义变量 https stackoverflow com questions 51407976 defining a variable in shell
  • 在训练期间启用和禁用变量学习

    我想在训练期间开始或停止变量的学习 虽然Variable的构造函数有一个trainable参数 该参数构建后不可更改 为了实现这种效果 我当前的解决方案是在我想要更改变量的可训练状态时保存模型 将变量设置为所需的可训练状态来重建网络 然后重
  • 每月第二个星期一的 Cron 表达式(对于 Hangfire)

    我正在尝试在 Hangfire 中创建定期作业 每月第二个星期一运行一次 如下所示 1 Monday May 14 2018 8 00 AM 2 Monday June 11 2018 8 0 AM 3 Monday July 9 2018
  • 在编译时检测编译器版本

    这既是一个问题 也是一个参考 我希望人们能够在此基础上进行构建 以便有类似问题的人可以重用它 我们如何可靠地检测 C C ObjC 编译器的特定版本 现在我知道了 Visual Studio 的答案 并部分知道了 Xcode 的答案 现在
  • JSF 1.2 startElement 和 writeAttribute 解释

    我有机会为我的项目编写一些自定义渲染器 并且运行得非常好 然而 我对 ResponseWriter 方法中的一些参数有些困惑 该文档没有很好地解释这一点 因此我希望一位常驻 JSF 专家可以更好地解释这一点 具体来说 public abst
  • 在 powershell 中使用 %userProfile% 环境变量创建路径时出现意外行为

    我编写了一个脚本来创建一系列符号链接 我想将目标值设置为 shortpath 其中 shortpath userprofile dir1 dir2 dir3 filename ext shortpath 变量的值是有效的 我可以从运行命令打
  • C - 将大写字母转换为小写字母

    一个非常简单的程序 我只想将 A 变成 a 但输出给了我 A include
  • 类 VS 引用结构

    我正在使用 C 编写游戏 因此 我非常关心性能 我想知道主要区别是什么 如果可能的话 使用类传递数据或通过引用传递结构的性能考虑因素 出于性能原因 我希望不要复制数据 我假设通过 ref 传递比这里通过值传递要快得多 我知道类始终通过引用传
  • MS 缺少 VSTO 4.0 运行时下载?

    我们有代码检查 VSTO 4 0 运行时是否存在并下载 如果丢失 直到今天这一切都运作良好 MS 中的 VSTO 运行时文件似乎丢失了 有人对这个有了解吗 我们能否告诉客户这是 MS 问题并且很快就会得到解决 Google 没有找到任何有关
  • Serialized 和 DataContract(不是对比?)

    我正在阅读我的新项目中的一些代码 发现前开发人员同时使用 Serialized 和 DataContract Serializable and DataContract Namespace Some Name Space IsReferen
  • iTerm2 隐藏标记

    我最近安装了 iTerm2 的 Shell Integration 但在输入 shell 命令时它还添加了那些小箭头 称为标记 这真的很烦人 有什么方法可以禁用 隐藏它们 我在网上找不到 As per 文档 https www iterm2
  • 让 IIS6 与 WordPress 完美配合

    我有一个由 WordPress 驱动的博客 我正在尝试在 IIS6 服务器上进行设置 除了令我头疼的永久链接结构之外 一切正常 在谷歌搜索 wordpress codex之后 我了解到这是因为IIS6没有相当于Apache的mod rewr
  • 如何在 Android 上注册的应用程序中从我的 WebView 中启动 Web 链接?

    在我的 Android 应用程序中 我有一个 WebView 我想every在我的 WebView 中单击链接以启动我的设备上已注册的应用程序 如果有 否则在外部浏览器中打开 例如 如果用户从 WebView 中单击 Facebook 页面
  • Ninject - 找不到资源

    我收到错误 无法找到该资源 当我尝试在我的 MVC 3 应用程序中实现 Ninject 时 该问题似乎来自 Global asax 期间CreateKernel region Inversion of Control protected o
  • Postgres - python 多个 SSL 连接

    我在使用 psycopg2 和 SSL 建立两个并发 Postgres 数据库连接 一个到主数据库 一个到从数据库 时遇到问题 两个连接分别工作 即 import psycopg2 dsnMaster dbname sslcert path