BLOG POSTS
How to Secure MongoDB on Ubuntu 24

How to Secure MongoDB on Ubuntu 24

MongoDB is a powerful NoSQL database that’s become a cornerstone of modern web applications, but out-of-the-box installations on Ubuntu 24 can leave your data vulnerable to attacks. Many developers rush through the initial setup without implementing proper security measures, which can lead to data breaches, unauthorized access, and compliance issues. This comprehensive guide will walk you through the essential steps to harden your MongoDB installation on Ubuntu 24, covering authentication, authorization, network security, encryption, and monitoring practices that will keep your database secure in production environments.

Understanding MongoDB Security Architecture

Before diving into the implementation, it’s crucial to understand how MongoDB’s security model works. MongoDB uses a multi-layered security approach that includes authentication (who you are), authorization (what you can do), auditing (what you did), and encryption (protecting data in transit and at rest).

The security architecture consists of several key components:

  • Authentication mechanisms – SCRAM-SHA-1, SCRAM-SHA-256, x.509 certificates, LDAP, and Kerberos
  • Role-based access control (RBAC) – Built-in roles and custom role definitions
  • Network security – IP whitelisting, SSL/TLS encryption, and firewall configurations
  • Audit logging – Comprehensive logging of database operations for compliance
  • Encryption – Both at-rest and in-transit data protection

Initial MongoDB Installation and Basic Configuration

Let’s start with a fresh MongoDB installation on Ubuntu 24. If you haven’t installed MongoDB yet, here’s the recommended approach:

# Import the public key used by the package management system
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor

# Create the list file for MongoDB
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list

# Update the package database
sudo apt-get update

# Install MongoDB
sudo apt-get install -y mongodb-org

# Start and enable MongoDB service
sudo systemctl start mongod
sudo systemctl enable mongod

After installation, verify that MongoDB is running:

sudo systemctl status mongod
mongosh --eval 'db.runCommand({ connectionStatus: 1 })'

Step-by-Step Security Implementation

Step 1: Enable Authentication and Create Administrative User

By default, MongoDB runs without authentication enabled, which is a major security risk. Let’s fix this immediately:

# Connect to MongoDB shell
mongosh

# Switch to admin database
use admin

# Create an administrative user
db.createUser({
  user: "admin",
  pwd: passwordPrompt(),
  roles: [
    { role: "userAdminAnyDatabase", db: "admin" },
    { role: "readWriteAnyDatabase", db: "admin" },
    { role: "dbAdminAnyDatabase", db: "admin" },
    { role: "clusterAdmin", db: "admin" }
  ]
})

# Exit MongoDB shell
exit

Now enable authentication by editing the MongoDB configuration file:

sudo nano /etc/mongod.conf

Add or modify the security section:

security:
  authorization: enabled

Restart MongoDB to apply the changes:

sudo systemctl restart mongod

Test the authentication:

# This should fail
mongosh --eval 'db.runCommand({ listCollections: 1 })'

# This should succeed
mongosh -u admin -p --authenticationDatabase admin --eval 'db.runCommand({ listCollections: 1 })'

Step 2: Configure Network Security

By default, MongoDB binds to all network interfaces, which is dangerous in production. Let’s restrict access:

sudo nano /etc/mongod.conf

Modify the network interfaces section:

net:
  port: 27017
  bindIp: 127.0.0.1,10.0.1.100  # Replace with your server's private IP
  maxIncomingConnections: 65536
  unixDomainSocket:
    enabled: true
    pathPrefix: /tmp
    filePermissions: 0700

Configure the firewall to allow MongoDB connections only from trusted sources:

# Enable UFW if not already enabled
sudo ufw enable

# Allow SSH (important - don't lock yourself out!)
sudo ufw allow ssh

# Allow MongoDB from specific IP ranges (adjust as needed)
sudo ufw allow from 10.0.1.0/24 to any port 27017
sudo ufw allow from 192.168.1.0/24 to any port 27017

# Check the status
sudo ufw status verbose

Step 3: Enable SSL/TLS Encryption

Encrypting data in transit is essential for production environments. Let’s generate a self-signed certificate for testing (use a proper CA-signed certificate in production):

# Generate private key and certificate
sudo openssl req -newkey rsa:2048 -new -x509 -days 3653 -nodes -out /etc/ssl/mongodb-cert.crt -keyout /etc/ssl/mongodb-cert.key

# Combine certificate and key into a single file
sudo cat /etc/ssl/mongodb-cert.key /etc/ssl/mongodb-cert.crt > /etc/ssl/mongodb.pem

# Set proper permissions
sudo chown mongodb:mongodb /etc/ssl/mongodb.pem
sudo chmod 400 /etc/ssl/mongodb.pem

Update the MongoDB configuration:

net:
  port: 27017
  bindIp: 127.0.0.1,10.0.1.100
  tls:
    mode: requireTLS
    certificateKeyFile: /etc/ssl/mongodb.pem
    allowConnectionsWithoutCertificates: true

Restart MongoDB and test the SSL connection:

sudo systemctl restart mongod

# Test SSL connection
mongosh --tls --host localhost:27017 -u admin -p --authenticationDatabase admin

Step 4: Implement Role-Based Access Control

Create specific users for different applications and purposes instead of using the admin user:

mongosh --tls --host localhost:27017 -u admin -p --authenticationDatabase admin

# Create a database-specific user
use myapp
db.createUser({
  user: "myapp_user",
  pwd: passwordPrompt(),
  roles: [
    { role: "readWrite", db: "myapp" }
  ]
})

# Create a read-only user for analytics
db.createUser({
  user: "analytics_user",
  pwd: passwordPrompt(),
  roles: [
    { role: "read", db: "myapp" }
  ]
})

# Create a backup user
use admin
db.createUser({
  user: "backup_user",
  pwd: passwordPrompt(),
  roles: [
    { role: "backup", db: "admin" }
  ]
})

Step 5: Enable Auditing

Auditing helps track database operations for security and compliance. Note that auditing is available in MongoDB Enterprise, but we can enable basic logging in Community Edition:

sudo nano /etc/mongod.conf

Add logging configuration:

systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
  logRotate: rename
  verbosity: 1
  component:
    accessControl:
      verbosity: 2
    command:
      verbosity: 1

Set up log rotation:

sudo nano /etc/logrotate.d/mongod
/var/log/mongodb/mongod.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    copytruncate
    notifempty
    create 0640 mongodb mongodb
    postrotate
        /bin/kill -SIGUSR1 $(cat /var/lib/mongodb/mongod.lock 2>/dev/null) 2>/dev/null || true
    endrotate
}

Advanced Security Configurations

MongoDB Configuration File Best Practices

Here’s a comprehensive, production-ready configuration file:

# /etc/mongod.conf
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 4
      journalCompressor: snappy
      directoryForIndexes: false
    collectionConfig:
      blockCompressor: snappy
    indexConfig:
      prefixCompression: true

systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
  logRotate: rename
  verbosity: 1
  component:
    accessControl:
      verbosity: 2

net:
  port: 27017
  bindIp: 127.0.0.1,10.0.1.100
  maxIncomingConnections: 65536
  tls:
    mode: requireTLS
    certificateKeyFile: /etc/ssl/mongodb.pem
    allowConnectionsWithoutCertificates: true

processManagement:
  timeZoneInfo: /usr/share/zoneinfo
  fork: true
  pidFilePath: /var/run/mongodb/mongod.pid

security:
  authorization: enabled
  clusterAuthMode: keyFile
  keyFile: /var/lib/mongodb/keyfile

operationProfiling:
  slowOpThresholdMs: 100
  mode: slowOp

replication:
  replSetName: "rs0"

setParameter:
  enableLocalhostAuthBypass: false
  authenticationMechanisms: SCRAM-SHA-1,SCRAM-SHA-256

Setting Up Replica Set Authentication

If you’re running a replica set, you’ll need to configure inter-node authentication:

# Generate a keyfile for replica set authentication
sudo openssl rand -base64 756 > /var/lib/mongodb/keyfile
sudo chmod 400 /var/lib/mongodb/keyfile
sudo chown mongodb:mongodb /var/lib/mongodb/keyfile

Security Monitoring and Maintenance

Regular Security Checks

Create a script to regularly check your MongoDB security status:

#!/bin/bash
# mongodb-security-check.sh

echo "=== MongoDB Security Status Check ==="
echo "Date: $(date)"
echo

# Check if authentication is enabled
echo "1. Authentication Status:"
mongosh --tls --host localhost:27017 -u admin -p --authenticationDatabase admin --quiet --eval "
  var config = db.runCommand('getCmdLineOpts');
  if (config.parsed && config.parsed.security && config.parsed.security.authorization === 'enabled') {
    print('✓ Authentication is ENABLED');
  } else {
    print('✗ Authentication is DISABLED - SECURITY RISK!');
  }
"

# Check SSL/TLS configuration
echo "2. SSL/TLS Status:"
if grep -q "mode: requireTLS" /etc/mongod.conf; then
    echo "✓ SSL/TLS is ENABLED"
else
    echo "✗ SSL/TLS is DISABLED - SECURITY RISK!"
fi

# Check bind IP configuration
echo "3. Network Binding:"
if grep -q "bindIp: 127.0.0.1" /etc/mongod.conf; then
    echo "✓ Restricted bind IP configuration"
else
    echo "⚠ Check bind IP configuration"
fi

# Check for default database
echo "4. Default Database Check:"
mongosh --tls --host localhost:27017 -u admin -p --authenticationDatabase admin --quiet --eval "
  if (db.getSiblingDB('test').stats().collections === 0) {
    print('✓ No default test database');
  } else {
    print('⚠ Default test database exists - consider removing');
  }
"

echo "=== End Security Check ==="

Performance Impact of Security Features

Security features do have performance implications. Here’s a comparison of typical performance impacts:

Security Feature Performance Impact CPU Overhead Network Overhead Recommended
Authentication Minimal (1-2%) Low None Always
SSL/TLS Moderate (5-10%) Medium Low Production
Auditing (Enterprise) High (10-20%) High None Compliance
Encryption at Rest Low (2-5%) Medium None Sensitive Data

Common Security Issues and Troubleshooting

Connection Issues After Enabling Security

The most common issues you’ll encounter after implementing security:

  • Authentication failures – Always specify the authentication database
  • SSL certificate errors – Ensure certificates are properly formatted and have correct permissions
  • Network connectivity issues – Check firewall rules and bind IP settings
  • Performance degradation – Monitor resource usage and optimize accordingly

Here are some debugging commands:

# Check MongoDB logs for authentication errors
sudo tail -f /var/log/mongodb/mongod.log | grep -i auth

# Test different authentication mechanisms
mongosh --authenticationMechanism SCRAM-SHA-256 -u admin -p --authenticationDatabase admin

# Verify SSL certificate
openssl x509 -in /etc/ssl/mongodb-cert.crt -text -noout

# Check network connections
sudo netstat -tlnp | grep :27017
sudo ss -tlnp | grep :27017

Emergency Access Recovery

If you get locked out of your MongoDB instance, you can temporarily disable authentication:

# Stop MongoDB
sudo systemctl stop mongod

# Comment out the security section in mongod.conf
sudo nano /etc/mongod.conf
# security:
#   authorization: enabled

# Start MongoDB without authentication
sudo systemctl start mongod

# Fix your user issues, then re-enable authentication
# Remember to restart MongoDB after re-enabling security

Real-World Use Cases and Best Practices

Multi-Environment Setup

In real-world scenarios, you’ll typically have different security requirements for different environments:

Environment Authentication SSL/TLS Auditing Network Access
Development Basic Optional Minimal Local/VPN
Staging Full RBAC Required Moderate Restricted
Production Full RBAC + MFA Required Full Highly Restricted

Integration with Application Security

Here’s an example of how to securely connect to MongoDB from a Node.js application:

// secure-mongodb-connection.js
const { MongoClient } = require('mongodb');

const connectOptions = {
  authSource: 'admin',
  authMechanism: 'SCRAM-SHA-256',
  ssl: true,
  sslValidate: true,
  sslCA: '/path/to/ca.pem', // CA certificate for production
  maxPoolSize: 10,
  serverSelectionTimeoutMS: 5000,
  socketTimeoutMS: 45000,
  connectTimeoutMS: 10000,
  maxIdleTimeMS: 30000
};

const uri = `mongodb://myapp_user:${process.env.MONGODB_PASSWORD}@localhost:27017/myapp`;

async function connectToDatabase() {
  try {
    const client = new MongoClient(uri, connectOptions);
    await client.connect();
    console.log('Connected to MongoDB securely');
    return client;
  } catch (error) {
    console.error('MongoDB connection error:', error);
    throw error;
  }
}

Additional Security Considerations

Operating System Level Security

MongoDB security doesn’t stop at the database level. Secure the underlying system:

# Create dedicated MongoDB user and group
sudo groupadd mongodb
sudo useradd -r -g mongodb -s /bin/false mongodb

# Secure MongoDB data directory
sudo chown -R mongodb:mongodb /var/lib/mongodb
sudo chmod 750 /var/lib/mongodb

# Secure log files
sudo chown -R mongodb:mongodb /var/log/mongodb
sudo chmod 750 /var/log/mongodb

# Set up system limits for MongoDB user
sudo nano /etc/security/limits.conf

Add these lines:

mongodb soft nofile 65536
mongodb hard nofile 65536
mongodb soft nproc 32768
mongodb hard nproc 32768

Backup Security

Don’t forget to secure your backups:

#!/bin/bash
# secure-mongodb-backup.sh

BACKUP_DIR="/secure/backups/mongodb"
DATE=$(date +%Y%m%d_%H%M%S)
GPG_RECIPIENT="your-gpg-key-id"

# Create backup
mongodump --host localhost:27017 --ssl --username backup_user --password "$BACKUP_PASSWORD" --authenticationDatabase admin --out "$BACKUP_DIR/dump_$DATE"

# Compress and encrypt
tar -czf "$BACKUP_DIR/mongodb_backup_$DATE.tar.gz" "$BACKUP_DIR/dump_$DATE"
gpg --encrypt --recipient "$GPG_RECIPIENT" "$BACKUP_DIR/mongodb_backup_$DATE.tar.gz"

# Clean up unencrypted files
rm -rf "$BACKUP_DIR/dump_$DATE"
rm "$BACKUP_DIR/mongodb_backup_$DATE.tar.gz"

# Keep only last 30 days of backups
find "$BACKUP_DIR" -name "*.gpg" -mtime +30 -delete

Securing MongoDB on Ubuntu 24 requires a comprehensive approach that covers authentication, network security, encryption, and ongoing monitoring. While the initial setup might seem complex, these security measures are essential for protecting your data in production environments. Remember to regularly review and update your security configurations, monitor logs for suspicious activities, and keep your MongoDB installation updated with the latest security patches. For more detailed information, refer to the official MongoDB security documentation and consider implementing additional enterprise features if your use case requires advanced compliance or auditing capabilities.



This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.

Leave a reply

Your email address will not be published. Required fields are marked