MongoDB : installation et securisation

MongoDB : installation et securisation

Deployer MongoDB en production : authentification, replica set, encryption, sauvegardes. La base NoSQL document-oriented la plus utilisee. Tres performante pour les charges flexibles, mais necessite une attention particuliere a la securite.

Introduction

MongoDB est une base NoSQL orientee documents JSON :

  • Schema flexible (chaque document peut differer)
  • Indexes secondaires, agregation pipeline
  • Replica sets pour la HA
  • Sharding pour le scaling horizontal
  • Drivers pour tous langages
  • Tres utilisee dans le monde Node.js (Mongoose)

⚠️ Par defaut, MongoDB ecoute sur toutes les interfaces sans auth. Les MongoDB Internet-facing non-securises sont une cible classique de ransomware. Toujours activer l'auth et le binding restreint.

Prerequis

  • VPS Linux Debian 12 / Ubuntu 24.04
  • 2 vCPU, 4 Go RAM
  • Acces root

Etape 1 : Installation

Ajouter le repo MongoDB 7 :

sudo apt update
sudo apt install -y gnupg curl
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg

echo "deb [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

sudo apt update
sudo apt install -y mongodb-org
sudo systemctl enable --now mongod

Verifiez :

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

Etape 2 : Securiser le binding

/etc/mongod.conf :

net:
  port: 27017
  bindIp: 127.0.0.1   # uniquement local par defaut

Si vous avez besoin d'acces depuis d'autres machines en LAN :

net:
  port: 27017
  bindIp: 127.0.0.1,10.0.0.5

⚠️ Jamais 0.0.0.0 sauf si firewall stricte devant.

Etape 3 : Activer l'authentification

Connectez-vous et creez un utilisateur admin :

mongosh
use admin

db.createUser({
  user: "admin",
  pwd: "pass-tres-fort",
  roles: [{ role: "userAdminAnyDatabase", db: "admin" },
          { role: "readWriteAnyDatabase", db: "admin" }]
})

exit

Activez l'auth dans /etc/mongod.conf :

security:
  authorization: enabled
sudo systemctl restart mongod

Maintenant :

mongosh -u admin -p --authenticationDatabase admin

Etape 4 : Creer un utilisateur applicatif

use monapp

db.createUser({
  user: "monapp_user",
  pwd: "pass-app-fort",
  roles: [{ role: "readWrite", db: "monapp" }]
})

L'utilisateur ne peut acceder qu'a la base monapp. Privilege minimum.

Etape 5 : Premiere insertion

use monapp

db.users.insertOne({
  name: "Alice",
  email: "[email protected]",
  age: 30,
  tags: ["dev", "admin"]
})

db.users.find({ age: { $gte: 25 } })

Etape 6 : Indexes

db.users.createIndex({ email: 1 }, { unique: true })
db.users.createIndex({ age: 1, name: 1 })

db.users.getIndexes()

Voir le plan d'execution :

db.users.find({ email: "[email protected]" }).explain("executionStats")

Recherchez stage: "IXSCAN" (index utilise) vs COLLSCAN (scan complet, lent).

Etape 7 : Replica Set pour la HA

Pour deployer un replica set 3 nodes :

Sur chaque node, /etc/mongod.conf :

replication:
  replSetName: rs0

net:
  bindIp: 127.0.0.1,10.0.0.X   # X = IP du node

security:
  authorization: enabled
  keyFile: /etc/mongodb-keyfile

Generer la keyFile (une seule, copiee sur les 3 nodes) :

openssl rand -base64 756 | sudo tee /etc/mongodb-keyfile
sudo chmod 400 /etc/mongodb-keyfile
sudo chown mongodb:mongodb /etc/mongodb-keyfile

Sur le node principal :

rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "10.0.0.1:27017" },
    { _id: 1, host: "10.0.0.2:27017" },
    { _id: 2, host: "10.0.0.3:27017" }
  ]
})

rs.status()

Le primary est elu automatiquement.

Etape 8 : Connection string applicative

Avec replica set, votre app se connecte ainsi :

mongodb://monapp_user:[email protected],10.0.0.2,10.0.0.3:27017/monapp?replicaSet=rs0&authSource=monapp

Le driver gere automatiquement le failover.

Etape 9 : Backup avec mongodump

mongodump --uri="mongodb://admin:[email protected]:27017" --out=/var/backups/mongo-$(date +%F)

Backup chiffre + compresse :

mongodump --uri="..." --archive | gzip > /var/backups/mongo-$(date +%F).archive.gz

Restore :

gunzip -c /var/backups/mongo-2026-05-17.archive.gz | mongorestore --uri="..." --archive

Etape 10 : Backup avance avec mongodump + S3

#!/bin/bash
DATE=$(date +%F)
mongodump --uri="..." --archive | gzip | aws s3 cp - s3://mes-backups/mongo-$DATE.archive.gz

Cronnez :

0 2 * * * /root/backup-mongo.sh

Etape 11 : Monitoring

mongosh --eval "db.serverStatus()"
mongosh --eval "db.stats()"

En CLI live :

mongostat --uri="..."
mongotop --uri="..."

Pour Prometheus, utilisez mongodb_exporter :

docker run -d -p 9216:9216 percona/mongodb_exporter:0.40 \
    --mongodb.uri=mongodb://admin:pass@host:27017

Etape 12 : Optimisation perf

WiredTiger cache

/etc/mongod.conf :

storage:
  wiredTiger:
    engineConfig:
      cacheSizeGB: 2     # 50% RAM disponible

Profiler les requetes lentes

db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ ts: -1 }).limit(10)

Ne pas faire de $where

$where desactive les indexes. Utilisez l'agregation pipeline a la place.

Depannage

"Authentication failed"

Verifiez authSource dans la connection string. Si l'user est cree dans admin, utilisez authSource=admin. Si cree dans monapp, authSource=monapp.

"exceeded connection limit"

db.serverStatus().connections

Augmentez net.maxIncomingConnections ou reduisez les connexions cote app (pool).

Replica set : "not master"

Vous etes sur un secondary. Pour lire dessus :

rs.secondaryOk()
db.users.find()

Pour ecrire, connectez-vous au primary.

Disk full

Verifiez :

sudo du -sh /var/lib/mongodb

Compactez :

db.runCommand({ compact: "users" })

Ou supprimez les vieux logs MongoDB :

sudo journalctl --vacuum-time=7d

Commandes utiles

# Service
sudo systemctl status mongod
sudo systemctl restart mongod
sudo tail -f /var/log/mongodb/mongod.log

# Stats temps reel
mongostat --uri="..."
mongotop --uri="..."

# Shell
mongosh -u admin -p --authenticationDatabase admin

# Backup
mongodump --uri="..." --archive | gzip > backup.archive.gz
mongorestore --uri="..." --archive < backup.archive

# Replica set
mongosh --eval "rs.status()"
mongosh --eval "rs.stepDown()"   # forcer changement primary

# Profiling
mongosh --eval "db.setProfilingLevel(1, { slowms: 100 })"

Conclusion

MongoDB est puissant pour les charges flexibles :

  • Schema dynamique
  • Scaling horizontal (sharding)
  • HA via replica sets
  • Aggregation framework riche

Limites :

  • Transactions ACID moins matures que SQL
  • Consommation memoire elevee
  • Joins limites (vs SQL)

Pour aller plus loin :

  • Configurez le sharding pour les bases > 1 TB
  • Explorez MongoDB Atlas (service managed)
  • Pour de l'analytics, considerez MongoDB Charts ou exportez vers BigQuery

Ressources

Join our Discord community server

For any questions, suggestions, or just to chat with the community, join us on Discord!

900+Members