Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用Node.js通过SSL连接到MongoDB_Javascript_Node.js_Mongodb_Ssl - Fatal编程技术网

Javascript 使用Node.js通过SSL连接到MongoDB

Javascript 使用Node.js通过SSL连接到MongoDB,javascript,node.js,mongodb,ssl,Javascript,Node.js,Mongodb,Ssl,如何使用Node.js通过SSL连接到MongoDB服务器 我已经阅读了一些驱动程序(,)的源代码,现在我已经在谷歌上搜索了一段时间,但似乎找不到任何合适的教程、指南或文档。正如评论中所建议的那样,节点mongodb native提供了所需的一切 我使用以下命令将其启动并运行: var mongo = require('mongodb'); var server = new mongo.Server('HOSTNAME', 27017, { ssl: true }); var db = new

如何使用Node.js通过SSL连接到MongoDB服务器


我已经阅读了一些驱动程序(,)的源代码,现在我已经在谷歌上搜索了一段时间,但似乎找不到任何合适的教程、指南或文档。

正如评论中所建议的那样,
节点mongodb native
提供了所需的一切

我使用以下命令将其启动并运行:

var mongo = require('mongodb');

var server = new mongo.Server('HOSTNAME', 27017, { ssl: true });
var db = new mongo.Db('NAME_OF_MY_DB', server, { w: 1 });
var auth = { user: 'USERNAME', pass: 'PASSWORD' };

db.open(function(err, db) {
  if (err) return console.log("error opening", err);

  db.authenticate(auth.user, auth.pass, function(err, result) {
    if (err) return console.log("error authenticating", err);

    console.log("authed?", result);

    db.collection('whatever').count(function(err, count) {
      if (err) return console.log("error counting", err);

      console.log("count", count);
      db.close()
    });
  });
});
编辑

您还可以从以下位置执行ssl:


如果要使用证书进行身份验证,请使用
节点mongodb native

var buffer = require('fs').readFileSync("mongodb.pem");
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://hostname:27017/test?ssl=true", {
    sslKey: buffer,
    sslCert: buffer,
    sslValidate: false //in case of self-generated certificate
}, function(err, db) {
    console.log(err);
    console.log(db);
    db.close();
});
步骤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
sudo vi /etc/mongod.conf
并修改“#网络接口”部分,如下所示:

# network interfaces
net:
  port: 27017
  #bindIp: 127.0.0.1
  ssl:
    mode: allowSSL
    PEMKeyFile: /etc/ssl/mongodb.pem
    #CAFile: /etc/ssl/mongodb-cert.crt
# 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
请注意:我们正在对
bindIp
进行注释。这允许外部连接访问您的Mongo数据库。我们假设这是您的最终目标(为什么要在localhost上加密流量?),但您应该在为MongoDB服务器设置授权规则之后才这样做

CAFile也被注释掉,因为它是可选的。在这篇文章的结尾,我将解释如何建立证书颁发机构信任

一如既往,在配置文件更改生效之前,必须重新启动MongoDB:

sudo service mongod restart
你的服务器启动失败了吗?您只能靠自己,但您的证书文件可能有问题。您可以通过手动运行
mongod
来检查启动错误:

sudo mongod --config /etc/mongod.conf
步骤4:测试服务器设置 在处理节点配置之前,让我们通过连接
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
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
步骤5:配置Node.JS/Mongoose 如果在节点应用程序中使用
节点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 = {
          "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
配置 并修改“#网络接口”部分,如下所示:

# network interfaces
net:
  port: 27017
  #bindIp: 127.0.0.1
  ssl:
    mode: allowSSL
    PEMKeyFile: /etc/ssl/mongodb.pem
    #CAFile: /etc/ssl/mongodb-cert.crt
# 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客户端还可以传入CA文件,以验证它们是否正在与正确的服务器进行通信。这是通过
--sslCAFile
参数完成的

配置了CAFile的Mongo服务器要求客户端拥有有效的证书和服务器的私钥。在mongo shell客户端中,这是通过传入
--sslPEMKeyFile
参数来完成的

如果没有PEM文件(包含服务器的证书),您可能会看到以下错误:

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
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 这里有两个陷阱,请容忍我

首先,您需要有
节点mongodb native
2.0
或更高版本。如果您使用的是Mongoose,则需要Mongoose
4.0
或更高版本。以前的Mongoose版本使用
节点mongodb native
1.*
,它不支持任何身份的证书验证

其次,在node mongodb native中没有可用的
sslAllowInvalidHostnames
或类似选项。这不是
node mongodb native
开发人员可以解决的问题(我现在已经解决了),因为node 0.10.*中提供的native TLS库不提供此选项。在节点4.*和5.*中,有一个
checkServerIdentity
选项提供了希望,但是在io.js合并后从原始节点分支切换到分支可能会在当前引起一些头痛

让我们试试这个:

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')
      }
    }
  ;


您可能对
mongodb ssl node.js
的第二个结果感兴趣。。我开始胡闹,但没能成功。我会再试一次。投票结束的主持人:真的吗?这与编程无关吗?让我们永远不要写连接到数据库的代码。可能的重复肯定是d