[box type="note" align="" class="" width=""]The following excerpt is taken from the book Mastering MongoDB 3.x written by Alex Giamas. It presents the techniques and essential concepts needed to tackle even the trickiest problems when it comes to working and administering your MongoDB instance.[/box]
Security is a multifaceted goal in a MongoDB cluster. In this article, we will examine different attack vectors and how we can protect MongoDB against them.
1. Authentication in MongoDB
Authentication refers to verifying the identity of a client. This prevents impersonating someone else in order to gain access to our data.
The simplest way to authenticate is using a username/password pair. This can be done via the shell in two ways:
> db.auth( <username>, <password> )
Passing in a comma separated username and password will assume default values for the rest of the fields:
> db.auth( {
user: <username>,
pwd: <password>,
mechanism: <authentication mechanism>,
digestPassword: <boolean>
} )
If we pass a document object we can define more parameters than username/password.
The (authentication) mechanism parameter can take several different values with the default being SCRAM-SHA-1. The parameter value MONGODB-CR is used for backwards compatibility with versions earlier than 3.0
MONGODB-X509 is used for TLS/SSL authentication. Users and internal replica set servers can be authenticated using SSL certificates, which are self-generated and signed, or come from a trusted third-party authority.
This for the configuration file:
security.clusterAuthMode / net.ssl.clusterFile
Or like this on the command line:
--clusterAuthMode and --sslClusterFile
> mongod --replSet <name> --sslMode requireSSL --clusterAuthMode x509 --sslClusterFile <path to membership certificate and key PEM file> --sslPEMKeyFile <path to SSL certificate and key PEM file> --sslCAFile <path to root CA PEM file>
MongoDB Enterprise Edition, the paid offering from MongoDB Inc., adds two more options for authentication.
The first added option is GSSAPI (Kerberos). Kerberos is a mature and robust authentication system that can be used, among others, for Windows based Active Directory Deployments.
The second added option is PLAIN (LDAP SASL). LDAP is just like Kerberos; a mature and robust authentication mechanism. The main consideration when using PLAIN authentication mechanism is that credentials are transmitted in plaintext over the wire. This means that we should secure the path between client and server via VPN or a TSL/SSL connection to avoid a man in the middle stealing our credentials.
After we have configured authentication to verify that users are who they claim they are when connecting to our MongoDB server, we need to configure the rights that each one of them will have in our database.
This is the authorization aspect of permissions. MongoDB uses role-based access control to control permissions for different user classes.
Every role has permissions to perform some actions on a resource. A resource can be a collection or a database or any collections or any databases.
The command's format is:
{ db: <database>, collection: <collection> }
If we specify "" (empty string) for either db or collection it means any db or collection.
For example:
{ db: "mongo_books", collection: "" }
This would apply our action in every collection in database mongo_books. Similar to the preceding, we can define:
{ db: "", collection: "" }
We define this to apply our rule to all collections across all databases, except system collections of course.
We can also apply rules across an entire cluster as follows:
{ resource: { cluster : true }, actions: [ "addShard" ] }
The preceding example grants privileges for the addShard action (adding a new shard to our system) across the entire cluster. The cluster resource can only be used for actions that affect the entire cluster rather than a collection or database, as for example shutdown, replSetReconfig, appendOplogNote, resync, closeAllDatabases, and addShard. What follows is an extensive list of cluster specific actions and some of the most widely used actions.
The list of most widely used actions are:
find
insert
remove
update
bypassDocumentValidation
viewRole / viewUser
createRole / dropRole
createUser / dropUser
inprog
killop
replSetGetConfig / replSetConfigure / replSetStateChange / resync
getShardMap / getShardVersion / listShards / moveChunk / removeShard /
addShard
dropDatabase / dropIndex / fsync / repairDatabase / shutDown
serverStatus / top / validate
Cluster-specific actions are:
unlock
authSchemaUpgrade
cleanupOrphaned
cpuProfiler
inprog
invalidateUserCache
killop
appendOplogNote
replSetConfigure
replSetGetConfig
replSetGetStatus
replSetHeartbeat
replSetStateChange
resync
addShard
flushRouterConfig
getShardMap
listShards
removeShard
shardingState
applicationMessage
closeAllDatabases
connPoolSync
fsync
getParameter
hostInfo
logRotate
setParameter
shutdown
touch
connPoolStats
cursorInfo
diagLogging
getCmdLineOpts
getLog
listDatabases
netstat
serverStatus
top
If this sounds too complicated that is because it is. The flexibility that MongoDB allows in configuring different actions on resources means that we need to study and understand the extensive lists as described previously.
Thankfully, some of the most common actions and resources are bundled in built-in roles. We can use the built-in roles to establish the baseline of permissions that we will give to our users and then fine grain these based on the extensive list.
There are two different generic user roles that we can specify:
read
: A read-only role across non-system collections and the following system collections: system.indexes, system.js, and system.namespaces collections
readWrite
: A read and modify role across non-system collections and the system.js collection
There are three database specific administration roles shown as follows:
dbAdmin
: The basic admin user role which can perform schema-related tasks, indexing, gathering statistics. A dbAdmin cannot perform user and role management.
userAdmin
: Create and modify roles and users. This is complementary to the dbAdmin role.
dbOwner
: Combining readWrite, dbAdmin, and userAdmin roles, this is the most powerful admin user role.
These are the cluster wide administration roles available:
hostManager
: Monitor and manage servers in a cluster.
clusterManager
: Provides management and monitoring actions on the cluster. A user with this role can access the config and local databases, which are used in sharding and replication, respectively.
clusterMonitor
: Read-only access for monitoring tools provided by MongoDB such as MongoDB Cloud Manager and Ops Manager agent.
clusterAdmin
: Provides the greatest cluster-management access. This role combines the privileges granted by the clusterManager, clusterMonitor, and hostManager roles. Additionally, the role provides the dropDatabase action.
Role-based authorization roles can be defined in the backup restore granularity level as Well:
backup
: Provides privileges needed to back-up data. This role provides sufficient privileges to use the MongoDB Cloud Manager backup agent, Ops Manager backup agent, or to use mongodump.
restore
: Provides privileges needed to restore data with mongorestore without the --oplogReplay option or without system.profile collection data.
Similarly, here are the set of available roles across all databases:
readAnyDatabase
: Provides the same read-only permissions as read, except it applies to all but the local and config databases in the cluster. The role also provides the listDatabases action on the cluster as a whole.
readWriteAnyDatabase
: Provides the same read and write permissions as readWrite, except it applies to all but the local and config databases in the cluster. The role also provides the listDatabases action on the cluster as a whole.
userAdminAnyDatabase
: Provides the same access to user administration operations as userAdmin, except it applies to all but the local and config databases in the cluster.
Since the userAdminAnyDatabase role allows users to grant any privilege to any user, including themselves, the role also indirectly provides superuser access.
dbAdminAnyDatabase
: Provides the same access to database administration operations as dbAdmin, except it applies to all but the local and config databases in the cluster. The role also provides the listDatabases action on the cluster as a whole.
Finally, these are the superuser roles available:
root
: Provides access to the operations and all the resources of the readWriteAnyDatabase, dbAdminAnyDatabase, userAdminAnyDatabase, clusterAdmin, restore, and backup combined.
__internal
: Similar to root user, any __internal user can perform any action against any object across the server.
Apart from MongoDB specific security measures, there are best practices established for network level security:
No matter how much we plan our security measures, a second or third pair of eyes from someone outside our organization can give a different view of our security measures and uncover problems that we may not have thought of or underestimated. Don't hesitate to involve security experts / white hat hackers to do penetration testing in your servers.
Medical or financial applications require added levels of security for data privacy reasons.
If we are building an application in the healthcare space, accessing users' personal identifiable information, we may need to get HIPAA certified.
If we are building an application interacting with payments and managing cardholder information, we may need to become PCI/DSS compliant. The specifics of each certification are outside the scope of this book but it is important to know that MongoDB has use cases in these fields that fulfill the requirements and as such it can be the right tool with proper design beforehand.
To sum up, in addition to the best practices listed above, developers and administrators must always use common sense so that security interferes only as much as needed with operational goals.
If you found our article useful, make sure to check out this book Mastering MongoDB 3.x to master other MongoDB administration-related techniques and become a true MongoDB expert.