I'm currently using MongoDB to record application logs, and while I'm quite happy with both the performance and with being able to dump arbitrary structured data into log records, I'm troubled by the mutability of log records once stored.
In a traditional database, I would structure the grants for my log tables such that the application user had INSERT and SELECT privileges, but not UPDATE or DELETE. Similarly, in CouchDB, I could write a update validator function that rejected all attempts to modify an e开发者_如何学Goxisting document.
However, I've been unable to find a way to restrict operations on a MongoDB database or collection beyond the three access levels (no access, read-only, "god mode") documented in the security topic on the MongoDB wiki.
Has anyone else deployed MongoDB as a document store in a setting where immutability (or at least change tracking) for documents was a requirement? What tricks or techniques did you use to ensure that poorly-written or malicious application code could not modify or destroy existing log records? Do I need to wrap my MongoDB logging in a service layer that enforces the write-only policy, or can I use some combination of configuration, query hacking, and replication to ensure a consistent, audit-able record is maintained?
I would say the best bet would be to wrap up the access to MongoDB in a service layer that enforces your specific contracts. We don't do much in the way of fine-grained access control because there are so many different cases that solving all of them correctly is tricky to get right. So for the most part it's up to the application layer to implement those kind of controls.
To add a write only (on collection level) user to the MongoDB do the following.
Say you want to have a user that can only write (insert only) to a certain collection on a certain database.
Create a file createuser.js
with following contents:
function createCollectionWriter(database, username, password, rolename, collection)
{
db.getSiblingDB(database).createUser({
user : username,
pwd : password,
roles : [ ]
});
db.getSiblingDB(database).createRole({
role : rolename,
privileges : [
{
resource : { db : database, "collection" : collection },
actions : [ "insert" ]
}
],
roles : []
});
db.getSiblingDB(database).grantRolesToUser(username, [ rolename ] );
}
And execute this from command-line
$ mongo --eval="load('createuser.js'); createCollectionWriter('yourdb', 'user1', 'pass1', 'rolename', 'col1')"
This creates a user with username user1 with password pass1 and this user has write only access to database's yourdb collection col1.
A side-effect of this is that role rolename is created. If you have existing user that should have a write only access to the same collection, grant role rolename to that existing user.
Feel free to use and modify the code provided above :).
In MongoDB 1.3.2+ you can add some restriction in user :
db.addUser("guest", "passwordForGuest", true)
But it's only existing now not better. Maybe you can add some feature request
see information in MongoDB documentation : http://www.mongodb.org/display/DOCS/Security+and+Authentication
精彩评论