Securing MongoDB Server on Linux: Configuring RBAC, TLS, and Encryption at Rest

Security tutorial - IT technology blog
Security tutorial - IT technology blog

1. Quick Start (Lock Down Access in 5 Minutes)

By default after installing on Ubuntu or CentOS, MongoDB leaves its doors wide open without requiring any password. If you inadvertently expose port 27017 to the internet, automated scanners like Shodan will discover your database in minutes. Here are the fastest steps to eliminate this vulnerability immediately.

Step 1: Create a root admin user

Open a terminal on your server and connect to the MongoDB shell:

mongosh

Switch to the admin database and create the superuser administrative account:

use admin
db.createUser({
  user: "siteRootAdmin",
  pwd: "ExtremelyComplexPassword123!@#",
  roles: [ { role: "root", db: "admin" } ]
})
exit

Step 2: Enable authorization in the configuration file

Open /etc/mongod.conf with root privileges:

sudo nano /etc/mongod.conf

Locate the security section and enable authorization:

security:
  authorization: enabled

Also check the net section to ensure MongoDB does not bind indiscriminately to all interfaces:

net:
  port: 27017
  bindIp: 127.0.0.1

Step 3: Restart the service and verify

sudo systemctl restart mongod

# Test login with the newly created user
mongosh -u siteRootAdmin -p --authenticationDatabase admin

At this point, any connection attempt without valid credentials will be rejected immediately.

2. Deep Dive: 3 Layers of Defense for Production

While auditing infrastructure for various teams, I see this scenario repeatedly: developers simply drop the root user credentials into the .env files of 4–5 microservices. When a single service is compromised, attackers gain full control over the entire database cluster. For peace of mind, you need to establish three solid lines of defense: RBAC, TLS, and Encryption at Rest.

Layer 1: Role-Based Access Control (RBAC)

Golden rule: Principle of Least Privilege. Only grant backend services the exact permissions they need on their specific target database.

For example, creating an account for an API backend with dedicated readWrite access on ecommerce_db:

use ecommerce_db
db.createUser({
  user: "app_backend",
  pwd: "AppSecurePassword_2026_!$",
  roles: [
    { role: "readWrite", db: "ecommerce_db" }
  ]
})

For database passwords and internal connection strings, generate random strings of at least 24–32 characters. You can quickly use the Password Generator by ToolCraft. This utility runs 100% client-side in your browser without sending any data to a server, making it completely safe for generating secret keys.

Layer 2: Transport Encryption with TLS/SSL

If your MongoDB server and backend application reside on separate VPS instances, unencrypted network traffic can be sniffed over the wire. Bundle your certificate and private key into a single PEM file (e.g., /etc/ssl/mongodb.pem).

Configure TLS in /etc/mongod.conf:

net:
  port: 27017
  bindIp: 127.0.0.1,10.0.1.15
  tls:
    mode: requireTLS
    certificateKeyFile: /etc/ssl/mongodb.pem
    CAFile: /etc/ssl/ca.crt

Restart mongod and verify the connection using the CA certificate:

mongosh --tls --tlsCAFile /etc/ssl/ca.crt -u app_backend -p --authenticationDatabase ecommerce_db

3. Advanced: Encryption at Rest

Data-at-rest encryption protects your underlying data if someone leaks a disk snapshot or physically steals a storage drive.

Option 1: Native WiredTiger Encryption (MongoDB Enterprise)

MongoDB Enterprise supports native storage engine encryption for WiredTiger using a keyfile:

# Generate a random 32-byte keyfile and restrict permissions
openssl rand -base64 32 | sudo tee /etc/mongodb-keyfile
sudo chown mongodb:mongodb /etc/mongodb-keyfile
sudo chmod 400 /etc/mongodb-keyfile

Declare the keyfile path in /etc/mongod.conf:

security:
  authorization: enabled
  enableEncryption: true
  encryptionKeyFile: /etc/mongodb-keyfile

Option 2: Block Device Level Encryption (MongoDB Community)

MongoDB Community Edition lacks the native enableEncryption flag. The most effective approach is hosting the data directory /var/lib/mongodb on a kernel-level encrypted partition (LUKS) or using fscrypt. All data, indexes, and journal logs will be transparently encrypted. The I/O performance penalty typically sits around 2–4%, which is well within acceptable limits for production.

4. Battle-Tested Operational Tips

  • Validate YAML syntax before restarting: A single misaligned space or accidental tab in mongod.conf will cause the service to fail immediately upon restart. You can validate your file structure using the YAML ↔ JSON Converter to catch syntax errors early.
  • Restrict ports using UFW Firewall: Allow incoming traffic on port 27017 only from your backend server’s internal IP:
    sudo ufw default deny incoming
    sudo ufw allow from 10.0.1.20 to any port 27017 proto tcp
    sudo ufw reload
  • Beware of the database profiler: Avoid enabling profile: 2 (logging all queries) in production environments. During failed login attempts or updates containing sensitive records, MongoDB may log plaintext passwords into /var/log/mongodb/mongod.log.
  • Always enforce 400 permissions on key files: All TLS certificates and encryption keyfiles must be owned by the mongodb:mongodb user and set to read-only (chmod 400). MongoDB will refuse to start if it detects overly permissive key file permissions.
Share: