MongoDB - Audit Log
MongoDB Audit Log
Introduction
For MongoDB, audit messages can be logged into syslog, console or file (JSON or BSON format).
Details of how to setup MongoDB Audit log can be found here
For example, to setup audit log with JSON output using configuration file:
auditLog:
destination: file
format: JSON
path: data/db/auditLog.json
Note:
- If format is not defined, MongoDB will default to use BSON for the log file.
- Using JSON format degrades server performance more than BSON format.
What is being logged
Generally speaking, the following actions can be logged:
- Authentication and authorization
- Cluster operations
- Read and write operations (logged under authCheck event and require auditAuthorizationSuccess parameter to be enabled)
- Schema operations
- Custom application messages (logged under applicationMessage event if the client/app issues a logApplicationMessage command, the user needs to have clusterAdmin role or the one that inherits from it to issue this command)
Logging for CRUD events
By default, MongoDB (using authCheck) only logs failed CRUD (create, read, update, and delete) events. To log all successful CRUD events, we need to enable auditAuthorizationSuccess by simply run this command with Mongo Shell:
db.adminCommand( { setParameter: 1, auditAuthorizationSuccess: true } )
Or setting the configuraton file with
auditLog:
destination: file
format: JSON
path: /var/lib/mongodb/auditLog.json
setParameter: { auditAuthorizationSuccess: true }
Note: When the auditAuthorizationSuccess is set to true, there will be performance impacts as each event will have to be logged in the audit before the oplog.
Here is an example of what an authCheck event looks like in the audit log
{
"atype": "authCheck",
"ts": { "$date": "2016-11-14T18:36:57.806+0000" },
"local":{ "ip": "127.0.0.1", "port": 27017 },
"remote":{ "ip": "127.0.0.1", "port": 48472 ,
"users": [{ "user": "accountUser", "db": "books" }],
"roles": [
{ "role": "dbAdmin", "db": "books" },
{ "role": "readWrite", "db": "books" }
],
"param": {
"command": "find",
"ns": "books.books",
"args": {
"find": "books",
"filter": {
"year": { "$gt": 1800 }
}
}
},
"result": 0
}
Audit with Filter
To only log a subset of events we can apply audit filters.
- Following example changes audit filters to audit specific user
...
...
# Audit log setting
auditLog:
destination: file
format: JSON
path: /var/log/mongodb/auditLog.json
filter: '{ users: { user: "superuser", db: "admin" } }'
# enable DML auditing by audit atype:authCheck
setParameter: {auditAuthorizationSuccess: true}
...
- Audit who had log into on a database - Authentication Operations on a Single Database
filter: '{ atype: "authenticate", "param.db": "test" }'
- Audit filtered by Authorization Role - The following example audits operations by users with readWrite role on the test database, including users with roles that inherit from readWrite, by using the filter
filter: '{roles: {role: "readWrite", db: "test"}}'
- Audit filtered on Read and Write Operations. - capture read and write operations in the audit log.
filter: '{ atype: "authCheck", "param.command": { $in: [ "find", "insert", "delete", "update", "findandmodify" ] } }'
Note: you must also enable the audit system to log authorization successes using the auditAuthorizationSuccess parameter.
- Audit read and Write Operations for a Collection - The following example audits the find(), insert(), remove(), update(), save(), and findAndModify() operations for the collection orders in the database test
filter: '{ atype: "authCheck", "param.ns": "test.orders", "param.command": { $in: [ "find", "insert", "delete", "update", "findandmodify" ] } }'
- Audit events on creating or droping collections
filter: '{atype: {$in: ["createCollection", "dropCollection"]}}'
- Auidt filtered on Collection Creation and Drop Operations for a Single Database
filter: '{ atype: { $in: [ "createCollection", "dropCollection" ] }, "param.ns": /^test\\./ } }'
note: The regular expression requires two backslashes (\) to escape the dot (.).
Misc
Using Bsondump
If default is used for Audit log file, BSON format is used
To read BSON file, use the /usr/bin/bsondump command
bsondump /var/log/mongodb/auditLog.bson
{"atype":"authenticate","ts":{"$date":"2018-01-29T03:12:09.680Z"},"local":{"ip":"10.206.97.133","port":27017},"remote":{"ip":"10.206.97.133","port":45802},"users":[{"user":"monitor","db":"admin"}],"roles":[{"role":"clusterMonitor","db":"admin"}],"param":{"user":"monitor","db":"admin","mechanism":"SCRAM-SHA-1"},"result":0}
{"atype":"authenticate","ts":{"$date":"2018-01-29T03:12:29.679Z"},"local":{"ip":"10.206.97.133","port":27017},"remote":{"ip":"10.206.97.133","port":45802},"users":[{"user":"monitor","db":"admin"}],"roles":[{"role":"clusterMonitor","db":"admin"}],"param":{"user":"monitor","db":"admin","mechanism":"SCRAM-SHA-1"},"result":0}
The following is an example on how to find out who create a database called "prod"
bsondump auditLog.bson | jq -c 'select(.atype == "createDatabase") | select(.param.ns == "prod")'
{"atype":"createDatabase","ts":{"$date":"2017-02-17T12:13:48.142+0100"},"local":{"ip":"127.0.1.1","port":27017},"remote":{"ip":"127.0.0.1","port":47896},"users":[{"user":"prod_app","db":"admin"}],"roles":[{"role":"root","db":"admin"}],"param":{"ns":"prod"},"result":0}
Importing the Log into MongoDB for Seraching
> mongorestore -d auditdb -c auditcol auditLog.bson
2017-02-17T12:28:56.756+0100 checking for collection data in auditLog.bson
2017-02-17T12:28:56.797+0100 restoring auditdb.auditcol from auditLog.bson
2017-02-17T12:28:56.858+0100 no indexes to restore
2017-02-17T12:28:56.858+0100 finished restoring auditdb.auditcol (142 documents)
2017-02-17T12:28:56.858+0100 done
The import is done, and now we can query the collection for the same data from the MongoDB client:
> use auditdb
switched to db auditdb
> db.auditcol.find({atype: "createDatabase", param: {ns: "prod"}})
{ "_id" : ObjectId("58a6de78bdf080b8e8982a4f"), "atype" : "createDatabase", "ts" : { "$date" : "2017-02-17T12:13:48.142+0100" }, "local" : { "ip" : "127.0.1.1", "port" : 27017 }, "remote" : { "ip" : "127.0.0.1", "port" : 47896 }, "users" : [ { "user" : "prod_app", "db" : "admin" } ], "roles" : [ { "role" : "root", "db" : "admin" } ], "param" : { "ns" : "prod" }, "result" : 0 }
can we add multiple atype? I want monitor commands such as (createIndex, dropIndex, update, drop, dropDatabase, remove)
ReplyDeleteI accept there are numerous more pleasurable open doors ahead for people that took a gander at your site.accounting and bookkeeping services in dubai
ReplyDeleteCan be audited errors for failed CRUD commands?
ReplyDeleteNow I only can see the command itself and result code , if result code is not 0, so the command failed.
But we need the error message in audit log. Is it possible?