summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpencer Jackson <spencer.jackson@mongodb.com>2021-01-20 11:13:41 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-02-09 20:15:31 +0000
commit0cac5b8ebcbf1bf5e0abfa3235c6ad15d85f3934 (patch)
treefe9577f9c2df05d439810334afa9963ceec6a620
parent252d3a718ca84b627b4934326646bc359876708b (diff)
downloadmongo-0cac5b8ebcbf1bf5e0abfa3235c6ad15d85f3934.tar.gz
SERVER-50538 Control intracluster traffic in speculative auth tests
-rw-r--r--jstests/auth/speculative-auth-replset.js87
-rw-r--r--jstests/ssl/speculative-auth-replset.js76
-rw-r--r--src/mongo/db/commands/authentication_commands.cpp3
3 files changed, 115 insertions, 51 deletions
diff --git a/jstests/auth/speculative-auth-replset.js b/jstests/auth/speculative-auth-replset.js
index d6f9a52c03a..594d83988bf 100644
--- a/jstests/auth/speculative-auth-replset.js
+++ b/jstests/auth/speculative-auth-replset.js
@@ -5,56 +5,77 @@
(function() {
'use strict';
-const rst = new ReplSetTest({nodes: 3, keyFile: 'jstests/libs/key1'});
+const rst = new ReplSetTest({nodes: 1, keyFile: 'jstests/libs/key1'});
rst.startSet();
rst.initiate();
-rst.awaitSecondaryNodes();
const admin = rst.getPrimary().getDB('admin');
admin.createUser({user: 'admin', pwd: 'pwd', roles: ['root']});
admin.auth('admin', 'pwd');
-const baseURI = (function() {
- let uri = 'mongodb://admin:pwd@';
-
- for (let i = 0; i < rst.ports.length; ++i) {
- if (i > 0) {
- uri = uri + ',';
- }
- uri = uri + rst.host + ':' + rst.ports[i];
- }
-
- return uri + '/admin?replicaSet=' + rst.name;
-})();
-
-function test(uri) {
- assert.eq(runMongoProgram('mongo', uri, '--eval', ';'), 0);
+function getMechStats(db) {
+ return assert.commandWorked(db.runCommand({serverStatus: 1}))
+ .security.authentication.mechanisms;
}
+// Capture statistics after a fresh instantiation of a 1-node replica set.
+const initialMechStats = getMechStats(admin);
+printjson(initialMechStats);
+assert(initialMechStats['SCRAM-SHA-256'] !== undefined);
+
// We've made no client connections for which speculation was possible,
-// since this connection came in during localhost auth bypass.
-// However we should have non-zero SCRAM-SHA-256 successes using internal auth.
-const mechStats =
- assert.commandWorked(admin.runCommand({serverStatus: 1})).security.authentication.mechanisms;
-printjson(mechStats);
-assert(mechStats['SCRAM-SHA-256'] !== undefined);
-Object.keys(mechStats).forEach(function(mech) {
- const specStats = mechStats[mech].speculativeAuthenticate;
- const clusterStats = mechStats[mech].clusterAuthenticate;
+// because we authenticated as `admin` using the shell helpers.
+// Because of the simple cluster topology, we should have no intracluster authentication attempts.
+Object.keys(initialMechStats).forEach(function(mech) {
+ const specStats = initialMechStats[mech].speculativeAuthenticate;
+ const clusterStats = initialMechStats[mech].clusterAuthenticate;
if (mech === 'SCRAM-SHA-256') {
- assert.gte(specStats.received, 2);
- assert.gte(clusterStats.received, 2);
- } else {
- assert.eq(specStats.received, 0);
+ // It appears that replication helpers use SCRAM-SHA-1, preventing SCRAM-SHA-256 cluster
+ // stats from being incremented during test setup.
+ assert.eq(clusterStats.received, 0);
}
+
+ // No speculation has occured
+ assert.eq(specStats.received, 0);
+
+ // Statistics should be consistent for all mechanisms
assert.eq(specStats.received, specStats.successful);
assert.eq(clusterStats.received, clusterStats.successful);
});
-test(baseURI);
-test(baseURI + '&authMechanism=SCRAM-SHA-1');
-test(baseURI + '&authMechanism=SCRAM-SHA-256');
+{
+ // Add and remove a node to force intra-cluster traffic, and authentication attempts.
+ // Removal will require force-reconfig because the original node will not constitute a
+ // "majority" of the resulting two node replicaset.
+ const singleNodeConfig = rst.getReplSetConfigFromNode();
+
+ const newNode = rst.add({});
+ rst.reInitiate();
+ rst.waitForState(newNode, ReplSetTest.State.SECONDARY);
+
+ rst.stop(newNode);
+ rst.remove(newNode);
+ admin.auth('admin', 'pwd');
+ singleNodeConfig.version = rst.getReplSetConfigFromNode(0).version + 1;
+ assert.commandWorked(admin.runCommand({replSetReconfig: singleNodeConfig, force: true}));
+}
+
+{
+ // Capture new statistics, and assert that they're consistent.
+ const newMechStats = getMechStats(admin);
+ printjson(newMechStats);
+ assert.eq(newMechStats["SCRAM-SHA-256"].speculativeAuthenticate.received,
+ newMechStats["SCRAM-SHA-256"].speculativeAuthenticate.successful);
+ assert.eq(newMechStats["SCRAM-SHA-256"].clusterAuthenticate.received,
+ newMechStats["SCRAM-SHA-256"].clusterAuthenticate.successful);
+
+ // Speculative and cluster statistics should be incremented by intracluster auth.
+ assert.gt(newMechStats["SCRAM-SHA-256"].speculativeAuthenticate.received,
+ initialMechStats["SCRAM-SHA-256"].speculativeAuthenticate.successful);
+ assert.gt(newMechStats["SCRAM-SHA-256"].clusterAuthenticate.received,
+ initialMechStats["SCRAM-SHA-256"].clusterAuthenticate.successful);
+}
admin.logout();
rst.stopSet();
diff --git a/jstests/ssl/speculative-auth-replset.js b/jstests/ssl/speculative-auth-replset.js
index 51f9e2c8154..23930c4811a 100644
--- a/jstests/ssl/speculative-auth-replset.js
+++ b/jstests/ssl/speculative-auth-replset.js
@@ -13,7 +13,7 @@ const x509_options = {
};
const rst = new ReplSetTest({
- nodes: 3,
+ nodes: 1,
nodeOptions: x509_options,
// ReplSetTest needs a keyFile present in order to know we want intracluster auth.
@@ -24,31 +24,75 @@ const rst = new ReplSetTest({
rst.startSet();
rst.initiate();
-rst.awaitSecondaryNodes();
const admin = rst.getPrimary().getDB('admin');
admin.createUser({user: 'admin', pwd: 'pwd', roles: ['root']});
admin.auth('admin', 'pwd');
-// We should have non-zero MONGODB-X509 successes using internal auth.
-// And we should have no other types of speculative authentications.
-const mechStats =
- assert.commandWorked(admin.runCommand({serverStatus: 1})).security.authentication.mechanisms;
-printjson(mechStats);
-assert(mechStats['MONGODB-X509'] !== undefined);
-Object.keys(mechStats).forEach(function(mech) {
- const specStats = mechStats[mech].speculativeAuthenticate;
- const clusterStats = mechStats[mech].clusterAuthenticate;
+function getMechStats(db) {
+ return assert.commandWorked(db.runCommand({serverStatus: 1}))
+ .security.authentication.mechanisms;
+}
+
+// Capture statistics after a fresh instantiation of a 1-node replica set.
+const initialMechStats = getMechStats(admin);
+printjson(initialMechStats);
+assert(initialMechStats['MONGODB-X509'] !== undefined);
+
+// We've made no client connections for which speculation was possible,
+// because we authenticated as `admin` using the shell helpers with SCRAM.
+// Because of the simple cluster topology, we should have no intracluster authentication attempts.
+Object.keys(initialMechStats).forEach(function(mech) {
+ const specStats = initialMechStats[mech].speculativeAuthenticate;
+ const clusterStats = initialMechStats[mech].clusterAuthenticate;
+
if (mech === 'MONGODB-X509') {
- assert.gte(specStats.received, 2);
- assert.gte(clusterStats.received, 2);
- } else {
- assert.eq(specStats.received, 0);
+ // It appears that replication helpers use SCRAM-SHA-1, preventing SCRAM-SHA-256 cluster
+ // stats from being incremented during test setup.
+ assert.eq(clusterStats.received, 0);
}
+
+ // No speculation has occured
+ assert.eq(specStats.received, 0);
+
+ // Statistics should be consistent for all mechanisms
assert.eq(specStats.received, specStats.successful);
- assert.gte(clusterStats.received, clusterStats.successful);
+ assert.eq(clusterStats.received, clusterStats.successful);
});
+{
+ // Add and remove a node to force intra-cluster traffic, and authentication attempts.
+ // Removal will require force-reconfig because the original node will not constitute a
+ // "majority" of the resulting two node replicaset.
+ const singleNodeConfig = rst.getReplSetConfigFromNode();
+
+ const newNode = rst.add(x509_options);
+ rst.reInitiate();
+ rst.waitForState(newNode, ReplSetTest.State.SECONDARY);
+
+ rst.stop(newNode);
+ rst.remove(newNode);
+ admin.auth('admin', 'pwd');
+ singleNodeConfig.version = rst.getReplSetConfigFromNode(0).version + 1;
+ assert.commandWorked(admin.runCommand({replSetReconfig: singleNodeConfig, force: true}));
+}
+
+{
+ // Capture new statistics, and assert that they're consistent.
+ const newMechStats = getMechStats(admin);
+ printjson(newMechStats);
+ assert.eq(newMechStats["MONGODB-X509"].speculativeAuthenticate.received,
+ newMechStats["MONGODB-X509"].speculativeAuthenticate.successful);
+ assert.eq(newMechStats["MONGODB-X509"].clusterAuthenticate.received,
+ newMechStats["MONGODB-X509"].clusterAuthenticate.successful);
+
+ // Speculative and cluster statistics should be incremented by intracluster auth.
+ assert.gt(newMechStats["MONGODB-X509"].speculativeAuthenticate.received,
+ initialMechStats["MONGODB-X509"].speculativeAuthenticate.successful);
+ assert.gt(newMechStats["MONGODB-X509"].clusterAuthenticate.received,
+ initialMechStats["MONGODB-X509"].clusterAuthenticate.successful);
+}
+
admin.logout();
rst.stopSet();
}());
diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp
index a54060a68e0..485b292c7a2 100644
--- a/src/mongo/db/commands/authentication_commands.cpp
+++ b/src/mongo/db/commands/authentication_commands.cpp
@@ -244,9 +244,8 @@ void _authenticateX509(OperationContext* opCtx, UserName& user, StringData dbnam
"Client isn't a mongod or mongos, but is connecting with a "
"certificate with cluster membership");
}
-
- authCounter.getMechanismCounter("MONGODB-X509").incClusterAuthenticateSuccessful();
}
+ authCounter.getMechanismCounter("MONGODB-X509").incClusterAuthenticateSuccessful();
authorizationSession->grantInternalAuthorization(client);
} else {