MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Łączenie się z MongoDB przez SSL za pomocą Node.js

Krok 1:Uzyskaj MongoDB 3.0

Pierwszą rzeczą, którą musisz wiedzieć, jest to, że SSL jest obsługiwany tylko przez MongoDB 3.0 i nowsze. Ubuntu nie ma wersji 3.0 w domyślnych repozytoriach, więc oto jak go zdobyć:

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 to najnowsza stabilna wersja od teraz, ale możesz zastąpić 3.0.7 swoją ulubioną wersją.

Krok 2:Uzyskaj klucz prywatny, certyfikat i pliki PEM

PEM zawiera certyfikat klucza publicznego i powiązany z nim klucz prywatny. Pliki te można uzyskać za dolary IRL z urzędu certyfikacji lub wygenerować za pomocą OpenSSL w następujący sposób:

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 zostanie użyty jako plik PEM, mongodb-cert.key to plik klucza prywatnego, a mongodb-cert.crt to plik certyfikatu, który może być również użyty jako plik CA. POTRZEBUJESZ WSZYSTKICH TRZECH.

Krok 3:Skonfiguruj MongoD

Zakładamy, że skopiowałeś te pliki do folderu /etc/ssl/, do którego należą. Teraz otwieramy nasz plik konfiguracyjny MongoDB:

sudo vi /etc/mongod.conf

i zmodyfikuj sekcję „# interfejsy sieciowe” w następujący sposób:

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

PROSZĘ ZWRÓCIĆ UWAGĘ :komentujemy bindIp . UMOŻLIWIA TO ZEWNĘTRZNYM POŁĄCZeniom dostęp do bazy danych Mongo. Zakładamy, że jest to Twój cel końcowy (Dlaczego miałbyś szyfrować ruch na hoście lokalnym? ), ale powinieneś to zrobić dopiero PO KONFIGURACJI REGUŁ AUTORYZACJI dla Twojego serwera MongoDB.

Plik CAFile jest również zakomentowany, ponieważ jest opcjonalny. Na końcu tego posta wyjaśnię, jak skonfigurować zaufanie urzędu certyfikacji.

Jak zawsze, musisz ponownie uruchomić MongoDB, zanim zmiany w pliku konfiguracyjnym zaczną obowiązywać:

sudo service mongod restart

CZY SERWER NIE URUCHOMIŁ? Jesteś zdany na siebie, ale prawdopodobnie jest problem z plikami certyfikatów. Możesz sprawdzić błędy uruchamiania, uruchamiając mongod ręcznie:

sudo mongod --config /etc/mongod.conf

Krok 4:Przetestuj ustawienia serwera

Zanim zaczniemy bawić się konfiguracjami węzłów, upewnijmy się, że konfiguracja serwera działa poprawnie, łącząc się z mongo klient wiersza poleceń:

mongo --ssl --sslAllowInvalidHostnames --sslAllowInvalidCertificates

Chyba że nazwa domeny na Twoim certyfikacie to 127.0.0.1 lub localhost , --sslAllowInvalidHostnames flaga jest konieczna. Bez tego prawdopodobnie otrzymasz ten błąd:

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

Krok 5:Skonfiguruj Node.JS / Mongoose

Jeśli używasz node-mongodb-native pakiet w aplikacji Node, natychmiast przestań i zacznij korzystać z Mongoose. To nie jest takie trudne. To powiedziawszy, mongoose.connect() ma praktycznie to samo API co mongodb.connect() , więc odpowiednio zastąp.

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

Krok 6:[Opcjonalnie] zweryfikuj swoje certyfikaty za pośrednictwem urzędu certyfikacji

Aby zweryfikować swoje certyfikaty SSL, musisz uzyskać CA (lub pakiet ) z Twojego urzędu certyfikacji. Będzie to bardzo przypominało plik certyfikatu, ale często będzie zawierał wiele certyfikatów (co tworzy łańcuch zaufania weryfikujący ważność certyfikatu ). Jeśli używasz certyfikatu z podpisem własnym, możesz użyć swojego mongodb-cert.crt jako plik CA.

Musisz również upewnić się, że nazwa hosta serwera MongoDB jest zgodna z nazwą użytą do utworzenia certyfikatu.

Krok 6.3:Zaktualizuj swojego mongod konfiguracja

sudo vi /etc/mongod.conf

i zmodyfikuj sekcję „# interfejsy sieciowe” w następujący sposób:

# 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

Krok 6.4:Przetestuj ustawienia serwera

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

Klienci Mongo mogą również przekazać plik CA, aby sprawdzić, czy rozmawiają z właściwym serwerem. Odbywa się to za pomocą --sslCAFile parametr

Serwery Mongo skonfigurowane z plikiem CAFile wymagają, aby klienci posiadali ważny certyfikat ORAZ klucz prywatny serwera. W kliencie powłoki mongo odbywa się to poprzez przekazanie --sslPEMKeyFile parametr.

Bez pliku PEM (zawierającego certyfikat serwera ), możesz zobaczyć ten błąd:

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

Serwer można skonfigurować tak, aby akceptował żądania od klientów bez pliku PEM, włączając net.ssl.weakCertificateValidation , ale osłabisz swoje bezpieczeństwo bez żadnych korzyści.

Krok 6.5:Skonfiguruj Node.JS / Mongoose

Jest tu kilka łajdaków, więc wytrzymaj ze mną.

Po pierwsze, MUSISZ mieć node-mongodb-native 2.0 lub później. Jeśli używasz Mongoose, POTRZEBUJESZ Mongoose 4.0 lub później. Poprzednie wersje Mongoose używają node-mongodb-native 1.* który nie obsługuje walidacji certyfikatu w żadnej roli.

Po drugie, nie ma sslAllowInvalidHostnames lub podobna opcja dostępna w node-mongodb-native. To nie jest coś, co node-mongodb-native programiści mogą naprawić (bym już to zrobił ), ponieważ natywna biblioteka TLS dostępna w węźle 0.10.* nie oferuje takiej opcji. W węźle 4.* i 5.* znajduje się checkServerIdentity opcja, która daje nadzieję, ale przełączanie się z oryginalnej gałęzi Node do gałęzi po scaleniu io.js może obecnie powodować trochę bólu głowy.

Spróbujmy więc tego:

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

Jeśli otrzymujesz błędy niezgodności nazwy hosta/adresu IP, albo napraw swój certyfikat, albo zrezygnuj z całej tej ciężkiej pracy, wyłączając 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')
      }
    }
  ;

Źródło



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Wyrażenie regularne dla MongoDB ObjectID

  2. Klonuj bazę danych w Mongodb między hostami za pomocą sterownika węzła

  3. Jak zignorować wartości null podczas rozmieszczania dokumentu MongoDB?

  4. Mongoose zagnieżdżone zapytanie w modelu według pola modelu, do którego się odwołuje

  5. Łączenie MongoDB z Ruby za pomocą certyfikatów z podpisem własnym dla SSL