mirror of https://github.com/mongodb/mongo
107 lines
4.0 KiB
JavaScript
107 lines
4.0 KiB
JavaScript
// Verify certificates and CAs between intra-cluster
|
|
// and client->server communication using different CAs.
|
|
|
|
import {ReplSetTest} from "jstests/libs/replsettest.js";
|
|
|
|
function testRS(node0_opts, node1_opts, succeed) {
|
|
const origSkipCheck = TestData.skipCheckDBHashes;
|
|
const rsOpts = {
|
|
// Use localhost so that SAN matches.
|
|
useHostName: false,
|
|
nodes: {node0: node0_opts, node1: node1_opts},
|
|
};
|
|
const rs = new ReplSetTest(rsOpts);
|
|
rs.startSet();
|
|
if (succeed) {
|
|
rs.initiate();
|
|
assert.commandWorked(rs.getPrimary().getDB("admin").runCommand({hello: 1}));
|
|
} else {
|
|
// By default, rs.initiate takes a very long time to timeout. We should shorten this
|
|
// period, because we expect it to fail. ReplSetTest has both a static and local copy
|
|
// of kDefaultTimeOutMS, so we must override both.
|
|
const oldTimeout = ReplSetTest.kDefaultTimeoutMS;
|
|
const shortTimeout = 60 * 1000;
|
|
ReplSetTest.kDefaultTimeoutMS = shortTimeout;
|
|
rs.timeoutMS = shortTimeout;
|
|
// The rs.initiate will fail in an assert.soon, which would ordinarily trigger the hang
|
|
// analyzer. We don't want that to happen, so we disable it here.
|
|
MongoRunner.runHangAnalyzer.disable();
|
|
try {
|
|
assert.throws(function () {
|
|
rs.initiate();
|
|
});
|
|
} finally {
|
|
ReplSetTest.kDefaultTimeoutMS = oldTimeout;
|
|
MongoRunner.runHangAnalyzer.enable();
|
|
}
|
|
TestData.skipCheckDBHashes = true;
|
|
}
|
|
rs.stopSet();
|
|
TestData.skipCheckDBHashes = origSkipCheck;
|
|
}
|
|
|
|
// The name "trusted" in these certificates is misleading.
|
|
// They're just a separate trust chain from the ones without the name.
|
|
// ca.pem signed client.pem and server.pem
|
|
// trusted-ca.pem signed trusted-client.pem and trusted-server.pem
|
|
const valid_options = {
|
|
tlsMode: "requireTLS",
|
|
// Servers present trusted-server.pem to clients and each other for inbound connections.
|
|
// Peers validate trusted-server.pem using trusted-ca.pem when making those connections.
|
|
tlsCertificateKeyFile: "jstests/libs/trusted-server.pem",
|
|
tlsCAFile: "jstests/libs/trusted-ca.pem",
|
|
// Servers making outbound connections to other servers present server.pem to their peers
|
|
// which their peers validate using ca.pem.
|
|
tlsClusterFile: "jstests/libs/server.pem",
|
|
tlsClusterCAFile: "jstests/libs/ca.pem",
|
|
// SERVER-36895: IP based hostname validation with SubjectAlternateName
|
|
tlsAllowInvalidHostnames: "",
|
|
};
|
|
|
|
testRS(valid_options, valid_options, true);
|
|
|
|
const wrong_cluster_file = Object.assign({}, valid_options, {tlsClusterFile: valid_options.tlsCertificateKeyFile});
|
|
testRS(wrong_cluster_file, wrong_cluster_file, false);
|
|
|
|
const wrong_key_file = Object.assign({}, valid_options, {tlsCertificateKeyFile: valid_options.tlsClusterFile});
|
|
testRS(wrong_key_file, wrong_key_file, false);
|
|
|
|
// Test self-signed clusterFile validated against peer's CAFile
|
|
const cafile_only_options = {
|
|
tlsMode: "requireTLS",
|
|
tlsCertificateKeyFile: "jstests/libs/server.pem",
|
|
tlsCAFile: "jstests/libs/ca.pem",
|
|
tlsAllowInvalidHostnames: "",
|
|
clusterAuthMode: "x509",
|
|
};
|
|
const selfsigned_cluster_file = Object.merge(cafile_only_options, {tlsClusterFile: "jstests/libs/smoke.pem"});
|
|
testRS(cafile_only_options, selfsigned_cluster_file, false);
|
|
|
|
const mongod = MongoRunner.runMongod(valid_options);
|
|
assert(mongod, "Failed starting standalone mongod with alternate CA");
|
|
|
|
function testConnect(cert, succeed) {
|
|
const mongo = runMongoProgram(
|
|
"mongo",
|
|
"--host",
|
|
"localhost",
|
|
"--port",
|
|
mongod.port,
|
|
"--tls",
|
|
"--tlsCAFile",
|
|
valid_options.tlsCAFile,
|
|
"--tlsCertificateKeyFile",
|
|
cert,
|
|
"--eval",
|
|
";",
|
|
);
|
|
|
|
// runMongoProgram returns 0 on success
|
|
assert.eq(mongo === 0, succeed);
|
|
}
|
|
|
|
testConnect("jstests/libs/client.pem", true);
|
|
testConnect("jstests/libs/trusted-client.pem", false);
|
|
|
|
MongoRunner.stopMongod(mongod);
|