diff options
author | Jonathan Reams <jbreams@mongodb.com> | 2019-03-18 14:52:38 -0400 |
---|---|---|
committer | Jonathan Reams <jbreams@mongodb.com> | 2019-04-08 15:48:38 -0400 |
commit | 51add9e4cdaf3ded4c0d0ff3666cb7927367c9c3 (patch) | |
tree | 80fe3d7f5c32d075a85fc00f52217f3a660086d4 | |
parent | e0148efd023cbf9a6a3fb7a084169e83f10e12f3 (diff) | |
download | mongo-51add9e4cdaf3ded4c0d0ff3666cb7927367c9c3.tar.gz |
SERVER-39820 Include client IP in log message for successful authentication
(cherry picked from commit 0a847ef8453015e8b622595692b2fde0488486a6)
(cherry picked from commit 4a515ef5692d48efffb74c4fe9e1a297bd063aa3)
-rw-r--r-- | jstests/auth/logs_include_client_info.js | 29 | ||||
-rw-r--r-- | jstests/ssl/x509_client.js | 11 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_commands.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/commands/authentication_commands.cpp | 13 |
4 files changed, 51 insertions, 5 deletions
diff --git a/jstests/auth/logs_include_client_info.js b/jstests/auth/logs_include_client_info.js new file mode 100644 index 00000000000..80903ef128b --- /dev/null +++ b/jstests/auth/logs_include_client_info.js @@ -0,0 +1,29 @@ +// This test just checks that the success/failure messages for authentication include the IP +// address of the client attempting to authenticate. + +(function() { + const conn = MongoRunner.runMongod({auth: ""}); + const admin = conn.getDB("admin"); + + admin.createUser({ + user: "root", + pwd: "root", + roles: ["root"], + }); + + assert(admin.auth("root", "root")); + + const failConn = new Mongo(conn.host); + failConn.getDB("admin").auth("root", "toot"); + + const log = assert.commandWorked(admin.runCommand({getLog: "global"})).log; + + const successRegex = + /Successfully authenticated as principal root on admin from client (?:\d{1,3}\.){3}\d{1,3}:\d+/; + const failRegex = + /SCRAM-SHA-\d+ authentication failed for root on admin from client (?:\d{1,3}\.){3}\d{1,3}:\d+/; + + assert(log.some((line) => successRegex.test(line))); + assert(log.some((line) => failRegex.test(line))); + MongoRunner.stopMongod(conn); +})(); diff --git a/jstests/ssl/x509_client.js b/jstests/ssl/x509_client.js index 5842438b98a..208155cb977 100644 --- a/jstests/ssl/x509_client.js +++ b/jstests/ssl/x509_client.js @@ -45,7 +45,8 @@ function authAndTest(mongo) { user: CLIENT_USER, roles: [ {'role': 'userAdminAnyDatabase', 'db': 'admin'}, - {'role': 'readWriteAnyDatabase', 'db': 'admin'} + {'role': 'readWriteAnyDatabase', 'db': 'admin'}, + {'role': 'clusterMonitor', 'db': 'admin'}, ] }); @@ -71,6 +72,14 @@ function authAndTest(mongo) { assert(external.runCommand({authenticate: 1, mechanism: 'MONGODB-X509'}).ok, "runCommand authentication with valid client cert and no user field failed"); + // Check that there's a "Successfully authenticated" message that includes the client IP + const log = + assert.commandWorked(external.getSiblingDB("admin").runCommand({getLog: "global"})).log; + const successRegex = new RegExp(`Successfully authenticated as principal ${CLIENT_USER} on ` + + `\\$external from client (?:\\d{1,3}\\.){3}\\d{1,3}:\\d+`); + + assert(log.some((line) => successRegex.test(line))); + // Check that we can add a user and read data test.createUser( {user: "test", pwd: "test", roles: [{'role': 'readWriteAnyDatabase', 'db': 'admin'}]}); diff --git a/src/mongo/db/auth/sasl_commands.cpp b/src/mongo/db/auth/sasl_commands.cpp index c4edf1f9a0f..ead1abae445 100644 --- a/src/mongo/db/auth/sasl_commands.cpp +++ b/src/mongo/db/auth/sasl_commands.cpp @@ -202,7 +202,8 @@ Status doSaslStep(const Client* client, if (!serverGlobalParams.quiet) { log() << "Successfully authenticated as principal " << session->getPrincipalId() - << " on " << session->getAuthenticationDatabase(); + << " on " << session->getAuthenticationDatabase() << " from client " + << client->session()->remote(); } } return Status::OK(); diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp index 852c8ab56ed..8bcf6fb879d 100644 --- a/src/mongo/db/commands/authentication_commands.cpp +++ b/src/mongo/db/commands/authentication_commands.cpp @@ -187,9 +187,10 @@ bool CmdAuthenticate::run(OperationContext* txn, Status status = _authenticate(txn, mechanism, user, cmdObj); audit::logAuthentication(Client::getCurrent(), mechanism, user, status.code()); if (!status.isOK()) { - if (!serverGlobalParams.quiet) { - log() << "Failed to authenticate " << user << " with mechanism " << mechanism << ": " - << status; + if (!serverGlobalParams.quiet.load()) { + auto const client = txn->getClient(); + log() << "Failed to authenticate " << user << " from client " << client->getRemote() + << " with mechanism " << mechanism << ": " << status; } if (status.code() == ErrorCodes::AuthenticationFailed) { // Statuses with code AuthenticationFailed may contain messages we do not wish to @@ -201,6 +202,12 @@ bool CmdAuthenticate::run(OperationContext* txn, sleepmillis(saslGlobalParams.authFailedDelay); return false; } + + if (!serverGlobalParams.quiet.load()) { + log() << "Successfully authenticated as principal " << user.getUser() << " on " + << user.getDB() << " from client " << txn->getClient()->session()->remote(); + } + result.append("dbname", user.getDB()); result.append("user", user.getUser()); return true; |