CVE Watch
Cybersécuritédevsecops4 min de lecture

Sécuriser son infrastructure Docker et Nginx en production

MB
Massioudath Bankole
13 mai 2026 · 33 vues

Introduction

Une application déployée en production est immédiatement exposée à internet. Sans mesures de sécurité, elle devient une cible pour les bots, les scanners automatiques et les attaquants. Dans cet article, on sécurise chaque couche de l'infrastructure : SSH, Nginx, MongoDB et les containers Docker.

Tout ce qui est décrit ici a été appliqué sur le serveur qui héberge ce blog.

1. Bloquer les attaques SSH avec Fail2ban

Dès qu'un serveur est en ligne, des bots tentent de se connecter en SSH par force brute. Des milliers de tentatives par jour avec des combinaisons d'identifiants courants.

Installation :

sudo apt install -y fail2ban

Configuration :

sudo nano /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5

[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log
maxretry = 3

Démarrage :

sudo systemctl start fail2ban
sudo systemctl enable fail2ban

Vérification :

sudo fail2ban-client status sshd

En quelques heures, Fail2ban bannit automatiquement les IPs malveillantes. Sur notre serveur, plusieurs IPs ont été bannies en moins d'une heure après l'installation.

2. Sécuriser MongoDB

Par défaut, MongoDB démarre sans authentification. N'importe qui ayant accès au serveur peut lire et modifier toutes les données.

Créer les utilisateurs :

docker exec -it mongodb mongosh
use admin
db.createUser({
  user: "mongoAdmin",
  pwd: "MotDePasseFort",
  roles: ["root"]
})

use mabase
db.createUser({
  user: "appUser",
  pwd: "AutreMotDePasse",
  roles: [{ role: "readWrite", db: "mabase" }]
})

Activer l'authentification en recréant le container avec deux changements importants :

docker run -d \
  --name mongodb \
  -p 127.0.0.1:27017:27017 \
  --restart always \
  -v /home/app/mongo-data:/data/db \
  mongo:7 --auth

-p 127.0.0.1:27017:27017 rend MongoDB accessible uniquement depuis le serveur lui-même. --auth rend l'authentification obligatoire pour toutes les connexions.

Mettre à jour l'URI de connexion dans le fichier .env de l'application :

MONGO_URI=mongodb://appUser:AutreMotDePasse@MONGO_IP:27017/mabase?authSource=mabase

3. Sauvegarder MongoDB automatiquement

Une base de données non sauvegardée est une base de données perdue.

Créer le script de sauvegarde :

sudo nano /home/app/backup-mongo.sh
#!/bin/bash
DATE=$(date +%Y-%m-%d_%H-%M)
BACKUP_DIR="/home/app/backups/mongodb"

docker exec mongodb mongodump \
  -u appUser -p AutreMotDePasse \
  --authenticationDatabase mabase \
  --db mabase \
  --out /tmp/backup-$DATE

docker cp mongodb:/tmp/backup-$DATE $BACKUP_DIR/

find $BACKUP_DIR -type d -mtime +7 -exec rm -rf {} +

echo "Sauvegarde terminée : $DATE"
sudo chmod +x /home/app/backup-mongo.sh

Automatiser avec cron, chaque nuit à 2h :

sudo crontab -e

0 2 * * * /home/app/backup-mongo.sh >> /var/log/backup-mongo.log 2>&1

4. Surveiller les containers Docker

Ce script vérifie toutes les 5 minutes que les containers tournent et les redémarre automatiquement si nécessaire.

sudo nano /home/app/monitor-containers.sh
#!/bin/bash
CONTAINERS=("mon-backend" "mon-frontend" "mongodb")

for container in "${CONTAINERS[@]}"; do
    if ! docker ps --format '{{.Names}}' | grep -q "^$container$"; then
        echo "Container $container arrete, redemarrage en cours..."
        docker start $container
    fi
done
sudo chmod +x /home/app/monitor-containers.sh

Ajouter au cron :

*/5 * * * * /home/app/monitor-containers.sh >> /var/log/monitor-containers.log 2>&1

5. Sécuriser Nginx

Masquer les informations techniques dans /etc/nginx/nginx.conf :

http {
    server_tokens off;
    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;
}

server_tokens off masque la version de Nginx dans les headers HTTP. Les directives limit_req_zone définissent des zones de rate limiting pour limiter le nombre de requêtes par IP.

Ajouter les headers de sécurité dans la configuration du site :

location / {
    limit_req zone=general burst=20 nodelay;
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    proxy_hide_header X-Powered-By;
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options DENY;
    add_header X-XSS-Protection "1; mode=block";
}

location /api/ {
    limit_req zone=api burst=10 nodelay;
    proxy_pass http://localhost:8000/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_hide_header X-Powered-By;
}

X-Content-Type-Options nosniff empêche le navigateur de deviner le type MIME d'une réponse. X-Frame-Options DENY empêche le clickjacking en interdisant l'intégration du site dans une iframe. X-XSS-Protection active la protection XSS du navigateur.

Bloquer les ports applicatifs depuis l'extérieur :

sudo iptables -A INPUT -p tcp --dport 3000 -j DROP
sudo iptables -A INPUT -p tcp --dport 8000 -j DROP
sudo apt install iptables-persistent
sudo netfilter-persistent save

6. Résumé

CoucheMesureEffet
SSHFail2banAttaques par force brute bloquées automatiquement
MongoDBAuthentification obligatoireBase de données inaccessible sans credentials
MongoDBAccès localhost uniquementPort 27017 non exposé sur internet
MongoDBSauvegarde automatique nocturneDonnées récupérables en cas de problème
DockerSurveillance automatiqueContainers redémarrés si ils tombent
NginxRate limitingProtection contre les attaques DDoS basiques
NginxHeaders de sécuritéProtection XSS, clickjacking, MIME sniffing
Nginxserver_tokens offVersion de Nginx masquée
PortsiptablesPorts 3000 et 8000 inaccessibles depuis internet

Conclusion

La sécurité n'est pas une étape qu'on fait une fois, c'est un processus continu. Ces mesures couvrent les bases pour un projet en production, mais il reste toujours plus à faire : audit régulier des logs, mise à jour des dépendances, tests de pénétration.

Le plus important est de commencer. Un serveur non sécurisé est une question de quand, pas de si.

devsecops
Partager cet article

Commentaires (0)

Sois le premier à commenter !

Articles similaires