MongoDb 和 nodejs SSl/Secure 连接

MongoDb and nodejs SSl/Secure Connection

如何通过 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;

任何帮助和建议

使用下面的链接在您的 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);

第一步:获取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 包含一个 Public 密钥证书及其关联的私钥。这些文件可以从证书颁发机构使用 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 interfaces”部分:

# 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 数据库。我们假设这是您的最终目标(为什么要在本地主机上加密流量?),但您应该只在为您的 Mongo 数据库服务器设置授权规则后执行此操作。

CAFile 也被注释掉,因为它是可选的。我将在本post.

的最后解释如何设置证书颁发机构信任

与往常一样,您必须重新启动 MongoDB 才能使配置文件更改生效:

sudo service mongod restart

您的服务器启动失败了吗?您是一个人,但您的证书文件可能有问题。您可以通过 运行 mongod 手动检查启动错误:

sudo mongod --config /etc/mongod.conf

第 4 步:测试您的服务器设置

在我们搞乱节点配置之前,让我们通过连接 mongo 命令行客户端来确保您的服务器设置正常工作:

mongo --ssl --sslAllowInvalidHostnames --sslAllowInvalidCertificates

除非证书上的域名是 127.0.0.1 或本地主机,否则 --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 interfaces”部分:

# 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 参数

完成的

Mongo 配置了 CAFile 的服务器要求客户端拥有服务器的有效证书和私钥。在 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 选项提供了希望,但是从原来的 Node 分支切换到 io.js merge 之后的分支在当前可能会有点头疼。

让我们试试这个:

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

如果您收到 hostname/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