Подключение приложения Heroku к облачному сервису Atlas MongoDB

#node.js #mongodb #heroku

#node.js #mongodb #ssl #heroku #мангуст

Вопрос:

Предваряя вопрос: нужно ли мне получать поддержку SSL на Heroku, чтобы установить соединение между Heroku и Atlas MongoDB Cloud с использованием SSL? (Для доступа к облачному сервису Atlas MongoDB требуется подключение TSL / SSL).

Я пытаюсь подключить свое приложение Heroku, написанное на node.js , в кластер, размещенный в облаке Atlas MongoDB.

Моя текущая база данных размещена в mLab (как дополнение Heroku), а URI MongoDB, используемый для доступа к кластеру через mongoose, является (с использованием xxx для опускания конфиденциальной информации):

 MONGODB_URI="mongodb://xxx:xxx@xxx-a0.mlab.com:23266,xxx-a1.mlab.com:xxx/xxx?replicaSet=rs-xxx"
  

Теперь, когда я перенес свои данные из mLab в облако Atlas MongoDB, в настоящее время я получаю доступ к кластеру с помощью 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=xxxamp;ssl=trueamp;authSource=admin"
  

При локальном запуске моего приложения Heroku на моем компьютере я могу получить доступ к базе данных без проблем. Я также могу подключиться к кластеру с помощью оболочки mongo.

Однако при запуске приложения в Heroku соединение не может быть установлено. В консоли JS браузера я получаю сообщение о недоступности службы 503. В heroku я получаю сообщение об ошибке:

 no primary found in replica set
  

Я знаю, что для Atlas MongoDB Cloud требуется SSL-соединение, отличное от mLab. Я полагаю, что на моем локальном компьютере для успешного подключения к кластеру используется самозаверяющий сертификат.

Мой вопрос: нужно ли мне получать поддержку SSL в Heroku, чтобы иметь возможность доступа к установлению безопасного соединения между Heroku и MongoDB Atlas? Или поддержка SSL в Heroku требуется только для безопасного соединения клиент / Heroku?

Ответ №1:

Что, я думаю, может решить вашу проблему

Отказ от ответственности: я не использовал ни Heroku, ни MongoDB Atlas, но я изучаю их.

Согласно обнаруженной мной проблеме с Github, вы получите это сообщение об ошибке, если вы не внесли IP-адреса сервера в белый список в MongoDB Atlas.

Читая документы MongoDB Atlas, я вижу единственный способ сделать это в сочетании с Heroku dynos — добавить 0.0.0.0/0 (т. Е. Все адреса) в ваш белый список MongoDB Atlas.

Попробуйте и, пожалуйста, сообщите, можете ли вы создать экземпляр соединения.

По протоколу SSL

Пытаясь ответить на вопрос SSL, я не думаю, что вам нужно включать его в Heroku на основе того, что я прочитал, хотя я не совсем уверен.

Если сервер MongoDB выполнил проверку сертификата, Node.js код для подключения к нему должен выглядеть следующим образом (взят из Node.js документация по драйверу):

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

Если сервер MongoDB не проверяет наличие каких-либо SSL-сертификатов, вы можете просто использовать следующий код (также взятый из Node.js документация по драйверу):

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

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

Учитывая, что документация Atlas содержит следующий пример кода для подключения к нему из Node.js , я думаю, что вам не нужно включать SSL на Heroku:

 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=trueamp;replicaSet=Mycluster0-shard-0amp;authSource=admin";
MongoClient.connect(uri, function(err, db) {
  db.close();
});
  

Комментарии:

1. Никлас, ты был прав! Проблема заключалась в доступе к белому списку. Что касается вопроса SSL, я думаю, вы правы, потому что я получил следующий ответ от службы поддержки Herkou: «(…) использование SSL для приложения полностью отделено от подключения mongo, поэтому я не думаю, что это будет проблемой здесь».

2. Обновление ( источник ): поскольку операционные системы Heroku используют подмножество IP-адресов инстансов AWS EC2, можно добавить IP-адреса AWS в белый список Cloud Atlas или получить надстройку для предоставления статического исходящего IP-адреса или для использования защищенной связи через TLS.

3. Потрясающе! Спасибо за ответ, Бруно. 🙂

Ответ №2:

Вы можете найти все диапазоны IP для Heroku с помощью этой команды:

 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")
  

Комментарии:

1. Удивительный ответ. Если кто-то хочет сделать это вручную, поскольку у него нет apt — узнайте, какой у вас регион heroku, затем перейдите по ссылке ip-ranges.amazonaws.com/ip-ranges . json и найдите диапазон IP-адресов этого региона

Ответ №3:

Также пришлось добавить 0.0.0.0 / 0 в белый список IP-адресов Mongo и повторно развернуть мое приложение на Heroku, чтобы оно наконец заработало (перед изменением IP была выдана ошибка CORS).

Ответ №4:

очень простое решение! просто добавьте в белый список IP в mongo atlas адрес «0.0.0.0 / 0»

это откроет mongo atlas для всего мира ….. так что это ОС не для производства, но помогает для небольших тестов

Ответ №5:

Я решил эту проблему, установив дополнение (я использовал Fixie Socks) для статических IP-адресов для запросов к базе данных и других TCP-соединений. Дополнительные опции здесь: https://elements.heroku.com/addons#network

Комментарии:

1. Спасибо за обмен, кажется полезным. Бесплатный уровень составляет 100 запросов в месяц 100 МБ, звучит низко, что считается «запросом»?

2. Можете ли вы поделиться некоторым кодом о том, как вы это сделали? Я пытаюсь понять, что мне нужно изменить в моем node.js введите код, чтобы использовать носки fixie и подключиться через mongoose.

3. Также хотелось бы это увидеть. Я также отправил по электронной почте Fixie Socks ранее сегодня.

4. Я рассматривал возможность использования Fixie Socks, но это было только для региона США

5. Исправленные носки сработали? Я пытаюсь выполнить ту же настройку, и она каждый раз терпит неудачу.

Ответ №6:

Поскольку разрешение доступа из любого места небезопасно, и диапазоны IP-адресов могут меняться, в итоге я установил дополнение QuotaGuard Static IP's (оно предоставляет 2 IP-адреса для белого списка IP), чтобы прокси SOCKS5 можно было использовать с QGTunnel.

QGTunnel должен быть загружен и включен в кодовую базу

 curl https://s3.amazonaws.com/quotaguard/qgtunnel-latest.tar.gz | tar xz
  

Procfile должен быть обновлен

 web: bin/qgtunnel npm start
  

Допустим, вы хотите получить доступ к реплицированному кластеру MongoDB с помощью QGTunnel с 3 репликами, расположенными на хостах: rs01.mongodb.net:52115 , rs02.mongodb.net:52115 , и rs1.mongodb.net:52115 . Для этой конфигурации вам нужно будет создать 3 отдельных туннеля для каждого хоста на порту 52115 в прозрачном режиме. Как только это будет сделано, QGTunnel изменит процесс разрешения DNS, чтобы преобразовать эти имена хостов в соответствующий адрес обратной связи, и автоматическое обнаружение для вашего реплицируемого кластера должно работать должным образом.