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"
)