Подключение к MongoDB через SSL с узлом.Яш
Как подключиться к MongoDB-серверу через SSL с помощью узла.Яш?
Я прочитал источники нескольких драйверов (mongojs, mongodb-родной) и я уже давно гуглю, но, похоже, не могу найти никаких правильных учебников, руководств или документов.
3 ответов
Шаг 1: Получить MongoDB 3.0
первое, что вам нужно знать, это то, что SSL поддерживается только из коробки MongoDB 3.0 и более поздних версий. 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 долларов из сертификата Authroity или генерируется с 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.ключ-это файл закрытого ключа и mongodb-cert.crt - это файл сертификата, который также может использоваться в качестве файла CA. ВАМ ПОНАДОБЯТСЯ ВСЕ ТРИ.
Шаг 3: Настройка MongoD
мы будем считать, что вы скопировали эти файлы в папку/etc/ ssl/, где они принадлежат. Теперь мы открываем наш файл конфигурации MongoDB:
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
обратите внимание: мы комментируем 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
Шаг 5) Настройка Узла.JS / Мангуст
если вы используете пакет node-mongodb-native в приложении Node немедленно прекратите и начните использовать Мангуста. Это не так уж сложно. Тем не менее, Мангуст.connect () имеет практически тот же API, что и mongodb.connect (), поэтому замените соответствующим образом.
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 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 это делается путем передачи в --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
сервер можно настроить для приема запросов от клиентов без PEM-файла, включив net.использование SSL.weakCertificateValidation, но вы будете ослабление безопасности никакой реальной выгоды.
Шаг 6.5) Настройка Узла.JS / Мангуст
здесь есть пара gotchas, так что потерпите со мной.
во-первых, вам нужно имейте node-mongodb-native 2.0 или более поздней версии. Если вы используете Мангуст, то вам нужен Мангуст 4.0 или более поздней версии. В предыдущих версиях Mongoose используется node-mongodb-native 1.* который не поддерживает проверку сертификатов в любом качестве.
во-вторых, в node-mongodb-native нет sslAllowInvalidHostnames или аналогичной опции. Это не то, что могут исправить разработчики node-mongodb-native (я бы уже), потому что собственная библиотека TLS доступна в узле 0.10.* не предлагает выбора для этого. В Узле 4.* и 5.* , есть опция checkServerIdentity, которая предлагает надежду, но переключение с исходной ветви узла на ветвь после ввода-вывода.слияние 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')
}
}
;
источник: http://www.bainweb.com/2015/11/connecting-to-mongodb-over-tlsssl-with.html
как предложено в комментариях,node-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 из мангуста:
mongoose.createConnection(connString, { server: { ssl: true }})
Если вы хотите аутентифицировать с помощью сертификата, используя node-mongodb-native
:
var buffer = require('fs').readFileSync("mongodb.pem");
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://hostname:27017/test?ssl=true", {
server: {
sslKey: buffer,
sslCert: buffer,
sslValidate: false //in case of self-generated certificate
}
}, function(err, db) {
console.log(err);
console.log(db);
db.close();
});