mongo/jstests/auth/cluster_ip_allowlist.js

159 lines
5.5 KiB
JavaScript

/**
* This test checks that cluster IP allowlists can be set and respected.
*/
print("When allowlist is empty, the server does not start.");
assert.throws(
() => MongoRunner.runMongod({auth: null, keyFile: "jstests/libs/key1", clusterIpSourceAllowlist: ""}),
[],
"The server unexpectedly started",
);
// Check that the same behavior is seen with the deprecated 'clusterIpSourceWhiteList' flag.
assert.throws(
() => MongoRunner.runMongod({auth: null, keyFile: "jstests/libs/key1", clusterIpSourceWhitelist: ""}),
[],
"The server unexpectedly started",
);
function emitWarningAuthErrorIsExpected(authResult) {
if (!authResult) {
print("***** NOTE: an authentication error is expected");
}
}
function testIpAllowlistStartup(description, allowlistString, authResult) {
print("Startup: " + description);
let conn = MongoRunner.runMongod({
auth: null,
keyFile: "jstests/libs/key1",
clusterIpSourceAllowlist: allowlistString,
});
assert.eq(authResult, conn.getDB("local").auth("__system", "foopdedoop"));
emitWarningAuthErrorIsExpected(authResult);
MongoRunner.stopMongod(conn);
// Verify that the deprecated 'clusterIpSourceWhitelist' flag still exhibits the same behavior.
conn = MongoRunner.runMongod({auth: null, keyFile: "jstests/libs/key1", clusterIpSourceWhitelist: allowlistString});
assert.eq(authResult, conn.getDB("local").auth("__system", "foopdedoop"));
emitWarningAuthErrorIsExpected(authResult);
MongoRunner.stopMongod(conn);
}
function testIpAllowlistRuntime(description, allowlistString, authResult) {
print("Runtime: " + description);
const conn = MongoRunner.runMongod({keyFile: "jstests/libs/key1"});
const admin = conn.getDB("admin");
const local = conn.getDB("local");
// Must create a user to verify that we don't fallback to localhost exception for auth.
assert.commandWorked(admin.runCommand({createUser: "admin", pwd: "admin", roles: ["root"]}));
assert(local.auth("__system", "foopdedoop"));
print("Testing whether __system can login after set to: " + allowlistString);
assert.commandWorked(admin.runCommand({setParameter: 1, "clusterIpSourceAllowlist": allowlistString.split(",")}));
if (!authResult) {
// At this time we have no valid authentication, and existing session should reset.
// We should expect admin commands to fail.
print("Verifying that there is no longer authenticated session and admin commands fail");
assert.commandFailed(conn.adminCommand({fsync: 1}));
}
let authDB = local;
assert.eq(authResult, local.auth("__system", "foopdedoop"));
emitWarningAuthErrorIsExpected(authResult);
if (!authResult) {
print("Authenticating with admin user since __system is barred");
assert(admin.auth("admin", "admin"));
authDB = admin;
}
print("Testing that __system can login after reset to null");
assert.commandWorked(admin.runCommand({setParameter: 1, "clusterIpSourceAllowlist": null}));
authDB.logout();
assert.eq(true, local.auth("__system", "foopdedoop"));
MongoRunner.stopMongod(conn);
}
function testIpAllowlist(description, allowlistString, authResult) {
testIpAllowlistStartup(description, allowlistString, authResult);
testIpAllowlistRuntime(description, allowlistString, authResult);
}
function testIpAllowlistRuntimeGarbage() {
print("Testing that garbage input is handled");
const conn = MongoRunner.runMongod({auth: null, keyFile: "jstests/libs/key1"});
assert.eq(true, conn.getDB("local").auth("__system", "foopdedoop"));
const BAD_INPUTS = [
[""],
["abcxyz"],
["1.1.1.1", "abcxyz"],
["1.1.1.1/abcxyz"],
"1.1.1.1",
1,
{"something": "something else"},
["1.1.1.1", {"something": "something else"}],
];
for (let bi in BAD_INPUTS) {
print(bi);
assert.commandFailed(conn.adminCommand({setParameter: 1, "clusterIpSourceAllowlist": bi}));
}
print("Testing that __system can login after reset to null");
assert.commandWorked(conn.adminCommand({setParameter: 1, "clusterIpSourceAllowlist": null}));
conn.getDB("local").logout();
assert.eq(true, conn.getDB("local").auth("__system", "foopdedoop"));
MongoRunner.stopMongod(conn);
}
testIpAllowlist(
"When 127.0.0.1 is allowlisted, a client connected via localhost may auth as __system.",
"127.0.0.1",
true,
);
testIpAllowlist(
"When 127.0.0.0 is allowlisted as a 24-bit CIDR block, a client connected via localhost may auth as __system.",
"127.0.0.0/24",
true,
);
testIpAllowlist(
"When 127.0.0.5 is allowlisted as a 24-bit CIDR block, a client connected via localhost may auth as __system.",
"127.0.0.5/24",
true,
);
testIpAllowlist(
"When 127.0.0.0 is allowlisted as a 8-bit CIDR block, a client connected via localhost may auth as __system.",
"127.0.0.0/8",
true,
);
testIpAllowlist(
"When the IP block reserved for documentation and the 127.0.0.0/8 block are both allowlisted, a client connected via localhost may auth as __system.",
"192.0.2.0/24,127.0.0.0/8",
true,
);
testIpAllowlist(
"When 127.0.0.0/8 and the IP block reserved for documentation are both allowlisted, a client connected via localhost may auth as __system.",
"127.0.0.0/8,192.0.2.0/24",
true,
);
testIpAllowlist(
"When the IP block reserved for documentation and examples is allowlisted, a client connected via localhost may not auth as __system.",
"192.0.2.0/24",
false,
);
testIpAllowlistRuntimeGarbage();