Durcissement de la sécurité : MongoDB / Redis / Elasticsearch
Symptôme
Objectif : durcir les magasins NoSQL/de données selon les recommandations CIS : authentification, restriction réseau, blocage des commandes dangereuses, TLS, rôles à moindre privilège et audit.
1. ACTIVEZ l'authentification : coupez tout accès non authentifié
Ces produits sont souvent livrés avec l'authentification DÉSACTIVÉE par défaut et sont compromis lorsqu'ils restent exposés sur Internet. Activez l'authentification et créez un utilisateur administrateur.
MongoDB
// mongod.conf:
security:
authorization: enabled
// Create an administrator user (first time, via the localhost exception):
use admin
db.createUser({ user: "admin", pwd: passwordPrompt(),
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] })
// Then connect with: mongosh -u admin --authenticationDatabase adminRedis
# redis.conf — ACL (Redis 6+): disable the default user, define named users:
user default off
user admin on >AdminPassword789! ~* &* +@all
user app on >AppPassword456! ~app:* +@read +@write
# Note: requirepass is a legacy compatibility setting that only sets the 'default' user's password;
# do not confuse it with ACL users. You can also keep users in an aclfile (persisted with ACL SAVE).Elasticsearch
# 8.x: security (authentication + TLS) is configured automatically on first start; elasticsearch.yml:
xpack.security.enabled: true
# Set/reset the password of the 'elastic' user:
bin/elasticsearch-reset-password -u elastic
# (elasticsearch-setup-passwords is deprecated since 8.0)
# Create separate users with dedicated roles for Kibana/clients instead of 'elastic'.2. Restreignez le réseau : n'ouvrez que les interfaces et ports nécessaires
Évitez que le service écoute le monde entier sur 0.0.0.0. Fixez l'adresse de liaison sur une interface interne/le loopback et activez le protected mode.
MongoDB
# mongod.conf — internal interface + loopback only:
net:
bindIp: 127.0.0.1,10.0.0.10
port: 27017
# Never use bindIpAll: true; limit the port with a firewall.Redis
# redis.conf:
bind 127.0.0.1 10.0.0.10
protected-mode yes
port 6379
# protected-mode blocks external access when no password is set;
# still limit 6379 with a firewall.Elasticsearch
# elasticsearch.yml — pin the listening interface:
network.host: 10.0.0.10
http.port: 9200
transport.port: 9300
# Open only the required ports in the firewall;
# 9300 (transport) must never be exposed externally.3. Restreignez les commandes dangereuses
Une seule commande peut effacer toutes les données. Renommez ou supprimez les commandes destructrices/d'administration, ou bloquez le ciblage par joker.
MongoDB
// Use role-based control instead of a separate command block:
// Grant destructive privileges (dropDatabase, dropCollection) only to
// dbAdmin/clusterAdmin roles; do not grant them to the application user.
db.grantRolesToUser("app", [ { role: "readWrite", db: "appdb" } ])
// Do NOT grant dbAdmin/root to the application user.Redis
# For Redis 6+ the preferred way is ACLs (do not give the application user dangerous commands):
# ACL SETUSER app ... -@dangerous
# Legacy method — disable/rename commands in redis.conf:
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command KEYS ""
rename-command DEBUG ""
# Caution: renaming CONFIG can break Sentinel, CONFIG REWRITE and management tools.Elasticsearch
# elasticsearch.yml — block wildcard/all-index deletion:
action.destructive_requires_name: true
# This rejects DELETE /* or DELETE /_all;
# bulk deletion is not possible without naming the index explicitly.4. Activez TLS/les connexions chiffrées
Les identifiants et les données ne doivent pas circuler en clair sur un réseau ouvert. Activez TLS pour le trafic client et entre nœuds.
MongoDB
# mongod.conf — client TLS:
net:
tls:
mode: requireTLS
certificateKeyFile: /etc/ssl/mongodb.pem
CAFile: /etc/ssl/ca.pem
# Client: mongosh --tls --tlsCAFile ca.pemRedis
# redis.conf — enable TLS, close the plain port:
port 0
tls-port 6379
tls-cert-file /etc/redis/redis.crt
tls-key-file /etc/redis/redis.key
tls-ca-cert-file /etc/redis/ca.crtElasticsearch
# elasticsearch.yml — HTTP and transport TLS:
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: http.p12
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: transport.p125. Accordez des rôles à moindre privilège : évitez les rôles étendus
Donnez à chaque utilisateur uniquement l'accès requis par sa fonction. Au lieu de rôles étendus/d'administration, utilisez des rôles fins limités à des bases, des motifs de clés ou des index précis.
MongoDB
// Instead of broad readWrite, grant only on the required DB;
// define a custom role if needed:
db.createRole({ role: "ordersRW",
privileges: [ { resource: { db: "appdb", collection: "orders" },
actions: [ "find", "insert", "update" ] } ], roles: [] })
db.grantRolesToUser("app", [ { role: "ordersRW", db: "appdb" } ])Redis
# Limit by key pattern and command category with ACLs:
ACL SETUSER app on >AppPassword456! ~app:* +@read +@write -@dangerous
# Only keys with the 'app:' prefix, read/write; dangerous commands forbidden.
ACL LIST
ACL WHOAMIElasticsearch
# Define a fine-grained role (read-only on specific indices):
POST /_security/role/orders_read
{ "indices": [ { "names": [ "orders-*" ],
"privileges": [ "read" ] } ] }
# Assign it to the user:
POST /_security/user/app
{ "password": "...", "roles": [ "orders_read" ] }6. Activez l'audit/la journalisation : surveillez les accès et les modifications
Les tentatives d'accès non autorisées et les opérations d'administration doivent être enregistrées. Activez le journal d'audit et envoyez-le vers un emplacement central.
MongoDB
# Auditing (requires MongoDB Enterprise) — mongod.conf:
auditLog:
destination: file
format: JSON
path: /var/log/mongodb/audit.json
# Filter: capture events such as authenticate, createUser, dropDatabase.Redis
# Redis has no full audit; use ACL LOG to see rejected
# authentication/command attempts:
ACL LOG
ACL LOG RESET
# Also: route the loglevel notice and logfile settings to a central collector.Elasticsearch
# elasticsearch.yml — enable security auditing:
xpack.security.audit.enabled: true
xpack.security.audit.logfile.events.include:
[ authentication_failed, access_denied, connection_denied ]
# Records are written to the <cluster>_audit.json file.