sql >> Databasteknik >  >> NoSQL >> MongoDB

Ansluter till MongoDB över SSL med Node.js

Steg 1:Skaffa MongoDB 3.0

Det första du behöver veta är att SSL endast stöds direkt av MongoDB 3.0 och senare. Ubuntu har inte 3.0 i standardförråden, så här är hur du får det:

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 är den senaste stabila versionen från och med nu, men ersätt gärna 3.0.7 med din favoritversion.

Steg 2:Skaffa privat nyckel, certifikat och PEM-filer

PEM innehåller ett Public Key-certifikat och dess tillhörande privata nyckel. Dessa filer kan antingen erhållas med IRL-dollar från en certifikatmyndighet eller genereras med OpenSSL så här:

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 kommer att användas som PEM-fil, mongodb-cert.key är den privata nyckelfilen och mongodb-cert.crt är certifikatfil som också kan användas som CA-fil. DU BEHÖVER ALLA TRE DESSA.

Steg 3:Konfigurera MongoD

Vi kommer att anta att du kopierade dessa filer till din /etc/ssl/-mapp där de hör hemma. Nu öppnar vi vår MongoDB-konfigurationsfil:

sudo vi /etc/mongod.conf

och ändra avsnittet "# nätverksgränssnitt" så här:

# network interfaces
net:
  port: 27017
  #bindIp: 127.0.0.1
  ssl:
    mode: allowSSL
    PEMKeyFile: /etc/ssl/mongodb.pem
    #CAFile: /etc/ssl/mongodb-cert.crt

OBS :vi kommenterar bindIp . DETTA MÅTAR EXTERNA ANSLUTNINGAR för att komma åt din Mongo-databas. Vi antar att detta är ditt slutmål (Varför skulle du kryptera trafik på localhost? ), men du bör bara göra detta EFTER att du har ställt in AUKTORISERINGSREGLER för din MongoDB-server.

CAFilen kommenteras också eftersom den är valfri. Jag kommer att förklara hur man ställer in Certificate Authority trust i slutet av det här inlägget.

Som alltid måste du starta om MongoDB innan ändringar av konfigurationsfilen träder i kraft:

sudo service mongod restart

HAR DIN SERVER INTE STARTA? Du är ensam, men det finns förmodligen ett problem med dina certifikatfiler. Du kan kontrollera startfel genom att köra mongod manuellt:

sudo mongod --config /etc/mongod.conf

Steg 4:Testa dina serverinställningar

Innan vi går och bråkar med nodkonfigurationer, låt oss se till att din serverinstallation fungerar korrekt genom att ansluta med mongo kommandoradsklient:

mongo --ssl --sslAllowInvalidHostnames --sslAllowInvalidCertificates

Såvida inte domännamnet på ditt certifikat är 127.0.0.1 eller localhost , --sslAllowInvalidHostnames flagga är nödvändig. Utan det kommer du förmodligen att få det här felet:

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

Steg 5:Konfigurera Node.JS / Mongoose

Om du använder node-mongodb-native paket i din Node-applikation, sluta omedelbart och börja använda Mongoose. Det är inte så svårt. Som sagt, mongoose.connect() har praktiskt taget samma API som mongodb.connect() , så ersätt på lämpligt sätt.

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

Steg 6:[Valfritt] verifiera dina certifikat via en certifikatutfärdare

För att validera dina SSL-certifikat måste du skaffa en CA (eller paket ) fil från din certifikatutfärdare. Detta kommer att likna din certifikatfil, men kommer ofta att innehålla flera certifikat (som bildar en förtroendekedja för att verifiera att ett certifikat är giltigt ). Om du använder ett självsignerat certifikat kan du använda ditt mongodb-cert.crt som en CA-fil.

Du måste också se till att din MongoDB-servers värdnamn matchar det som användes för att skapa certifikatet.

Steg 6.3:Uppdatera din mongod konfiguration

sudo vi /etc/mongod.conf

och ändra avsnittet "# nätverksgränssnitt" så här:

# 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

Steg 6.4:Testa dina serverinställningar

mongo --ssl --sslAllowInvalidHostnames --sslCAFile /etc/ssl/mongodb-ca.crt --sslPEMKeyFile /etc/ssl/mongodb.pem

Mongo-klienter kan även skicka in CA-filen för att verifiera att de pratar med rätt server. Detta görs med --sslCAFile parameter

Mongo-servrar konfigurerade med en CAFile kräver att klienter har ett giltigt certifikat OCH den privata nyckeln för servern. I mongo shell-klienten görs detta genom att skicka in --sslPEMKeyFile parameter.

Utan en PEM-fil (som innehåller serverns certifikat ), kan du se detta fel:

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

Servern kan konfigureras för att acceptera förfrågningar från klienter utan en PEM-fil genom att aktivera net.ssl.weakCertificateValidation , men du kommer att försvaga din säkerhet utan någon verklig vinst.

Steg 6.5:Konfigurera Node.JS / Mongoose

Det finns ett par gotchas här, så ha ut med mig.

Först MÅSTE du ha node-mongodb-native 2.0 eller senare. Om du använder Mongoose, så BEHÖVER du Mongoose 4.0 eller senare. Tidigare Mongoose-versioner använder node-mongodb-native 1.* som inte stöder certifikatvalidering i någon egenskap.

För det andra finns det inga sslAllowInvalidHostnames eller liknande alternativ tillgängligt i node-mongodb-native. Det här är inget som är node-mongodb-native utvecklare kan fixa (jag skulle ha gjort det vid det här laget ) eftersom det ursprungliga TLS-biblioteket som är tillgängligt i Node 0.10.* inte erbjuder något alternativ för detta. I Nod 4.* och 5.* finns en checkServerIdentity alternativ som ger hopp, men att byta från den ursprungliga nodgrenen till grenen efter sammanslagningen av io.js kan orsaka lite huvudvärk just nu.

Så låt oss prova detta:

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

Om du får fel på värdnamn/IP-fel, åtgärda antingen ditt certifikat eller förneka allt detta hårda arbete genom att inaktivera 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')
      }
    }
  ;

Källa



  1. Aggregate $lookup returnerar inte elementens ursprungliga arrayordning

  2. MongoDB findOneAndReplace()

  3. Hur konfigurerar man MongoDB Java-drivrutin MongoOptions för produktionsanvändning?

  4. Hur kan jag köra MongoDB som en Windows-tjänst?