Passaggio 1:ottieni MongoDB 3.0
La prima cosa che devi sapere è che SSL è supportato immediatamente solo da MongoDB 3.0 e versioni successive. Ubuntu non ha 3.0 nei repository predefiniti, quindi ecco come lo ottieni:
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 è l'ultima versione stabile al momento, ma sentiti libero di sostituire la 3.0.7 con la tua versione preferita.
Fase 2:ottieni la chiave privata, il certificato e i file PEM
Il PEM contiene un certificato di chiave pubblica e la chiave privata associata. Questi file possono essere ottenuti con dollari IRL da un'autorità di certificazione o generati con OpenSSL in questo modo:
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 verrà utilizzato come file PEM, mongodb-cert.key è il file della chiave privata e mongodb-cert.crt è il file del certificato che può essere utilizzato anche come file CA. AVRAI BISOGNO DI TUTTI E TRE QUESTI.
Fase 3:configura MongoD
Assumiamo che tu abbia copiato questi file nella tua cartella /etc/ssl/ a cui appartengono. Ora apriamo il nostro file di configurazione MongoDB:
sudo vi /etc/mongod.conf
e modifica la sezione "# interfacce di rete" in questo modo:
# network interfaces
net:
port: 27017
#bindIp: 127.0.0.1
ssl:
mode: allowSSL
PEMKeyFile: /etc/ssl/mongodb.pem
#CAFile: /etc/ssl/mongodb-cert.crt
SI PREGA DI NOTARE :stiamo commentando bindIp
. QUESTO PERMETTE A CONNESSIONI ESTERNE di accedere al tuo database Mongo. Partiamo dal presupposto che questo sia il tuo obiettivo finale (Perché dovresti crittografare il traffico su localhost? ), ma dovresti farlo solo DOPO AVER IMPOSTATO LE REGOLE DI AUTORIZZAZIONE per il tuo server MongoDB.
Anche il CAFile è commentato in quanto facoltativo. Spiegherò come impostare l'attendibilità dell'autorità di certificazione alla fine di questo post.
Come sempre, è necessario riavviare MongoDB prima che le modifiche al file di configurazione abbiano effetto:
sudo service mongod restart
IL TUO SERVER NON SI AVVIENE? Sei da solo, ma probabilmente c'è un problema con i file del certificato. Puoi controllare gli errori di avvio eseguendo mongod
manualmente:
sudo mongod --config /etc/mongod.conf
Fase 4:verifica le impostazioni del server
Prima di andare a pasticciare con le configurazioni di Node, assicuriamoci che la configurazione del tuo server funzioni correttamente collegandoti con mongo
client della riga di comando:
mongo --ssl --sslAllowInvalidHostnames --sslAllowInvalidCertificates
A meno che il nome di dominio sul tuo certificato non sia 127.0.0.1
o localhost
, il --sslAllowInvalidHostnames
la bandiera è necessaria. Senza di esso, probabilmente otterrai questo errore:
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
Passaggio 5:Configura Node.JS / Mongoose
Se stai usando il node-mongodb-native
pacchetto nella tua applicazione Node, fermati immediatamente e inizia a usare Mongoose. Non è così difficile. Detto questo, mongoose.connect()
ha praticamente la stessa API di mongodb.connect()
, quindi sostituisci in modo appropriato.
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);
Passaggio 6:[facoltativamente] verifica i tuoi certificati tramite un'autorità di certificazione
Per convalidare i tuoi certificati SSL, devi ottenere una CA (o bundle ) dalla tua autorità di certificazione. Questo assomiglierà molto al tuo file di certificato, ma spesso conterrà più certificati (che forma una catena di fiducia per verificare che un certificato sia valido ). Se stai utilizzando un certificato autofirmato, puoi utilizzare il tuo mongodb-cert.crt
come un file CA.
Dovrai anche assicurarti che il nome host del tuo server MongoDB corrisponda a quello utilizzato per creare il certificato.
Passaggio 6.3:aggiorna il tuo mongod
configurazione
sudo vi /etc/mongod.conf
e modifica la sezione "# interfacce di rete" in questo modo:
# 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
Passaggio 6.4:verifica le impostazioni del server
mongo --ssl --sslAllowInvalidHostnames --sslCAFile /etc/ssl/mongodb-ca.crt --sslPEMKeyFile /etc/ssl/mongodb.pem
I client Mongo possono anche passare il file CA per verificare che stiano parlando con il server corretto. Questo viene fatto con il --sslCAFile
parametro
I server Mongo configurati con un CAFile richiedono che i client possiedano un certificato valido AND la chiave privata per il server. Nel client mongo shell, questo viene fatto passando il --sslPEMKeyFile
parametro.
Senza un file PEM (che contiene il certificato del server ), potresti visualizzare questo errore:
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
Il server può essere configurato per accettare richieste dai client senza un file PEM abilitando net.ssl.weakCertificateValidation
, ma indebolirai la tua sicurezza senza alcun reale vantaggio.
Passaggio 6.5:Configura Node.JS / Mongoose
Ci sono un paio di trucchi qui, quindi abbi pazienza.
Innanzitutto, DEVI avere node-mongodb-native
2.0
o più tardi. Se stai usando Mongoose, allora HAI BISOGNO di Mongoose 4.0
o più tardi. Le versioni precedenti di Mongoose utilizzano node-mongodb-native
1.*
che non supporta la convalida del certificato in alcun modo.
In secondo luogo, non ci sono sslAllowInvalidHostnames
o un'opzione simile disponibile in node-mongodb-native. Questo non è qualcosa che node-mongodb-native
gli sviluppatori possono risolvere (avrei già fatto ) perché la libreria TLS nativa disponibile nel nodo 0.10.* non offre alcuna opzione per questo. Nei nodi 4.* e 5.* è presente un checkServerIdentity
opzione che offre speranza, ma il passaggio dal ramo Node originale al ramo dopo l'unione io.js può causare un po' di mal di testa al momento attuale.
Quindi proviamo questo:
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')
}
}
;
Se ricevi errori di mancata corrispondenza nome host/IP, correggi il certificato o annulla tutto questo duro lavoro disabilitando 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')
}
}
;
Fonte