Securing MongoDB on Linux VPS: Localhost-Only Configuration & Hardening Guide


4 views

The first critical step is restricting MongoDB to listen only on localhost. Edit your MongoDB configuration file (typically located at /etc/mongod.conf):


# network interfaces
net:
  port: 27017
  bindIp: 127.0.0.1  # Only listen on localhost

Additionally, configure your firewall to block all external access to MongoDB's default port (27017):


sudo ufw deny 27017
sudo ufw enable

Even for localhost connections, enable authentication. First, connect to MongoDB without authentication:


mongo --port 27017

Then create an admin user with appropriate privileges:


use admin
db.createUser({
  user: "admin",
  pwd: "complexPassword123!",
  roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
})

After creating users, enable authentication in mongod.conf:


security:
  authorization: enabled

Run MongoDB under a dedicated user account with minimal privileges:


sudo useradd --system --no-create-home --shell /bin/false mongodb_user
sudo chown -R mongodb_user:mongodb_user /var/lib/mongodb
sudo chown -R mongodb_user:mongodb_user /var/log/mongodb

Update your systemd service file (/lib/systemd/system/mongod.service) to reflect this user:


[Service]
User=mongodb_user
Group=mongodb_user

For a production localhost-only setup, disable features you don't need:


# Disable HTTP interface and REST API
net:
  http:
    enabled: false
    RESTInterfaceEnabled: false

# Disable scripting if not needed
security:
  javascriptEnabled: false

Implement these ongoing security measures:

  • Regularly apply security updates: sudo pacman -Syu
  • Enable MongoDB logging and monitor for suspicious activity
  • Consider implementing TLS even for localhost connections
  • Regularly audit user privileges and remove unnecessary accounts

Here's how to securely connect from your Node.js application:


const { MongoClient } = require('mongodb');
const uri = "mongodb://admin:complexPassword123!@localhost:27017/?authSource=admin";
const client = new MongoClient(uri);

async function run() {
  try {
    await client.connect();
    const database = client.db("yourDatabase");
    // ... your operations here
  } finally {
    await client.close();
  }
}
run().catch(console.dir);

When deploying MongoDB in production, especially on a VPS, security should be your top priority. Since you're running Arch Linux with localhost-only connections, we can implement several layers of protection without compromising functionality.

First, ensure MongoDB only listens on localhost by modifying the bindIp parameter in your mongod.conf:


# /etc/mongod.conf
net:
  port: 27017
  bindIp: 127.0.0.1

Even for localhost connections, authentication is crucial. Create an admin user first:


use admin
db.createUser({
  user: "admin",
  pwd: "complexPassword123!",
  roles: ["root"]
})

Then enable auth in your configuration:


# /etc/mongod.conf
security:
  authorization: enabled

Set proper permissions for MongoDB data directories:


chown -R mongodb:mongodb /var/lib/mongodb
chmod 700 /var/lib/mongodb

While binding to localhost prevents external connections, adding firewall rules provides extra protection:


# UFW example
sudo ufw deny 27017
sudo ufw allow from 127.0.0.1 to 127.0.0.1 port 27017

Keep MongoDB updated for security patches. On Arch Linux:


sudo pacman -Syu mongodb

For additional security between your web app and MongoDB, enable TLS:


# /etc/mongod.conf
net:
  ssl:
    mode: preferSSL
    PEMKeyFile: /etc/ssl/mongodb.pem
    CAFile: /etc/ssl/ca.pem

Set up proper logging to detect unauthorized access attempts:


systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
  logRotate: reopen

When connecting from your web app, use connection strings with proper authentication:


# Python example
from pymongo import MongoClient
client = MongoClient(
    "mongodb://admin:complexPassword123!@localhost:27017/?authSource=admin"
)