我正在尝试使用PyMongo创建安全的SSL连接到MongoDB。 目标是在EC2上运行的Mongo实例上使用此配置,以便我可以使用Python客户端连接。 为了测试,我首先尝试将配置在本地运行。 我的尝试未能成功,可以在这里找到。
我认为问题的简短版本是:我的客户端证书机构文件ca.pem
不正确。 我现在的做法是,这个文件与我在服务器端使用的文件完全相同。 这两个文件都是使用x509
和openssl
创建的,我怀疑我的客户端文件需要某种不同的内容,但我不确定如何生成该内容或者这个怀疑是否正确。
下面是我为创建必要的证书和密钥所做的详细信息(在Mac El Capitan上):
首先,生成证书机构:
$ mkdir ~/ssl
$ cd ~/ssl
$ openssl req -out ca.pem -new -x509 -days 3650
# enter info
生成服务器 .pem
文件:
$ openssl genrsa -out server.key 2048
$ openssl req -key server.key -new -out server.req
# enter info
$ openssl x509 -req -in server.req -CA ca.pem -CAkey privkey.pem -CAserial file.srl -out server.crt -days 3650
$ cat server.key server.crt > server.pem
现在对于客户端也做同样的操作:
$ openssl genrsa -out client.key 2048
$ openssl req -key client.key -new -out client.req
$ openssl x509 -req -in client.req -CA ca.pem -CAkey privkey.pem -CAserial file.srl -out client.crt -days 3650
$ cat client.key client.crt > client.pem
接下来我在etc/mongod.conf
中进行以下配置:
net:
...
ssl:
mode: requireSSL
PEMKeyFile: ~/ssl/server.pem
CAFile: ~/ssl/ca.pem
现在使用以下命令在Mac上启动Mongo:
$ mongod --config /etc/mongod.conf
如预期一样工作。进程运行并似乎正在接受配置。
然后在Python端(也在本地调试中运行),我在调用mongo时执行以下操作:
import ssl
from pymongo import MongoClient
client = MongoClient(
'127.0.0.1',
27017,
ssl=True,
ssl_certfile='~/ssl/client.pem',
ssl_cert_reqs=ssl.CERT_REQUIRED,
ssl_ca_certs='~/ssl/ca.pem'
)
# try a simple insert
当我运行这段代码时,在创建MongoClient
后,Python代码块被阻塞,并且我在mongo
日志中看到以下内容:2016-03-03T22:11:30.331-0800 E NETWORK [conn21] SSL: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca
基于下面Wan的评论,我重新做了整件事情,并确保'Distinguished Name'中的信息与那些规范相一致。旧版本明显针对服务器和客户端都使用同样的通用名称。连接仍未成功,但是消息有所不同:
2016-03-11T12:29:40.380-0800 I NETWORK [initandlisten] connection accepted from 127.0.0.1:57363 #3 (1 connection now open)
2016-03-11T12:29:40.386-0800 I NETWORK [conn3] end connection 127.0.0.1:57363 (0 connections now open)
这两条消息会不断重复,直到我停止Python进程,在尝试打开连接时会被阻塞。现在end connection
部分已经放置在mongo日志之前alert unknown ca
行的位置。
调试附加信息:
$ openssl verify -CAfile ca.pem client.pem
client.pem: OK
$ openssl verify -CAfile ca.pem server.pem
server.pem: OK
$ openssl x509 -noout -subject -in server.pem
subject= /C=US/ST=Washington/L=Seattle/O=codeMelon/OU=Engineering/CN=server.com/emailAddress=<my-email-address>@gmail.com
$ openssl x509 -noout -subject -in client.pem
subject= /C=US/ST=Washington/L=Seattle/O=codeMelon/OU=Engineering/CN=client.com/emailAddress=<my-email-address>@gmail.com
在正确形成主题行之后,最终结论是mongo接受了连接,然后结束了连接,Python进程在没有进行预期插入的情况下阻塞。
非常感谢任何帮助!
file.srl
пјүпјҢе®ғеҸҜд»Ҙе·ҘдҪңгҖӮйңҖиҰҒжЈҖжҹҘзҡ„еҮ 件дәӢжғ…пјҡ1пјүиҝҗиЎҢopenssl verify -CAfile ca.pem client.pem
жқҘйӘҢиҜҒе®ўжҲ·з«Ҝе’ҢжңҚеҠЎеҷЁpemдёҺCAзҡ„еҢ№й…ҚжҖ§гҖӮ2пјүзЎ®дҝқжӮЁиҫ“е…Ҙзҡ„subj
жҲ–дҝЎжҒҜе…·жңүеҢ№й…Қзҡ„дҝЎжҒҜпјҢеҚі/C=<Country Name>/ST=<State>/L=<Locality Name>/O=<Organisation Name>/emailAddress=<email>пјҢдҪҶеҜ№дәҺCN=<Common Name> CA/server/clientжңүдёҚеҗҢзҡ„еҖјгҖӮеҰӮжһңжӮЁд»Қжңүй—®йўҳпјҢиҜ·еҸ‘еёғжӮЁзҡ„subj
еҖјзӨәдҫӢгҖӮ - Wan B.hostname
命令(假设您使用的是*nix系统)。将主机名为服务器的subj
添加一个“CN”附加项。将您的MongoClient127.0.0.1
值更改为与主机名匹配(在1之前也应该是一个句点而不是引号),或查看sslAllowInvalidHostnames标志。2)尝试使用mongo
shell连接,而不是您的Python脚本,先解决SSL问题,然后再添加额外的脚本。告诉我进展如何。 - Wan B.MongoClient()
中传递参数ssl_match_hostname=False
,我已经成功地在本地使用PyMongo工作了。如果您想将结果总结为答案,我很乐意给您一个“正确的答案”。非常感谢您的帮助! - Marshall Farrier