我想在MongoDB中使用SSL。它在默认情况下没有启用,所以必须使用必要的选项从源代码进行编译。我遵循了官方文档,构建了v2.6.4二进制文件,并在新部署的运行Ubuntu 14.04的服务器上运行良好。到目前为止一切都很好。
接下来,我按照官方文档中的描述设置mongod。我确实遵循了他们的例子,使用自我认证的密钥进行测试。配置的相关部分看起来像:
...
net:
bindIp: 127.0.0.1
port: 27017
ssl:
mode: requireSSL
PEMKeyFile: /opt/mongo/security/mongodb.pem
...
如果我随后运行客户端并指定使用SSL,我可以正常连接。($ mongo --ssl
)。FWIW如果我在没有--ssl
参数的情况下尝试,那么它不会连接。
好的,是时候通过Ruby连接了。我在同一台服务器上,我尝试了以下ruby脚本:
require 'rubygems'
require 'mongo'
client = Mongo::MongoClient.new('localhost', 27017, {:ssl => true})
没有。它没有:
/home/test/.rvm/gems/ruby-1.9.3-p547/gems/mongo-1.11.1/lib/mongo/mongo_client.rb:422:in `connect': Failed to connect to a master node at localhost:27017 (Mongo::ConnectionFailure)
from /home/test/.rvm/gems/ruby-1.9.3-p547/gems/mongo-1.11.1/lib/mongo/mongo_client.rb:661:in `setup'
from /home/test/.rvm/gems/ruby-1.9.3-p547/gems/mongo-1.11.1/lib/mongo/mongo_client.rb:177:in `initialize'
from test_mongo_ssl.rb:8:in `new'
from test_mongo_ssl.rb:8:in `<main>'
因此,最好确保没有SSL的默认连接没有任何问题。我在mongod上禁用了SSL并重新启动。然后再次尝试ruby脚本,这次没有ssl选项:
...
client = Mongo::MongoClient.new('localhost', 27017)
这很好。因此,我觉得我已经把它缩小到ruby驱动程序&ssl,但除此之外,几乎没有其他事情可做。
EDIT我在同一台服务器上尝试了他们的Python驱动程序,并使用了他们的示例程序:
from pymongo import MongoClient
c = MongoClient(host="localhost", port=27017, ssl=True)
这确实很好。所以至少我可以确信mongod配置正确,问题出在Mongo-Ruby驱动程序中。很可能是他们当前驱动程序(v1.11.1)中的一个错误。
UPDATE我还成功地使用node.js驱动程序通过ssl进行了连接:
var mongo = require('mongodb');
var database = new mongo.Db("my_database", new mongo.Server("127.0.0.1", 27017, {ssl:true} ), {w:0});
database.open(function(err, db) {
if(err) throw err;
db.authenticate('user', 'password', function(err, result) {
var collection = db.collection('foo');
collection.findOne(function(err, item) {
if(err) throw err;
console.log(item);
db.close();
});
});
});
在那里,ruby驱动程序中似乎越来越有可能存在错误,或者文档不完整,没有准确解释如何使用SSL连接。因此,我在MongoDB的问题跟踪器上打开了一个新的问题,希望能弄清真相。
令人尴尬的是,这个问题的解决方案是我的/etc/hosts文件的localhost条目有一个拼写错误:
127.0.0.1 localhost.localdomain locahost
正如您所看到的,它缺少"localhost"中的第二个字母L。(我怀疑它是在一次意外的vim手势中丢失的。)因此,为了解决这个问题,我只需要恢复丢失的"l":
127.0.0.1 localhost.localdomain localhost
Python示例为什么能正常工作仍然是个谜。正因为如此,我之前没有发现主机文件有问题。