Postgres – python多个SSL连接
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Postgres – python多个SSL连接,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6977字,纯文字阅读大概需要10分钟。
内容图文
![Postgres – python多个SSL连接](/upload/InfoBanner/zyjiaocheng/794/a99b3df169074906975ce5d9723d33f8.jpg)
我有麻烦使用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错误:块类型不是01
.似乎psycopg使用以前连接的证书.
我试图.close()第一个连接(如此处所示,但没有ssl change database (postgresql) in python using psycopg2 dynamically),并尝试了各种psycopg.extensions isolation_level选项,但没有成功.
提前致谢!
解决方法:
我相信我已将问题追溯到libq … PostgreSQL C库.
我也注意到我不能为2个不同的连接使用不同的ssl客户端证书.第一个连接始终成功,而第二个连接始终因SSL错误而失败:证书验证失败
在服务器日志中,我无法接受SSL连接: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
如果我切换2个连接,则结果相同……第一个连接成功,但第二个连接失败.因此,第二个连接的dsn是正确的,因为如果先执行连接,连接会成功.
检查psycopg2的来源,它只是从libq C库调用PQconnectdb …并且它使用正确的参数调用它.
您可以在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).第一次连接成功,第二次连接失败.
我怀疑只要使用libq进行连接,任何连接到PostgreSQL的软件或模块都会遇到同样的问题.事实上,我甚至测试过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/
在此之前,我能够提出一个适合我的解决方案……现在的解决方案是简单地为两个服务器使用相同的证书.如果您可以这样做,它适用于两个连接,您可以有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
内容总结
以上是互联网集市为您收集整理的Postgres – python多个SSL连接全部内容,希望文章能够帮你解决Postgres – python多个SSL连接所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。