#MongoDB 3.2.x Security
##Network Ports The standard ports used by mongo are:
Process | Role | Default Port |
---|---|---|
mongod | Stand-alone | 27017 |
--shardsvr | 27018 | |
--configsvr | 27019 | |
mongos | n/a | 27017 |
Status page (off) | +1000 |
You should limit access to the mongo servers using firewall rules to specify the ip addresses that can connect to the database. You can change the default ports but this will not stop an automated script.
You can also limit which specific interfaces are connected to mongo using the bindIp: 10.23.22.11
in the mongod.conf.
Remember that replica/shards sets listen on 27018 and the config server listens on 27019.
##Mongo with SSL You can enable SSL on your Mongo server by setting it in your mongod.conf.
net:
ssl:
mode: requireSSL
PEMKeyFile: /certs/example_cert.pem
PEMKeyPassword: myPassword
CAFile: /certs/cacert.pem
You can have four different modes:
- requireSSL - Client must use SSL
- allowSSL - Clients may or may not use SSL. Servers do not use SSL to talk to other servers.
- preferSSL - Clients may or may not use SSL. Servers will use SSL to talk to other servers.
- disabled - Do not use SSL. This is the default.
The PEMKeyFile is the certificate. It should be the fully qualified server name ie mongo0.example.com
. Your certificates location should also be protected using file security.
##Connecting to a Mongo using SSL To connect to a mongo instance using the shell you need to do:
mongo --ssl -sslCAFile /certs/cacert.pem --host mongo0.example.com --sslPEMKeyFile /certs/example_cert.pem --sslPEMKeyPassword myPassword
##Check the Server Security Status
db.serverStatus().security
{
"SSLServerSubjectName": "emailAddress=demo@example.com,CN=mongo0.example.com,OU=HQ,O=Plus N,ST=CA,C=US",
"SSLServerHasCertificateAuthority": true,
"SSLServerCertificateExpirationDate": ISODate("2020-12-31T23:00:00Z")
}
##Users & Roles There are a number of predefined roles:
- root - All powerful. Use with caution
- userAdminAnyDatabase - Can create users and assign roles on any database. Use with caution
- userAdmin - Can only create users and assign roles in a specific database
- read - Read collections in a specific database.
- readWrite - Read and Write to a specific database
###Enabling Authentication
To enable authentication you need to ensure that the following line is added to the mongod.conf
:
security:
authorization: enabled
Then restart mongo. You can connect to a local mongo with the shell and there are no users defined. This is called the localhost exception. It allows you to gain access so that you can start setting up the users. Once the first user is created the localhost exception no longer applies.
###First User The first user should be an admin user that can manage the database.
use admin
var adminUser = {
"user": "adminUser",
"pwd": "mypassword",
"readOnly" : false,
"roles": [
{
"role": "userAdminAnyDatabase",
"db": "admin"
}
]
}
db.createUser(adminUser)
The readOnly: false
option give the adminUser readWrite access to all databases.
####Reporting User Change the database to the applicationDB unless you want to have a central authentication using the admin database.
user applicationDB
var rptUser = {user: 'rptUser', pwd: '1234', roles: [{role: 'read', db: 'mydatabase'}]}
db.createUser(rptUser)
####Application
use applicationDB
var appUser = {user: 'appUser', pwd: '1234', roles: [{role: 'readWrite', db: 'mydatabase'}]}
db.createUser(appUser)
###Deleting a user:
db.dropUser("fred")
###Add Roles to Users If we want to add the ability for the adminUser to be able to read and write to the database then we can grant this role to the user. The admin user can manage users and roles.
db.grantRolesToUser("adminUser",["readWrite"])
When the role is expressed as a string ie "readWrite" then it is assumed to mean the current database.
To give access to specific database
db.grantRolesToUser("fred",[{db: "mydatabase", role: "read"])
To remove a role from a user:
db.revokeRolesFromUser("fred", ["read"])
###Viewing user Details There are two ways to view the user details:
show users
or, if you can read the system.users
table, you can just find it.
##Authentication Database If it quite possible to authenticate with a different database from the one you are using. For example you may have a number of databases but only one central user database. The user will still only have the rights on the database that have been assigned to it, regardless of the authentication right on the user database. To log on using a specific authentication database:
mongo --username fred --password mypassword --authenticationDatabase userdatabase
##Logging in and out from the mongo Shell
db.logout("fred") db.auth("fred","mypassword")
##Intra Cluster Authentication To ensure that all members of a cluster (replica set or shards or both) are real you can give each one a key file containing a shared secret. The Key File has the following properties:
- Arbitrary content
- 6-1024 characters
- Base64 characters only
- User-only file read properties
You need to specify the Key File in the mongod.conf.
###Server1
storage:
dbPath: /data
replication:
replSetName: rs1
security:
keyFile: /certs/clusterKeyFile.txt
clusterAuthMode: sendKeyFile
net:
port: 27017
ssl:
mode: requireSSL
PEMKeyFile: /certs/clusterHost1_complete.pem
PEMKeyPassword: mypassword
CAFile: /certs/cacert.pem
###Server2
storage:
dbPath: /data
replication:
replSetName: rs1
security:
keyFile: /certs/clusterKeyFile.txt
clusterAuthMode: sendKeyFile
net:
port: 27017
ssl:
mode: requireSSL
PEMKeyFile: /certs/clusterHost2_complete.pem
PEMKeyPassword: mypassword
CAFile: /certs/cacert.pem
###Initiating a replica set using SSL Certs
When you intitialize a set which are using certs you ned to specify the exact name as per the certs:
var cfg = { _id: "rs1", members: [{_id: 0, "host1.example.com:27017"}, {_id: 1, "host2.example.com:27017"}] }
rs.initiate(cfg)
You then need to create the ```superUser``` so that you can vire the ```rs.status()``` or ```rs.config()```.
use admin
db.createUser({ "user": "root", "pwd": "mypassword", "roles": ["root"]})
Then log in as this user:
db.auth("root","mypassword")
rs.config()
That means the replica set is running with SSL and Authentication is enabled and it is uing a Key File to authenticate the members of the cluster.