Gestion de la sécurité dans MongoDB

  • Ahmed 

Introduction & contexte

MongoDB est un SGBD NoSQL open source écrit en C++ qui stocke ses données en BSON (Binary JSON). Son développement a commencé  en 2007 et a été initié par la société 10gen. Ce système est orienté documents, répartissables sur un nombre quelconque d’ordinateurs et ne nécessitant pas de schéma prédéfini des données.

En termes de marché, MongoDB est la base no SQL la plus utilisée et ce depuis plusieurs années. Elle est utilisée par des grands comptes comme eBay, Cisco, GAP, CERN, HSBC ou encore CitiGroup.

Le but de cet article n’est pas de décrire l’architecture de Mongo ou ses modèles de données. Ces sujets étant largement détaillés dans la littérature, nous allons nous intéresser à un sujet moins traité par la communauté, à savoir la gestion de la sécurité dans MongoDB.

En effet, lorsqu’on installe MongoDB, aucune sécurité n’est requise par défaut. N’importe quel utilisateur ayant accès à votre système peut lire, écrire ou détruire vos données.

Le sujet étant vaste, nous allons l’aborder en deux parties. Dans ce premier article, nous mettrons le focus sur les deux éléments essentiels et indispensables pour une sécurité minimale de vos bases de données à savoir :

  • L’Authentification: Qui doit garantir l’identité des « Users » se connectant,
  • L’Autorisation: Qui doit garantir un accès maîtrisé des « Users » authentifiés aux différentes ressources de MongoDB.

 

Dans un second temps, nous traiterons les deux éléments restants :

  • L’encryption du trafic réseau : Pour garantir la sécurité au niveau des flux entrants et sortants depuis et vers les bases MongoDB.
  • Authentification avec LDAP / Kerberos

 

Environnement technique

Voici l’environnement technique que nous avons déployé pour réaliser ce sujet :

  • OS : Linux Ubuntu 16.04
  • MongoDB server version : 4.0.0
  • Fichier de configuration par défaut de MongoDB : /etc/mongodb.conf
  • Port TCP par défaut : 27017

Prérequis

On suppose que le lecteur connait les concepts de base et le fonctionnement de MongoDB (Base de données, collection, document, …Etc).

Authentification vs Autorisation

Bien que l’authentification et l’autorisation soient étroitement liées, ces deux concepts sont distincts.

  • L’authentification est le processus de vérification de l’identité d’un utilisateur.
  • L’autorisation détermine l’accès de l’utilisateur aux ressources (Base de données, collections, serveurs) et aux opérations (lecture, écriture, suppression, …Etc).

Lorsque l’autorisation est activée, MongoDB exige que tous les clients s’authentifient pour déterminer leur accès.

L’Authentification

Pour authentifier un client, il faut ajouter un/des utilisateurs par client. Ce dernier pourra ainsi se connecter à une base de données MongoDB avec les identifiants d’accès de l’utilisateur approprié.

Créer un utilisateur

L’exemple ci-dessous indique comment créer l’utilisateur « reportsUser » dans la base de données « customers » avec son id, mot de passe et les rôles spécifiés (lecture seule).

 use customers
 db.createUser(
  {
   user: "reportsUser",
   pwd: "12345678",
   roles: [
    { role: "read", db: "customers" },
    { role: "read", db: "products" },
    { role: "read", db: "sales" },
    { role: "readWrite", db: "accounts" }
   ]
  }
 )

Notes importantes

  • La base de données où vous créez l’utilisateur (dans cet exemple, customers) est la base de données d’authentification de l’utilisateur.
  • Bien que l’utilisateur s’authentifie sur cette base, celui-ci peut avoir des rôles dans d’autres bases de données (products, sales, accounts).
    1. La base de données d’authentification de l’utilisateur ne limite pas les privilèges de celui-ci.

Se connecter en tant qu’utilisateur donné

Pour s’authentifier il faut indiquer le nom de cet  utilisateur, son mot de passe et la base de données d’authentification associée à cet utilisateur.

# mongo -u "reportsUser" -p "12345678" --authenticationDatabase "customers"

Note : Comme dit plus haut, les mécanismes d’authentification avec LDAP et Kerberos seront traités dans le prochain article.

 

L’Autorisation (Contrôle d’Accès)

 

Pour activer le contrôle d’accès proprement dit dans le fichier de config, il convient de suivre la procédure suivante :

  • Lancer une instance MongoDB sans authentification (sans user ni mot de passe spécifique),
  • Ajouter un utilisateur de type administrateur (qui doit avoir tous les droits sur toutes les bases de données)
  • Activer le contrôle d’accès
  • Ajouter, si vous le souhaitez, d’autres utilisateurs avec les privilèges souhaités.

Ci-dessous le détail de cette procédure :

Lancer une instance MongoDB sans authentification

Pour ce faire, il est possible d’utiliser la commande :

 # mongod 

ou la commande suivante, si vous vous connectez à un serveur MongoDB distant :

 # mongod --host adr_ip_seveur_mongodb --port port_mongodb 

Ajouter un utilisateur Admin

Dans la base de données admin, ajoutez un utilisateur avec le rôle userAdminAnyDatabase.

Le code ci-dessous indique la création de l’utilisateur AdminDba dans la base de données admin qui a des privilèges très large (role : userAdminAnyDatabase):

 
use admin 
switched to db admin
db.createUser(
 {
  user: "AdminDba",
  pwd: "mySecretPassword",
  roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
 }
)

Sortie shell :

 
 Successfully added user: {
  "user" : "AdminMDba",
  "roles" : [
    {
     "role" : "userAdminAnyDatabase",
     "db" : "admin"
   }
  ]
 }

Activer l’autorisation

Depuis le fichier mongod.conf, ajouter ou mettre à jour ces deux lignes :

 security:
   authorization: "enabled"

Créer d’autres utilisateurs et leurs privilèges

Décrit plus haut (voir Authentification).

Redémarrer MongoDB

Les utilisateurs pourront toujours se connecter à MongoDB sans s’authentifier, mais ils devront fournir un nom d’utilisateur et un mot de passe avant de pouvoir interagir avec les bases de données.

Pour se connecter à mongo, plusieurs façons sont possibles :

Façon 1 : Se connecter en s’authentifiant directement 

# mongo --host XX.XX.XX.XX --port PPPP -u "reportsUser" -p "12345678" --authenticationDatabase "customers"

Façon 2 :  Lancer mongo et se connecter en second temps

# mongo --host XX.XX.XX.XX --port PPPP 
use customers
db.auth("reportsUser", "12345678")

RBAC – Contrôle d’accès basé sur les rôles

Il est possible d’utiliser la notion de rôle pour décrire des autorisations spécifiques à certains utilisateurs. Dans l’exemple suivant, on va créer un utilisateur «userDev1 » avec un accès restreint en lecture seule à la collection « inventory ».  En revanche, on va lui donner des droits élargis sur la collection «orders ».

Pour ce faire, on va créer un rôle (que nous allons appeler «roleDev ») où l’on va matérialiser ces contraintes en utilisant la notion de resource.

db.createRole(
 {
  role: "roleDev",
  privileges: [
   {resource: {db: "sales", collection: "orders"}, actions: [ "find", "update", "insert", "remove" ] },
   {resource: {db: "sales", collection: "inventory"}, actions: [ "find" ] }
  ],
  roles: [{ role: "readWrite", db: "sales"}]
 }
);

Ensuite, on peut créer notre utilisateur en lui attribuant le rôle roleDev.

db.createUser(
 {
  user: "userdev1",
  pwd: "pwdev1",
  roles: [ { role: "roleDev", db: " sales " } ]
 }
)

 

Règles de sécurité de base à mettre en place

Pour éviter des attaques de sécurité faciles, il convient de rappeler certaines règles de base de la sécurité :

  • Utiliser un pare-feu : Utilisez un pare-feu pour limiter les autres entités autorisées à se connecter à votre serveur MongoDB. Dans cet exemple, seuls les serveurs 192.168.1.1, 192.168.1.2 et 192.168.1.3 sont autorisés à accéder à votre serveur de base de données MongoDB (192.168.1.1)
  • Limiter l’exposition au réseau:  Au travers de la partie « net » du fichier de configuration de MongoDB (/etc/mongo.conf), il est possible de protéger les instances Mongo en renseignant les paramètres suivants :
    • bindIP: binder MongoDB afin qu’elle ne puisse être accédée que sur votre VLAN.
    • port:  il convient de changer le port par défaut (27017).
    • Exemple: Admettons que nous ayons une application web installée sur un serveur « 192.168.1.1 » et devant accéder à un serveur MongoDB installé sur un autre serveur « 168.1.2 ». Nous pouvons par exemple modifier la partie « net » du fichier /etc/mongo.config comme ceci :
 # network interfaces
 net:
    port: 35269
    bindIp: 192.168.1.2

Conclusion

Dans cet article, nous avons montré comment configurer l’authentification, l’autorisation, limiter l’accès au réseau et mettre en place des pares-feux pour avoir un seuil de protection minimal pour vos serveurs de bases de données MongoDB.

Toutefois, ces mécanismes sont essentiels mais restent insuffisants. Dans le prochain article, nous ferons un focus sur les mécanismes adéquats pour maximiser la sécurité autour de MongoDB.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *