MongoDB should never run in unauthenticated mode outside isolated development systems. Harden network, authentication, TLS, and backup handling from day one. This guide covers security measures for production MongoDB deployments.
In mongod.conf:
net:
bindIp: 127.0.0.1,10.0.10.15 # Only bind to specific IPs
port: 27017
# Disable IPv6 if not needed
ipv6: false
27017 publicly# Using ufw (Ubuntu)
sudo ufw allow from 10.0.10.0/24 to any port 27017
# Using iptables (RHEL/CentOS)
sudo iptables -A INPUT -s 10.0.10.0/24 -p tcp --dport 27017 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 27017 -j DROP
In mongod.conf:
security:
authorization: enabled
# For replica sets/sharding
# clusterAuthMode: keyFile # Or x509 for advanced setups
After enabling authorization:
// Connect without auth first to create the initial user
use admin
db.createUser({
user: "admin",
pwd: passwordPrompt(), // Prompts for password securely
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" },
{ role: "dbAdminAnyDatabase", db: "admin" },
{ role: "clusterAdmin", db: "admin" }
]
})
// For a specific application database
use application_db
db.createUser({
user: "app_user",
pwd: passwordPrompt(),
roles: [
{ role: "readWrite", db: "application_db" },
{ role: "dbAdmin", db: "application_db" }
]
})
// For read-only access
use reporting_db
db.createUser({
user: "report_user",
pwd: passwordPrompt(),
roles: [
{ role: "read", db: "reporting_db" }
]
})
# Create a private key
openssl genrsa -out mongodb.key 2048
# Create a certificate signing request
openssl req -new -key mongodb.key -out mongodb.csr
# Create a self-signed certificate (for testing only)
openssl x509 -req -in mongodb.csr -signkey mongodb.key -out mongodb.crt -days 365
# Combine key and cert
cat mongodb.key mongodb.crt > mongodb.pem
net:
ssl:
mode: requireSSL
PEMKeyFile: /etc/ssl/mongodb/mongodb.pem
# PEMKeyPassword: password # If key is encrypted
CAFile: /etc/ssl/mongodb/ca.pem
clusterFile: /etc/ssl/mongodb/mongodb.pem
# clusterPassword: password # If cluster key is encrypted
allowConnectionsWithoutCertificates: false
allowInvalidCertificates: false
allowInvalidHostnames: false
FIPSMode: false
# Using mongosh with TLS
mongosh --tls --tlsCertificateKeyFile /path/to/client.pem --tlsCAFile /path/to/ca.pem
# Using connection string
mongosh "mongodb://user:pass@host:27017/database?ssl=true&sslCertificateAuthorityFile=/path/to/ca.pem"
Create a keyfile:
# Generate a keyfile (contents should be identical across all replica set members)
openssl rand -base64 741 > /path/to/keyfile
chmod 600 /path/to/keyfile
chown mongod:mongod /path/to/keyfile
Configure in mongod.conf:
security:
keyFile: /path/to/keyfile
clusterAuthMode: keyFile
For production environments, consider using X.509 certificates for internal authentication:
security:
clusterAuthMode: x509
authorization: enabled
auditLog:
destination: file
format: JSON
path: /var/log/mongodb/auditLog.json
# Filter specific events (optional)
filter: '{ atype: { $in: [ "createUser", "dropUser", "authCheck", "authenticate", "delete", "insert", "update" ] } }'
Common audit filters:
# Log all authentication events
filter: '{ atype: { $in: [ "authenticate", "authCheck" ] } }'
# Log all user management events
filter: '{ atype: { $in: [ "createUser", "dropUser", "grantRole", "revokeRole" ] } }'
# Log all data modification events
filter: '{ atype: { $in: [ "insert", "update", "delete" ] } }'
security:
enableEncryption: true
encryptionKeyFile: /path/to/encryption/keys-file
# encryptionCipherMode: AES256-GCM # Default
# kmipKeyIdentifier: unique-id
# kmipServerName: kmip-server-name
# kmipPort: 5696
# kmipClientCertificateFile: /path/to/client.pem
# kmipClientCertificatePassword: password
# kmipServerCaFile: /path/to/ca.pem
setParameter:
# Disable javascript execution (if not needed)
javascriptEnabled: false
# Limit connection pool sizes
connPoolMaxShardedConnsPerHost: 200
connPoolMaxConnsPerHost: 100
# Disable localhost auth bypass after initial setup
enableLocalhostAuthBypass: false
operationProfiling:
mode: slowOp # Options: off, slowOp, all
slowOpThresholdMs: 100 # Log operations slower than this threshold
# Rate limit logging
rateLimit: 100
# Ensure MongoDB runs as 'mongod' user
# This is typically handled by the package manager
ps aux | grep mongod
# Secure data directory
sudo chown -R mongod:mongod /var/lib/mongo
sudo chmod 755 /var/lib/mongo
# Secure log directory
sudo chown -R mongod:mongod /var/log/mongodb
sudo chmod 755 /var/log/mongodb
# Secure configuration file
sudo chmod 600 /etc/mongod.conf
sudo chown root:mongod /etc/mongod.conf
If using SELinux:
# Check SELinux status
sestatus
# Set proper SELinux contexts
sudo setsebool -P mongod_can_network_connect 1
# Create encrypted backup
mongodump --uri="mongodb://user:pass@localhost:27017" --gzip --archive=backup.gz
gpg --symmetric --cipher-algo AES256 backup.gz
# For automated backups, use a key management solution
Never store credentials in plain text:
# Use environment variables
export MONGO_URI="mongodb://admin:password@localhost:27017"
# Or use MongoDB's credential file
mongodump --config /path/to/mongo-credentials-file
Content of /path/to/mongo-credentials-file:
username=user
password=password
authenticationDatabase=admin
Monitor for suspicious activities:
# Monitor authentication failures
grep "Authentication failed" /var/log/mongodb/mongod.log
# Monitor unauthorized access attempts
grep "Unauthorized" /var/log/mongodb/mongod.log
# Monitor for unexpected user creations
grep "createUser" /var/log/mongodb/auditLog.json
Consider implementing file integrity monitoring:
# Using aide (Advanced Intrusion Detection Environment)
sudo aide --init
sudo aide --check
# Regularly update MongoDB
sudo apt update && sudo apt install mongodb-org # Debian/Ubuntu
sudo dnf update mongodb-org # RHEL/CentOS
# Restart after updates
sudo systemctl restart mongod
Plan for regular certificate rotation:
# Script to rotate certificates (example)
#!/bin/bash
NEW_CERT_DATE=$(date -d "+30 days" '+%Y-%m-%d')
echo "Next certificate rotation due: $NEW_CERT_DATE"
# Test authentication
mongosh -u admin -p --authenticationDatabase admin --eval "db.runCommand({connectionStatus: 1})"
# Test network restrictions
# Try connecting from unauthorized IP addresses
# Test TLS (if configured)
mongosh --tls --tlsAllowInvalidCertificates --eval "db.runCommand({ping: 1})"
Regularly scan for vulnerabilities:
# Use vulnerability scanners like Nessus, OpenVAS, etc.
# Check MongoDB security advisories regularly