将Heroku App连接到Atlas MongoDB Cloud服务

Bru*_*ral 18 ssl heroku mongoose mongodb node.js

要解决这个问题:我是否需要在Heroku 上获得SSL支持,以便使用SSL 在HerokuAtlas MongoDB Cloud之间建立连接?(TSL/SSL连接是访问Atlas MongoDB Cloud服务的必要条件).


我正在尝试将以node.js编写的Heroku应用程序连接到Atlas MongoDB Cloud托管的集群.

我当前的数据库托管在mLab(作为Heroku Add-on),用于通过mongoose访问集群的MongoDB URI是(使用xxx省略机密信息):

MONGODB_URI="mongodb://xxx:xxx@xxx-a0.mlab.com:23266,xxx-a1.mlab.com:xxx/xxx?replicaSet=rs-xxx"
Run Code Online (Sandbox Code Playgroud)

现在我已将我的数据从mLab迁移到Atlas MongoDB Cloud,我目前正在使用URI访问集群:

MONGODB_URI="mongodb://xxx:xxx@cluster0-shard-xxx.mongodb.net:xxx,cluster0-shard-xxx.mongodb.net:xxx,cluster0-shard-xxx.mongodb.net:xxx/xxx?replicaSet=xxx&ssl=true&authSource=admin"
Run Code Online (Sandbox Code Playgroud)

在我的机器本地运行我的Heroku应用程序时,我可以毫无问题地访问数据库.我也可以使用mongo shell连接到集群.

但是,在Heroku中运行App时,无法建立连接.在Browser JS控制台中,我收到503服务不可用消息.在heroku中,我收到错误:

no primary found in replica set
Run Code Online (Sandbox Code Playgroud)

我知道Atlas MongoDB Cloud需要SSL连接,与mLab不同.在我的本地计算机中,我认为正在使用自签名证书成功连接到群集.

我的问题是:我是否需要在Heroku中获得SSL支持才能访问在Heroku和MongoDB Atlas之间建立安全连接?或者Heroku中的SSL支持只需要客户端/ Heroku安全连接?

小智 24

我认为可以解决你的问题

免责声明:我既没使用Heroku也没使用MongoDB Atlas,但我正在调查它们.

根据我发现[1]的Github问题,如果您没有将MongoDB Atlas中的服务器IP地址列入白名单,您将收到该错误消息.

阅读MongoDB Atlas docs [2],我认为与Heroku dynos结合使用的唯一方法是将0.0.0.0/0(即所有地址)添加到MongoDB Atlas白名单中.

尝试一下,请报告您是否可以实例化连接.

在SSL上

试图回复SSL问题,我不认为你需要根据我读到的内容在Heroku上启用它,虽然我不完全确定.

如果MongoDB服务器执行了证书验证,则用于连接它的Node.js代码必须如下所示(取自Node.js驱动程序文档[3]):

var MongoClient = require('mongodb').MongoClient,
  f = require('util').format,
  fs = require('fs');

// Read the certificates
var ca = [fs.readFileSync(__dirname + "/ssl/ca.pem")];
var cert = fs.readFileSync(__dirname + "/ssl/client.pem");
var key = fs.readFileSync(__dirname + "/ssl/client.pem");

// Connect validating the returned certificates from the server
MongoClient.connect("mongodb://localhost:27017/test?ssl=true", {
  server: {
      sslValidate:true
    , sslCA:ca
    , sslKey:key
    , sslCert:cert
    , sslPass:'10gen'
  }
}, function(err, db) {
  db.close();
});
Run Code Online (Sandbox Code Playgroud)

如果MongoDB服务器没有检查任何SSL证书,您可以简单地使用如下代码(也取自Node.js驱动程序文档[3]):

var MongoClient = require('mongodb').MongoClient;

MongoClient.connect("mongodb://localhost:27017/test?ssl=true", function(err, db) {
  db.close();
});
Run Code Online (Sandbox Code Playgroud)

鉴于阿特拉斯文档[4]中包含用于连接到它的Node.js下面的示例代码,我认为你不是要在Heroku上启用SSL:

var MongoClient = require('mongodb').MongoClient;

var uri = "mongodb://kay:myRealPassword@mycluster0-shard-00-00-wpeiv.mongodb.net:27017,mycluster0-shard-00-01-wpeiv.mongodb.net:27017,mycluster0-shard-00-02-wpeiv.mongodb.net:27017/admin?ssl=true&replicaSet=Mycluster0-shard-0&authSource=admin";
MongoClient.connect(uri, function(err, db) {
  db.close();
});
Run Code Online (Sandbox Code Playgroud)
var MongoClient = require('mongodb').MongoClient,
  f = require('util').format,
  fs = require('fs');

// Read the certificates
var ca = [fs.readFileSync(__dirname + "/ssl/ca.pem")];
var cert = fs.readFileSync(__dirname + "/ssl/client.pem");
var key = fs.readFileSync(__dirname + "/ssl/client.pem");

// Connect validating the returned certificates from the server
MongoClient.connect("mongodb://localhost:27017/test?ssl=true", {
  server: {
      sslValidate:true
    , sslCA:ca
    , sslKey:key
    , sslCert:cert
    , sslPass:'10gen'
  }
}, function(err, db) {
  db.close();
});
Run Code Online (Sandbox Code Playgroud)

  • **更新([来源](https://kb.heroku.com/i-need-to-whitelist-heroku-dynos-what-are-ip-address-ranges-in-use-at-heroku)):**当Heroku dynos使用IP范围的AWS EC2实例的子集时,可以添加[AWS IP范围](http://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges. html)到Cloud Atlas的白名单,或获取附加组件以提供静态出站IP地址,或通过TLS使用安全通信. (12认同)
  • 尼克拉斯,你是对的!问题出在白名单访问中.关于SSL问题,我猜你是对的,因为我从Herkou的支持得到了以下回复:"(...)使用SSL为应用程序完全独立于mongo连接,所以我不认为这将是一个问题在这里." (3认同)

ehp*_*hpc 6

您可以使用以下命令查找 Heroku 的所有 IP 范围:

HEROKU_REGION=eu; sudo apt -qqy install curl jq 2>/dev/null 1>/dev/null; heroku regions --json 2>/dev/null | jq ".[] | select(.name==\"$HEROKU_REGION\") | .provider.region" | (REGION=$(cat); curl -s https://ip-ranges.amazonaws.com/ip-ranges.json |  jq ".prefixes[] | select(.region==$REGION) | .ip_prefix")
Run Code Online (Sandbox Code Playgroud)