如何通过ssl连接mongoDB和nodejs,
我正在使用此代码创建连接但它无法正常工作
var Db = require('mongodb').Db;
var Server = require('mongodb').Server;
Db.connect('mongodb://xxx.xxx.xxx.xxx:27017/db-login', { auto_reconnect: true, poolSize:4, ssl:true }, function (err, db) {
我还尝试了另一个代码
var localIP='xxx.xxx.xxx.xxx:27017', ssl=true;
任何帮助和建议
答案 0 :(得分:3)
第1步:获取MongoDB 3.0
首先需要知道的是,只有MongoDB 3.0及更高版本支持SSL。 Ubuntu在默认存储库中没有3.0,所以这里有你如何获得它:
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org=3.0.7 mongodb-org-server=3.0.7 mongodb-org-shell=3.0.7 mongodb-org-mongos=3.0.7 mongodb-org-tools=3.0.7
3.0.7是目前最新的稳定版本,但您可以随意用自己喜爱的版本替换3.0.7。
第2步:获取私钥,证书和PEM文件
PEM包含公钥证书及其关联的私钥。这些文件既可以从证书认证中获得IRL美元,也可以使用OpenSSL生成,如下所示:
openssl req -newkey rsa:2048 -new -x509 -days 3650 -nodes -out mongodb-cert.crt -keyout mongodb-cert.key
cat mongodb-cert.key mongodb-cert.crt > mongodb.pem
mongodb.pem将用作PEM文件,mongodb-cert.key是私钥文件,mongodb-cert.crt是证书文件,也可以用作CA文件。你将需要这三个。
第3步:配置MongoD
我们假设您将这些文件复制到它们所属的/ etc / ssl /文件夹中。现在我们打开我们的MongoDB配置文件:
sudo vi /etc/mongod.conf
并修改" #network interface"这样的部分:
# network interfaces
net:
port: 27017
#bindIp: 127.0.0.1
ssl:
mode: allowSSL
PEMKeyFile: /etc/ssl/mongodb.pem
#CAFile: /etc/ssl/mongodb-cert.crt
请注意:我们正在评论bindIp。这允许外部连接访问您的Mongo数据库。我们假设这是您的最终目标(为什么您的加密会在localhost上加密?),但您只应在为MongoDB服务器设置授权规则后执行此操作。
CAFile也被注释掉,因为它是可选的。我将在本文末尾解释如何设置证书颁发机构信任。
与往常一样,您必须在配置文件更改生效之前重新启动MongoDB:
sudo service mongod restart
您的服务器无法启动?您是独立的,但您的证书文件可能存在问题。您可以通过手动运行mongod来检查启动错误:
sudo mongod --config /etc/mongod.conf
第4步:测试您的服务器设置
在我们搞乱Node配置之前,让我们通过连接mongo命令行客户端来确保您的服务器设置正常工作:
mongo --ssl --sslAllowInvalidHostnames --sslAllowInvalidCertificates
除非证书上的域名是127.0.0.1或localhost,否则--sslAllowInvalidHostnames标志是必需的。没有它,你可能会收到这个错误:
E NETWORK The server certificate does not match the host name 127.0.0.1
E QUERY Error: socket exception [CONNECT_ERROR] for
at connect (src/mongo/shell/mongo.js:179:14)
at (connect):1:6 at src/mongo/shell/mongo.js:179
exception: connect failed
步骤5)配置Node.JS / Mongoose
如果您在Node应用程序中使用node-mongodb-native软件包,请立即停止并开始使用Mongoose。这并不难。也就是说,mongoose.connect()实际上与mongodb.connect()具有相同的API,因此可以适当替换。
var fs = require('fs')
, mongoose = require('mongoose')
, mongoUri = "mongodb://127.0.0.1:27017?ssl=true"
, mongoOpt = {
"server": {
"sslValidate": false,
"sslKey": fs.readFileSync('/etc/ssl/mongodb.pem'),
"sslCert": fs.readFileSync('/etc/ssl/mongodb-cert.crt')
}
}
;
mongoose.connect(mongoUri, mongoOpt);
步骤6)[可选]通过证书颁发机构验证您的证书
要验证您的SSL证书,您需要从证书颁发机构获取CA(或捆绑)文件。这看起来很像您的证书文件,但通常会包含多个证书(形成信任,以验证证书是否有效)。如果您使用的是自签名证书,则可以将mongodb-cert.crt用作CA文件。
您还需要确保MongoDB服务器的主机名与用于创建证书的主机名匹配。
步骤6.3)更新您的mongod配置
sudo vi /etc/mongod.conf
并修改" #network interface"这样的部分:
# network interfaces net: port: 27017 #bindIp: 127.0.0.1 ssl:
mode: allowSSL
PEMKeyFile: /etc/ssl/mongodb.pem
CAFile: /etc/ssl/mongodb-ca.crt
sudo service mongod restart
步骤6.4)测试您的服务器设置
mongo --ssl --sslAllowInvalidHostnames --sslCAFile /etc/ssl/mongodb-ca.crt --sslPEMKeyFile /etc/ssl/mongodb.pem
Mongo客户端也可以传入CA文件,以验证他们是否正在与正确的服务器通信。这是通过--sslCAFile参数
完成的使用CAFile配置的Mongo服务器要求客户端拥有有效的证书和服务器的私钥。在mongo shell客户端中,这是通过传入--sslPEMKeyFile参数来完成的。
没有PEM文件(包含服务器的证书),您可能会看到以下错误:
I NETWORK DBClientCursor::init call() failed
E QUERY Error: DBClientBase::findN: transport error: 127.0.0.1:27017 ns: admin.$cmd query: { whatsmyuri: 1 }
at connect (src/mongo/shell/mongo.js:179:14)
at (connect):1:6 at src/mongo/shell/mongo.js:179
exception: connect failed
通过启用net.ssl.weakCertificateValidation,可以将服务器配置为接受来自没有PEM文件的客户端的请求,但是您将削弱您的安全性而无法获得实际收益。
步骤6.5)配置Node.JS / Mongoose
这里有几个陷阱,所以忍受我。
首先,您需要拥有node-mongodb-native 2.0或更高版本。如果您使用的是Mongoose,那么您需要Mongoose 4.0或更高版本。以前的Mongoose版本使用node-mongodb-native 1. *,它不支持任何容量的证书验证。
其次,node-mongodb-native中没有可用的sslAllowInvalidHostnames或类似选项。这不是node-mongodb-native开发人员可以修复的东西(我现在可以使用),因为Node 0.10。*中提供的本机TLS库没有为此提供任何选项。在Node 4. *和5. *中,有一个checkServerIdentity选项提供了希望,但是在io.js合并之后从原始Node分支切换到分支可能会在当前时间引起一些麻烦。
所以让我们试试这个:
var fs = require('fs')
, mongoose = require('mongoose')
, mongoUri = "mongodb://127.0.0.1:27017?ssl=true"
, mongoOpt = {
"server": {
"sslKey": fs.readFileSync('/etc/ssl/mongodb.pem'),
"sslCert": fs.readFileSync('/etc/ssl/mongodb-cert.crt'),
"sslCa": fs.readFileSync('/etc/ssl/mongodb-ca.crt')
}
}
;
如果您收到主机名/ IP不匹配错误,请修复您的证书,或通过禁用sslValidate否定所有这些艰苦的工作:
var fs = require('fs')
, mongoose = require('mongoose')
, mongoUri = "mongodb://127.0.0.1:27017?ssl=true"
, mongoOpt = {
"server": {
"sslValidate": false,
"sslKey": fs.readFileSync('/etc/ssl/mongodb.pem'),
"sslCert": fs.readFileSync('/etc/ssl/mongodb-cert.crt'),
"sslCa": fs.readFileSync('/etc/ssl/mongodb-ca.crt')
}
}
;
来源: http://www.bainweb.com/2015/11/connecting-to-mongodb-over-tlsssl-with.html
答案 1 :(得分:2)
使用以下链接在mongoDB环境中配置SSL。
必须在MongoDB环境中启用SSL,并且必须在应用程序中启用SSL。
http://docs.mongodb.org/manual/tutorial/configure-ssl/ http://docs.mongodb.org/manual/tutorial/configure-ssl-clients/
您可以在节点中配置SSL连接,如下所示:
var options = {
key: fs.readFileSync('ssl/your_ssl_key.key'),
cert: fs.readFileSync('ssl/your_ssl_cert.cert')
};
https.createServer(options, app).listen(443);
如果要强制为所有用户建立https连接,可以强制重定向:
require("http").createServer(function (req, res) {
res.writeHead(301, {
'Content-Type': 'text/plain',
'Location': 'https://' + req.headers.host + req.url
});
res.end('Redirecting to SSL\n');
}).listen(80);
https.createServer(options, app).listen(443);