With SSL setup on MongoDB https requests don't work, but http
I have installed self signed certificates and SSL in my mongo database according to several articles, mongodb.org manual, some dba.stackexchange.com questions and various tutorials.
So, I start a mongodb instance with the following command (or config file):
mongod --sslMode requireSSL --sslPEMKeyFile ./selfsignsec/mongodb.pem --sslCAFile ./selfsignsec/ca.pem
And everything looks fine:
[datetime].129-0700 I CONTROL [initandlisten] MongoDB starting : pid=42188 port=27017 dbpath=/data/db
...
[datetime].129-0700 I CONTROL [initandlisten] OpenSSL version: OpenSSL 1.0.2 22 Jan 2015
...
[datetime].129-0700 I CONTROL [initandlisten] options: { net: { ssl: { CAFile: "./selfsignsec/dbclient.pem", PEMKeyFile: "./selfsignsec/mongodb.pem", mode: "requireSSL" } } }
...
[datetime].178-0700 I NETWORK [initandlisten] waiting for connections on port 27017 ssl
Then I connected to this instance with a client certificate using this code:
...
var https = require('https'),
fs = require('fs');
...
app.use(methodOverride('X-HTTP-Method-Override')); //ability to use put, etc.
...
// For the moment, allow just about everything for CORS origin, methods, and headers
...
// http://docs.mongodb.org/manual/core/authentication/
var config = {
mongo: {
host: "localhost",
port: 27017,
db: "test",
ssl: true
}
};
var dbstring = "mongodb://" + config.mongo.host + ":" + config.mongo.port +
"/" + config.mongo.db;
var dboptions = {
server: {
ssl: true,
sslCert: fs.readFileSync('./selfsignsec/my-client.crt.pem'),
sslKey: fs.readFileSync('./selfsignsec/my-client.key.pem')
}
};
mongoose.connect(dbstring, dboptions);
mongoose.connection.once('open', function() {
app.models = require('./models/index');
var routes = require('./routes');
_.each(routes, function(controller, route) {
// declaring controllers & pass in the app & route
app.use(route, controller(app, route));
});
console.log('Secure Express server listening on port 27017...');
app.listen(27017);
});
And the server log looks good:
[datetime].166-0700 I NETWORK [initandlisten] connection accepted from 127.0.0.1:57591 #1 (1 connection now open)
...
But, in the browser, when I go to https: // localhost: 27017 / somecollection , the GET fails. I am not getting a connection (ERR_CONNECTION_CLOSED).
When I just use http I am returning a json collection!
Another time I used admin username and password and got:
[datetime].347-0700 I ACCESS [conn43] Successfully authenticated as principal adminrole on test
But the browser requests and responses were the same: there was no response for https and no complete collection for the HTTP request.
If ssl is given on mongod and mongo client, why does http return results?
TL; DR:
By the way, if I don't pass any ssl values in the client code, I get what I expect from the server:
AssertionException handling request, closing client connection: 17189 The server is configured to only allow SSL connections
And if I submit a bad certificate, I expect:
no SSL certificate provided by peer; connection rejected
end connection 127.0.0.1:55829 (0 connections now open)
The result of the incognito queries was the same as above.
Netstat result -a | grep 27017:
tcp46 0 0 *.27017 *.* LISTEN
tcp4 0 0 localhost.27017 localhost.56297 ESTABLISHED
tcp4 0 0 localhost.56297 localhost.27017 ESTABLISHED
tcp4 0 0 localhost.27017 localhost.56296 ESTABLISHED
tcp4 0 0 localhost.56296 localhost.27017 ESTABLISHED
tcp4 0 0 localhost.27017 localhost.56295 ESTABLISHED
tcp4 0 0 localhost.56295 localhost.27017 ESTABLISHED
tcp4 0 0 localhost.27017 localhost.56294 ESTABLISHED
tcp4 0 0 localhost.56294 localhost.27017 ESTABLISHED
tcp4 0 0 localhost.27017 localhost.56293 ESTABLISHED
tcp4 0 0 localhost.56293 localhost.27017 ESTABLISHED
tcp4 0 0 *.27017 *.* LISTEN
704e9db9a444912b stream 0 0 704e9db9b79bb6c3 0 0 0 /tmp/mongodb-27017.sock
Openssl result s_client -connect localhost: 27017 -tls1 -servername localhost | openssl x509 -text -noout:
depth=1 C = US, ST = CA, L = SanFran, O = Local Signing Authority, CN = localhost
verify error:num=19:self signed certificate in certificate chain
read:errno=0
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 13550121380367150794 (0xbc0bb39a9435aeca)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=CA, L=SanFran, O=Local Signing Authority, CN=localhost
Validity
Not Before: May 21 19:42:47 2015 GMT
Not After : Oct 2 19:42:47 2016 GMT
Subject: C=US, ST=CA, L=SanFran, O=Local Signing Authority, CN=127.0.0.1
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ba:0e:a4:0d:23:6c:a7:01:a9:e7:92:0e:9e:15:
1c:83:5d:91:32:7a:fb:6e:6f:da:ad:70:24:ef:a0:
4d:83:24:a1:f0:d0:6a:40:81:12:aa:f9:40:6d:53:
b3:d6:c1:24:b4:c9:07:a2:e9:5a:80:7a:51:30:71:
9c:e2:ee:fc:ce:d7:b1:2c:e2:91:40:94:9d:43:50:
08:33:67:cb:58:66:0d:c7:13:cc:45:20:e7:ef:70:
c4:8a:26:64:b5:af:4e:f8:c4:70:d8:7e:17:21:40:
4f:12:5b:35:71:b0:51:87:6f:12:4e:06:99:12:ac:
0e:4e:8e:7d:9c:6e:41:6f:d8:ca:93:77:9a:ee:60:
7e:9d:86:c1:6d:df:7c:a6:3a:71:cd:73:d8:8e:d1:
d8:61:f9:48:e5:02:44:10:31:94:58:1a:d2:75:a7:
14:83:b5:ad:b9:2e:ae:7a:65:af:8d:5d:31:65:fd:
c5:1f:e1:4f:f2:fb:80:df:08:25:64:5b:a6:c2:9d:
aa:10:8b:25:2e:fc:75:65:82:ea:4f:5c:18:68:21:
2b:0e:00:b8:57:e9:fb:14:67:18:14:ae:e0:c5:e6:
d9:5d:a1:df:6e:9d:27:0b:72:bd:33:e2:e8:a6:b3:
e8:a1:94:cc:ec:78:15:1b:37:b2:23:57:7c:d6:65:
c8:71
Exponent: 65537 (0x10001)
Signature Algorithm: sha256WithRSAEncryption
56:f6:ca:05:be:4a:ab:8d:94:8b:4e:7a:51:e2:8c:ed:d3:0e:
16:ac:68:61:eb:5b:d0:c3:e5:96:f2:50:12:f3:a8:10:14:c8:
9f:63:cc:f3:d3:b9:c2:71:8b:ac:7a:9c:9e:61:8d:09:26:4c:
6f:0d:30:2d:87:e2:e8:aa:77:f0:33:25:51:cb:67:d9:99:a5:
3c:cf:3a:3d:27:63:cd:3e:42:50:da:d6:68:a0:0a:c4:78:ad:
aa:a5:b1:93:8f:01:d0:70:72:5e:c0:19:5a:43:94:ba:65:35:
aa:0d:8b:da:b5:16:50:f5:bc:8f:cf:80:c9:f9:53:67:eb:68:
a2:0b:60:11:a0:c0:04:ef:47:5c:8b:e6:28:09:37:b9:43:bb:
0f:8f:1d:28:2a:d7:aa:46:6e:7d:32:64:44:70:74:c0:84:bd:
3e:82:87:85:68:51:c1:ba:44:d1:b3:29:bd:78:d8:80:63:59:
40:a5:dd:97:a1:a5:35:7c:5d:cb:11:1d:39:63:08:15:f5:00:
7c:6f:85:a8:df:9b:26:aa:66:a4:8a:81:f9:7a:ea:65:f5:03:
89:0b:ef:49:67:60:79:c5:82:39:eb:b3:88:9e:7b:b9:f9:6e:
c1:2c:30:19:23:d5:c8:3a:4e:c6:2a:33:c0:5a:5f:74:04:90:
91:07:b3:f2
source to share
You have two problems. The first is the self-signed server certificate; and secondly, the DNS names in CN. You have a third problem that goes away after you fix the first two problems.
For the first issue, a self-signed certificate, see How do you sign a certificate signing request at your CA? ... The browser has actively moved against self-signed certificates.
For the second issue of DNS names in CN, see How do I generate a self-signed certificate with openssl? ... This is another browser requirement. DNS names should be placed in the subject alternative name (SAN), not in the Common Name (CN).
But, in the browser, when I go to
https://localhost:27017/somecollection
, the GET fails.
A related issue is the CN subject CN=127.0.0.1
. 127.0.0.1
not localhost
, so the browser thinks of a different origin. Even other user agents (non-browsers) will fail for this. Non-browsers include cURL and GNU Wget.
This problem will go away once you put all DNS names in the SAN. DNS names include 127.0.0.1
, localhost
, john-dev-machine
and john-dev-machine.example.com
.
You can see if the server is actually serving HTTPS with:
echo -e "GET /somecollection HTTP/1.1\r\nHost:localhost\r\n\r\n" | \
openssl s_client -connect localhost:27017 -tls1 -servername localhost -ign_eof
You should see the raw HTML. Then you can click CTRL+Cto exit.
OpenSSL does not do hostname checks (the programmer has to do this manually) or enforce DNS naming policies (in CN or SAN). Thus, it will work if the server is serving pages on that port over HTTPS.
source to share