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