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

Rejoignez notre serveur communautaire Discord

Pour toute question, suggestion ou simplement pour discuter avec la communauté, rejoignez-nous sur Discord !

900+Membres