The 6 Aspects You Must Secure On Your MongoDB Instances
Authentication, authorization, and accounting and key aspects of MongoDB instances. Here, we explore some quick wins to improve their security.
Join the DZone community and get the full member experience.Join For Free
After going through the adventure of deploying a high-availability MongoDB cluster on Docker and sharing it publicly, I decided to complement that tutorial with some security concerns and tips.
In this post, you'll learn a few details about MongoDB deployment vulnerabilities and security mechanisms. And more importantly, how to actually protect your data with these features.
- understand database aspects of security.
- Find ways to implement authentication, authorization, and accounting (AAA).
- Learn how to enable MongoDB security features.
Any running MongoDB instance on which you have full access will do. Standalone or replica set, containerized or not. We will also mention some details on MongoDB Docker instances, but we’ll keep Docker-specific security tips for another post.
List of Quick Wins
Accessing data in a database has several stages. We will look at these stages and find ways to harden them, to get a cumulative security effect at the end. Most of the time, each of these stages will have the ability to block the next one (e.g., you need to have network access to get to the authentication part).
1. Network Access
MongoDB’s default port is 27017 (TCP). Choosing a different port to operate might confuse some hackers, but it is still a minor security action because of port scanning, so you won't get that much out of it.
Assuming we choose the default port for our service, we will open that port on the database server's firewall. We do not wish to expose the traffic from this port to the internet. There are two approaches to solve that and both can be used simultaneously. One is limiting your traffic to your trusted servers through firewall configuration.
There’s a MongoDB feature you can use for this: IP Binding. You pass the
--bind_ip argument on the MongoDB launch command to enable it. Let's say your
app1 server needs to access the MongoDB server for data. To limit traffic for that specific server, you start your server as:
mongod --bind_ip localhost,app1
If you are using Docker, you can avoid this risk by using a Docker network between your database and your client application.
You can add another layer of network security by creating a dedicated network segment for databases, in which you apply an ACL (access list) in the router and/or switch configuration.
2. System Access
The second A in AAA means authorization. We know privileged shell access is needed during database installation. When concluding the installation, locking system root user access is part of the drill.
Data analysts need to read database data and applications also need to read and (almost always) write data as well. As this can be addressed with database authentication (more on this on 4. Authorization), make sure to restrict root and other shell access to people who can't do their jobs without it. Only allow it for database and system administrators.
Furthermore, running MongoDB processes with a dedicated operating system user account is a good practice. Ensure that this account has permission to access data but no unnecessary permissions.
Authentication is the first A in AAA. Authentication-wise, MongoDB supports 4 mechanisms:
- SCRAM (default)
- x.509 certificate authentication
- LDAP proxy authentication
- Kerberos authentication
If you are using MongoDB Enterprise Server, then you can benefit from LDAP and Kerberos support. Integrating your company identity and access management tool will make AAA 3rd A (Accounting) implementation easier, as every user will have a dedicated account associated with his records.
MongoDB has its own SCRAM implementations: SCRAM_SHA1 for versions below 4.0 and SCRAM_SHA256 for 4.0 and above. You can think of SHA-256 as the successor of SHA-1, so pick the latter if available on your database version.
Replica sets keyfiles also use the SCRAM authentication mechanism where these keyfiles contain the shared password between the replica set members. Another internal authentication mechanism supported in replica sets is x.509. You can read more on replica sets and how to generate keyfiles in our previous blog post.
To be able to use the x.509 certificates authentication mechanism, there are some requirements regarding certificate attributes. To enable x.509 authentication, add
--tlsCAFile (in case the certificate has a certificate authority). To perform remote connections to the database, specify the
mongod --tlsMode requireTLS --tlsCertificateKeyFile <path to TLS/SSL
certificate and key PEM file> --tlsCAFile <path to root CA PEM file>
To generate these certificates, you can use the
openssl library on Linux or the equivalent on other operating systems.
openssl x509 -in <pathToClientPEM> -inform PEM -subject -nameopt RFC2253
The command returns the subject string as well as the certificate:
Next, add a user on the $external database using the obtained subject string like in the example below:
Finally, connect to the database with the arguments for TLS, certificates location, CA file location, authentication database, and the authentication mechanism.
mongo --tls --tlsCertificateKeyFile <path to client PEM file>
--tlsCAFile <path to root CA PEM file> --authenticationDatabase '$external'
You have now successfully connected to your database using the x.509 authentication mechanism.
For non-testing environments (like production) it is clearly not recommended to have Access Control disabled, as this grants all privileges to any successful access to the database. To enable authentication, follow the procedure below.
# start MongoDB without access control
# connect to the instance
# start MongoDB with access control
If you're using MongoDB on Docker, you can create an administrator through
MONGO_INITDB_ROOT_PASSWORD environment variables (
-e argument). Like so:
docker run -d -e MONGO_INITDB_ROOT_USERNAME=<username> -e
Do not neglect human usability convenience. Make sure all passwords are strong, fit your company's password policy, and are stored securely.
MongoDB has a set of built-in roles and allows us to create new ones. Use roles to help when giving privileges while applying the principle of least privilege on user accounts and avoid user account abuse.
5. Encrypted Connections
Let's now see how to configure encrypted connections to protect you from sniffing attacks.
If you think about internet browsers, you notice how they keep pressing for users to navigate on sites that support HTTP over TLS, also known as HTTPS. That enforcement exists for a reason: sensitive data protection, both for the client and the server. TLS is therefore protecting this sensitive data during the client-server communication, bidirectionally.
We have explained how to use TLS certificates on 4. Authentication and now we will see how to encrypt our communications between the database server and a client app through TLS configuration on the application’s MongoDB driver.
First, to configure the MongoDB server to require our TLS certificate, add the
mongod --tlsMode requireTLS --tlsCertificateKeyFile <pem>
To test the connection to mongo shell, type in:
mongo --tls --host <hostname.example.com> --tlsCertificateKeyFile
Then, add TLS options to the database connection on your application code. Here is a snippet of a NodeJS application using MongoDB’s official driver package. You can find more of these encryption options on the driver documentation.
6. Encryption at Rest
MongoDB Enterprise Server comes with an Encryption at Rest feature. Through a master and database keys system, this allows us to store our data in an encrypted state by configuring the field as encrypted on rest. You can learn more about the supported standards and enciphering/deciphering keys on the MongoDB documentation.
On the other side, if you will stick with the MongoDB Community, on v4.2 MongoDB started supporting Client-Side Field Level Encryption. Here’s how it works: you generate the necessary keys and load them in your database driver (e.g. NodeJS MongoDB driver). Then, you will be able to encrypt your data before storing it in the database and decrypt it for your application to read it.
While this post attempts to cover some of the most important quick wins you can achieve to secure your MongoDB instances, there is much more to MongoDB security.
Upgrading database and driver versions frequently, connecting a monitoring tool, and keeping track of database access and configuration are also good ideas to increase security.
Nevertheless, even if the system was theoretically entirely secured, it is always prone to human mistakes. Make sure the people working with you are conscious of the importance of keeping data secured - properly securing a system is always contingent on all users taking security seriously.
Security is everyone's job. Like in tandem kayaks, it only makes sense if everyone is paddling together in the same direction, with all efforts contributing to the same purpose.
Published at DZone with permission of Rui Trigo. See the original article here.
Opinions expressed by DZone contributors are their own.