MongoDB on a Linux Server

Learn how to install and setup a MongoDB NoSQL database on a Linux server.

If you are not familiar with MongoDB, it is a NoSQL database, the most popular one. It can be downloaded and installed for free and it has a great community. In addition to that, it is available for Windows, Mac and Linux operating systems and is supported by all of the popular programming languages. The difference between SQL (like MySQL, PostgerSQL…) and NoSQL databases is that NoSQL stores data in documents/collections which are in a JSON format with a flexible schema, while SQL stores data in tables with a fixed schema. In my opinion, the flexible schema is a really big advantage but if used without caution, it can be dangerous.

Install and setup

In this post we will not go into details about MongoDB, we will only show you how to install it on your server and secure it for local environment. First of all, install mongodb package by running sudo apt install mongodb. This will install mongodb server, client and do the basic setup of a database. With this done, we will change some configurations in /etc/mongodb.conf. If this file does not exist on your server, create it.

  dbpath=/data/mongo/db
  logpath=/data/mongo/log/mongo.log
  logappend=true
  bind_ip=127.0.0.1
  port=27017
  journal=true

As you can see, we have specified database path and log path. If they do not exist in your filesystem, you will need to create them. In addition to that, we have also bind a database to a localhost on port 27017 which means that only users from the localhost can access it. This is good since we do not want to allow access over internet or local network. If you want to expose the database to the internet in your production environment I will highly suggest you to research MongoDB security or use MongoDB Atlas. This configuration is not suitable for production environments where database is exposed to the internet!

Now we can restart mongodb by running sudo /etc/init.d/mongodb restart and after that access the database by running command mongo. While in database, we will create a root user by running next commands:

  use admin
  db.createUser(
    {
      user: "SOME_ADMIN_NAME",
      pwd: "SOME_ADMIN_PASSWORD",
      roles: [ "root" ]
    }
  )
  exit

Now we have root/admin user for the database and authorization can be enabled. This will prevent unauthorized users to access data from the database and run commands. Authorization will be enabled in /etc/mongodb.conf by adding auth = true. With this done we can restart mongodb. If we enter the database by running only mongo and try to list databases by running show dbs mongo will deny the command, this command and any other. This means that we need to access mongo with an authorized user. This can be done with the command mongo -u USERNAME -p --authenticationDatabase DATABASE.

With this done, our database is now accessable only from the localhost and is requiring authorization but have in mind that database files are not encrypted, therefore restrict access to database files. In my case this is the directory /data/mongo, I will run the commands:

	sudo chmod 770 -R /data/mongo
	sudo chown root:mongodb -R /data/mongo

Always restrict access to parts of your server and create user for every action or group of actions that user is allowed to do on the server. In many cases this is not very convenient for the end user but it will allow you to sleep better at night as a system administrator.

Manual and automatic DB backup

MongoDB provides a command to dump database collections into BSON files by running:

	mongodump -u USERNAME -p --authenticationDatabase AUTH_DATABASE -d DATABASE -o BACKUP_DIR

Please have in mind that BSON files in this state are not encrypted, therefore if backups are stored on the same server, do not forger to restrict access to the files. It is a good idea to allow only root linux user to access the files and root directory.

For automatic backups we can create a simple script that will run mongodump for us and add a script execution to the CRON job. This is not the safest solution but it is good enough for the majority of applications. We will create a structure where the script will be stored.

  mkdir /backups
  mkdir /backups/mongo
  mkdir /backups/mongo/db_name
  cd /backups/mongo
  touch mdb.sh
  touch mdb.log
  sudo chown -R root:root /backups
  sudo chmod -R 700 /backups

Now we can write the script:

	#!/bin/bash
	log_path="/backups/mongo/mdb.log"
	date=$(date)
	db_name="${1}"
	backup_path="/backups/mongo/${db_name}/${db_name}__${date}"
	user="${2}"
	pass="${3}"

	echo -e "\n\nMongoDB - backup DB \"${db_name}\" at \"${backup_path}\" for ${date}\n" >> $log_path

	mkdir "${backup_path}"

	mongodump -u "${user}" -p "${pass}" --authenticationDatabase "${db_name}" -d "${db_name}" -o "${backup_path}" &>> $log_path

	chown -R root:root "${backup_path}"
	chmod 700 -R "${backup_path}"

	echo -e "\n\n---done---" >> $log_path

As you can see this script is very simple. It is accepting 3 parameters: database name, username and password. After that, it is running mongodump command and restricting access to the dump directory. We can test the script by running:

	./mdb.sh DATABASE DB_USER DB_USER_PASS

Never user a database root user for this command. Use a user that has permission to access only specified database and run only the backup command. Now we can create the CRON job that will execute the script as shown:

 
	crontab -e
	0 0 * * */6 /bin/bash -c "/backups/mongo/mdb.sh DATABASE DB_USER DB_USER_PASS"

Script will be executed on every 6th day of the week. You can go to crontab guru for calculating time for the cron.

Share on: