MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Connexion à MongoDB via SSL avec Node.js

Étape 1 :Obtenir MongoDB 3.0

La première chose que vous devez savoir est que ce SSL n'est pris en charge que par MongoDB 3.0 et versions ultérieures. Ubuntu n'a pas la version 3.0 dans les référentiels par défaut, alors voici comment l'obtenir :

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

La 3.0.7 est la dernière version stable à ce jour, mais n'hésitez pas à remplacer la 3.0.7 par votre version préférée.

Étape 2 :Obtenir la clé privée, le certificat et les fichiers PEM

Le PEM contient un certificat de clé publique et sa clé privée associée. Ces fichiers peuvent soit être obtenus avec des dollars IRL auprès d'une autorité de certification, soit générés avec OpenSSL comme ceci :

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 sera utilisé comme fichier PEM, mongodb-cert.key est le fichier de clé privée et mongodb-cert.crt est le fichier de certificat qui peut également être utilisé comme fichier CA. VOUS AUREZ BESOIN DE CEUX-CI.

Étape 3 :Configurer MongoD

Nous allons supposer que vous avez copié ces fichiers dans votre dossier /etc/ssl/ où ils appartiennent. Maintenant, nous ouvrons notre fichier de configuration MongoDB :

sudo vi /etc/mongod.conf

et modifiez la section "# interfaces réseau" comme suit :

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

VEUILLEZ NOTER :nous commentons bindIp . CELA PERMET AUX CONNEXIONS EXTERNES d'accéder à votre base de données Mongo. Nous supposons qu'il s'agit de votre objectif final (Pourquoi chiffreriez-vous le trafic sur localhost ? ), mais vous ne devriez le faire qu'APRÈS AVOIR CONFIGURÉ LES RÈGLES D'AUTORISATION pour votre serveur MongoDB.

Le CAFile est également commenté car il est facultatif. J'expliquerai comment configurer la confiance de l'autorité de certification à la fin de cet article.

Comme toujours, vous devez redémarrer MongoDB avant que les modifications du fichier de configuration ne prennent effet :

sudo service mongod restart

VOTRE SERVEUR N'A-T-IL PAS DÉMARRÉ ? Vous êtes seul, mais il y a probablement un problème avec vos fichiers de certificat. Vous pouvez vérifier les erreurs de démarrage en exécutant mongod manuellement :

sudo mongod --config /etc/mongod.conf

Étape 4 :Testez les paramètres de votre serveur

Avant de jouer avec les configurations de nœud, assurons-nous que la configuration de votre serveur fonctionne correctement en vous connectant avec le mongo client en ligne de commande :

mongo --ssl --sslAllowInvalidHostnames --sslAllowInvalidCertificates

Sauf si le nom de domaine sur votre certificat est 127.0.0.1 ou localhost , le --sslAllowInvalidHostnames le drapeau est nécessaire. Sans cela, vous obtiendrez probablement cette erreur :

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

Étape 5 :Configurer Node.JS / Mongoose

Si vous utilisez le node-mongodb-native package dans votre application Node, arrêtez immédiatement et commencez à utiliser Mongoose. Ce n'est pas si dur. Cela dit, mongoose.connect() a pratiquement la même API que mongodb.connect() , alors remplacez-le de manière appropriée.

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

Étape 6 :[Facultatif] vérifiez vos certificats via une autorité de certification

Afin de valider vos certificats SSL, vous devez obtenir une autorité de certification (ou un bundle ) de votre autorité de certification. Cela ressemblera beaucoup à votre fichier de certificat, mais contiendra souvent plusieurs certificats (qui forment une chaîne de confiance pour vérifier qu'un certificat est valide ). Si vous utilisez un certificat auto-signé, vous pouvez utiliser votre mongodb-cert.crt en tant que fichier CA.

Vous devrez également vous assurer que le nom d'hôte de votre serveur MongoDB correspond à celui utilisé pour créer le certificat.

Étape 6.3 :Mettez à jour votre mongod configuration

sudo vi /etc/mongod.conf

et modifiez la section "# interfaces réseau" comme suit :

# 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

Étape 6.4 :Testez les paramètres de votre serveur

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

Les clients Mongo peuvent également transmettre le fichier CA pour vérifier qu'ils parlent au bon serveur. Cela se fait avec le --sslCAFile paramètre

Les serveurs Mongo configurés avec un CAFile exigent que les clients possèdent un certificat valide ET la clé privée du serveur. Dans le client shell mongo, cela se fait en transmettant le --sslPEMKeyFile paramètre.

Sans fichier PEM (qui contient le certificat du serveur ), vous pouvez voir cette erreur :

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

Le serveur peut être configuré pour accepter les demandes des clients sans fichier PEM en activant net.ssl.weakCertificateValidation , mais vous affaiblirez votre sécurité sans réel gain.

Étape 6.5 :Configurer Node.JS / Mongoose

Il y a quelques pièges ici, alors soyez indulgent avec moi.

Tout d'abord, vous DEVEZ avoir node-mongodb-native 2.0 ou plus tard. Si vous utilisez Mongoose, alors vous AVEZ BESOIN de Mongoose 4.0 ou plus tard. Les versions précédentes de Mongoose utilisent node-mongodb-native 1.* qui ne prend pas en charge la validation des certificats à quelque titre que ce soit.

Deuxièmement, il n'y a pas de sslAllowInvalidHostnames ou une option similaire disponible dans node-mongodb-native. Ce n'est pas quelque chose que node-mongodb-native les développeurs peuvent corriger (je l'aurais déjà fait ) car la bibliothèque TLS native disponible dans Node 0.10.* n'offre aucune option pour cela. Dans Node 4.* et 5.*, il y a un checkServerIdentity option qui offre de l'espoir, mais le passage de la branche Node d'origine à la branche après la fusion io.js peut causer un peu de mal de tête à l'heure actuelle.

Alors essayons ceci :

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

Si vous obtenez des erreurs de non-concordance de nom d'hôte/IP, corrigez votre certificat ou annulez tout ce travail acharné en désactivant 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')
      }
    }
  ;

Source