Here is a quick guide on setting up a MongoDB 3.4 server on Ubuntu 16.04, with practical advice on securing the installation.

Installation

Let’s spin up a node in your favorite cloud provider, with an Ubuntu 16.04 base image. Follow the steps below to install the v3.4.x community edition of MongoDB from MongoDB APT repository.

# add the MongoDB APT repo echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list # trust the signing key sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6 # update repo information sudo apt-get -yq update # install sudo apt-get install -yq mongodb-org

Private Network

Ideally, the MongoDB node, as well as the other nodes that need to talk to the MongoDB nodes should be placed on a secure, internal network. All communication with MongoDB should take place over this network, and never over public internet. Additionally, even this communication over the private network should be encrypted.

For example, Google Cloud provides a private network for all the VMs in a project, and each VM can get a public IP as well as a private IP. DigitalOcean provides a “shared private” network, which really is not a “private” network. Any port you expose over a “private” IP on DigitalOcean is accessible to all the droplets in that datacenter.

If your cloud provider does not provide a true private network, you should consider building an overlay VPN, for example using OpenVPN, Tinc VPN, or even Weave.

Configuration File

In the configuration file /etc/mongod.conf , update the address to which the mongod process listens on to the private IP of the node:

net : bindIp : <private ip>

If you don’t need the built-in HTTP interfaces of MongoDB, you should disable them. (This is disabled by default in 3.4, but that was not the case earlier.) If you’re going to interact with MongoDB only via client libraries or the mongo shell, you don’t need the HTTP interface.

net : http : enabled : false JSONPEnabled : false RESTInterfaceEnabled : false

You should also consider placing a stricter upper bound on the maximum number of connections to the database. The default value of 65536 might be too high for most installations. Monitor the total open connections during peak traffic, and set a value higher than that.

net : http : maxIncomingConnections : 100

Restricting Access at IP Level

Access to the MongoDB mongod port 27017 should be permitted:

only over the internal network, and

only from permitted nodes.

You should use your cloud providers’ access control features, like AWS Security Groups or Google Cloud Firewall to enforce these two rules.

If you’re using DigitalOcean or similar providers you should use iptables, ufw, firewalld etc. While these solutions are difficult to scale, it is essential that you use these for the sake of security. If your cloud provider does not provide a true private network, you must use this to restrict access to each node to your other nodes only.

Setup User Authentication

Let’s enable user authentication for this MongoDB server. With this, you’ll be able to connect to MongoDB only with a valid username and password. First, let’s start mongod as is:

$ sudo systemctl start mongod && sudo systemctl status mongod ● mongod.service - High-performance, schema-free document-oriented database Loaded: loaded (/lib/systemd/system/mongod.service; disabled ; vendor preset: enabled ) Active: active (running) since Fri 2017-01-13 14:28:39 IST; 37ms ago Docs: https://docs.mongodb.org/manual Main PID: 2027 (mongod) Tasks: 1 Memory: 5.5M CPU: 14ms CGroup: /system.slice/mongod.service └─2027 /usr/bin/mongod --quiet --config /etc/mongod.conf Jan 13 14:28:39 mongo1 systemd[1]: Started High-performance, schema-free document-oriented database.

Next, we create a user with admin privileges:

$ mongo MongoDB shell version v3.4.1 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.1 > use admin switched to db admin > db.createUser ({ user: "wheel" , pwd : "p@ssw0rd" , roles: [ { role: "userAdminAnyDatabase" , db: "admin" } ] }) Successfully added user: { "user" : "wheel", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }

Now you have a user called wheel , who can create further users. However, authentitcation is not yet enabled. For that, edit /etc/mongod.conf yet again, and add:

security : authorization : enabled

And restart mongod again:

$ sudo systemctl restart mongod

Now you should be able to connect to the mongodb by supplying the credentials:

$ mongo -u wheel -p p@ssw0rd private.ip/admin

You should create more users as needed, and with roles that are appropriate to their need. The MongoDB docs have more information. Also see the list of built-in roles – the userAdminAnyDatabase role that we used above is one of them.

Encrypted Communication

You should also ensure that you communicate with MongoDB over TLS. Ideally, you’ll configure your MongoDB so that it requires TLS for all connections.

These MongoDB docs explain how to configure your MongoDB server for TLS.

Once you’ve done that, you’ll also want to learn how clients can connect to such servers.

Monitoring

Every MongoDB in production needs to be monitored. Using OpsDash, you can quickly start monitoring your MongoDB instances without having to install plugins or agents. OpsDash provides a well-thought-out dashboard that displays metrics that are most relevant to the health and performance of the MongoDB instances being monitored.

You can find out more about monitoring MongoDB and MongoDB clusters here.

Got MongoDB setup? Ready to start monitoring? Check out the OpsDash SaaS Beta! It’s free and you can be up and running with MongoDB monitoring in a matter of mintues. Sign Up today!

New Here?

OpsDash is a server monitoring, service monitoring, and database monitoring solution for monitoring MySQL, PostgreSQL, MongoDB, memcache, Redis, Apache, Nginx, HTTP URLs, Elasticsearch and more. It provides intelligent, customizable dashboards and spam-free alerting via email, HipChat, Slack, PagerDuty and PushBullet.