MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Verbindung zu MongoDB über SSL mit Node.js

Schritt 1:Besorgen Sie sich MongoDB 3.0

Als Erstes müssen Sie wissen, dass SSL standardmäßig nur von MongoDB 3.0 und höher unterstützt wird. Ubuntu hat 3.0 nicht in den Standard-Repositories, also bekommst du es so:

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 ist ab sofort die neueste stabile Version, aber Sie können 3.0.7 gerne durch Ihre Lieblingsversion ersetzen.

Schritt 2:Private Key-, Zertifikat- und PEM-Dateien abrufen

Das PEM enthält ein Public-Key-Zertifikat und seinen zugehörigen privaten Schlüssel. Diese Dateien können entweder mit IRL-Dollar von einer Zertifizierungsstelle bezogen oder wie folgt mit OpenSSL generiert werden:

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 wird als PEM-Datei verwendet, mongodb-cert.key ist die private Schlüsseldatei und mongodb-cert.crt ist eine Zertifikatsdatei, die auch als CA-Datei verwendet werden kann. SIE BRAUCHEN ALLE DREI VON DIESEN.

Schritt 3:MongoD konfigurieren

Wir gehen davon aus, dass Sie diese Dateien in Ihren /etc/ssl/-Ordner kopiert haben, wo sie hingehören. Jetzt öffnen wir unsere MongoDB-Konfigurationsdatei:

sudo vi /etc/mongod.conf

und ändern Sie den Abschnitt "# Netzwerkschnittstellen" wie folgt:

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

BITTE BEACHTEN :wir kommentieren bindIp aus . DIES ERLAUBT EXTERNEN VERBINDUNGEN den Zugriff auf Ihre Mongo-Datenbank. Wir gehen davon aus, dass dies Ihr Endziel ist (Warum sollte Ihr Datenverkehr auf localhost verschlüsselt werden? ), aber Sie sollten dies nur NACH DEM EINRICHTEN DER AUTORISIERUNGSREGELN für Ihren MongoDB-Server tun.

Die CA-Datei ist ebenfalls auskommentiert, da sie optional ist. Ich werde am Ende dieses Beitrags erklären, wie man das Vertrauen der Zertifizierungsstelle einrichtet.

Wie immer müssen Sie MongoDB neu starten, bevor die Änderungen an der Konfigurationsdatei wirksam werden:

sudo service mongod restart

KONNTE IHR SERVER NICHT STARTEN? Sie sind auf sich allein gestellt, aber wahrscheinlich liegt ein Problem mit Ihren Zertifikatsdateien vor. Sie können Startfehler überprüfen, indem Sie mongod ausführen manuell:

sudo mongod --config /etc/mongod.conf

Schritt 4:Testen Sie Ihre Servereinstellungen

Bevor wir uns mit Node-Konfigurationen herumschlagen, stellen wir sicher, dass Ihr Server-Setup ordnungsgemäß funktioniert, indem Sie sich mit dem mongo verbinden Befehlszeilen-Client:

mongo --ssl --sslAllowInvalidHostnames --sslAllowInvalidCertificates

Es sei denn, der Domänenname auf Ihrem Zertifikat lautet 127.0.0.1 oder localhost , die --sslAllowInvalidHostnames Flagge ist notwendig. Ohne sie erhalten Sie wahrscheinlich diesen Fehler:

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

Schritt 5:Node.JS / Mongoose konfigurieren

Wenn Sie die Datei node-mongodb-native verwenden Paket in Ihrer Node-Anwendung, stoppen Sie sofort und beginnen Sie mit der Verwendung von Mongoose. Es ist nicht so schwer. Das heißt, mongoose.connect() hat praktisch die gleiche API wie mongodb.connect() , also entsprechend ersetzen.

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

Schritt 6:[Optional] Ihre Zertifikate über eine Zertifizierungsstelle verifizieren

Um Ihre SSL-Zertifikate zu validieren, benötigen Sie eine Zertifizierungsstelle (oder Bundle )-Datei von Ihrer Zertifizierungsstelle. Diese sieht Ihrer Zertifikatsdatei sehr ähnlich, enthält jedoch häufig mehrere Zertifikate (die eine Vertrauenskette bilden, um zu überprüfen, ob ein Zertifikat gültig ist ). Wenn Sie ein selbstsigniertes Zertifikat verwenden, können Sie Ihre mongodb-cert.crt verwenden als CA-Datei.

Sie müssen außerdem sicherstellen, dass der Hostname Ihres MongoDB-Servers mit dem übereinstimmt, der zum Erstellen des Zertifikats verwendet wurde.

Schritt 6.3:Aktualisieren Sie Ihren mongod Konfiguration

sudo vi /etc/mongod.conf

und ändern Sie den Abschnitt "# Netzwerkschnittstellen" wie folgt:

# 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

Schritt 6.4:Testen Sie Ihre Servereinstellungen

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

Mongo-Clients können die CA-Datei ebenfalls übergeben, um zu überprüfen, ob sie mit dem richtigen Server kommunizieren. Dies geschieht mit --sslCAFile Parameter

Mongo-Server, die mit einer CA-Datei konfiguriert sind, erfordern, dass Clients ein gültiges Zertifikat besitzen UND den privaten Schlüssel für den Server. Im Mongo-Shell-Client erfolgt dies durch Übergabe von --sslPEMKeyFile Parameter.

Ohne eine PEM-Datei (die das Zertifikat des Servers enthält ), wird möglicherweise dieser Fehler angezeigt:

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

Der Server kann so konfiguriert werden, dass er Anfragen von Clients ohne PEM-Datei akzeptiert, indem net.ssl.weakCertificateValidation aktiviert wird , aber Sie werden Ihre Sicherheit ohne wirklichen Gewinn schwächen.

Schritt 6.5:Node.JS / Mongoose konfigurieren

Hier gibt es ein paar Fallstricke, also haben Sie Geduld mit mir.

Zuerst MÜSSEN Sie node-mongodb-native haben 2.0 oder später. Wenn Sie Mongoose verwenden, BENÖTIGEN Sie Mongoose 4.0 oder später. Frühere Mongoose-Versionen verwenden node-mongodb-native 1.* die Zertifikatvalidierung in keiner Weise unterstützt.

Zweitens gibt es keine sslAllowInvalidHostnames oder eine ähnliche Option, die in node-mongodb-native verfügbar ist. Dies ist nicht etwas, das node-mongodb-native ist Entwickler beheben können (hätte ich inzwischen ), da die in Node 0.10.* verfügbare native TLS-Bibliothek dafür keine Option bietet. In Knoten 4.* und 5.* gibt es eine checkServerIdentity Option, die Hoffnung macht, aber der Wechsel vom ursprünglichen Node-Zweig zum Zweig nach dem io.js-Merge kann derzeit etwas Kopfzerbrechen bereiten.

Versuchen wir also Folgendes:

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

Wenn Sie Hostname/IP-Nichtübereinstimmungsfehler erhalten, reparieren Sie entweder Ihr Zertifikat oder negieren all diese harte Arbeit, indem Sie sslValidate deaktivieren :

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

Quelle