Comment exécuter un serveur MongoDB sécurisé avec OpenVPN et Docker sur Ubuntu 16.04

http://mongodb.org [MongoDB] est une base de données NoSQL à source ouverte. Une configuration MongoDB traditionnelle manque de certaines fonctionnalités de sécurité que vous souhaiteriez si vous êtes préoccupé par la sécurité des données.

Il existe plusieurs méthodes pour sécuriser le serveur qui exécute la base de données. Tout d’abord, vous pouvez configurer un VPN et limiter l’accès aux seuls clients connectés au VPN. Ensuite, vous pouvez chiffrer la couche de transport entre le client et le serveur avec des certificats. Vous ferez les deux dans ce tutoriel. De plus, vous utiliserez Docker pour exécuter votre instance MongoDB afin de garantir la réutilisation de votre configuration MongoDB et de vos certificats sur plusieurs serveurs.

Conditions préalables

Pour compléter ce tutoriel, vous avez besoin de:

  • Un serveur OpenVPN, que vous pouvez configurer en suivant le tutoriel How Configurer un serveur OpenVPN sur Ubuntu 16.04. Assurez-vous de cocher la case * Réseaux privés * lors de la création du serveur.

  • Une machine Ubuntu 16.04 avec Docker installé. C’est là que vous créerez votre image MongoDB Docker et que vous exécuterez MongoDB dans un conteneur. Pour le créer, cliquez sur * Créer un droplet * dans la console de gestion DigitalOcean, choisissez * Applications en un clic *, puis sélectionnez * Docker 1.x le 16.04 *. Activez également la mise en réseau privée sur ce serveur.

  • Un utilisateur non root avec des privilèges sudo sur les deux serveurs. Le Initial Initial Setup Guide for Ubuntu 16.04 explique comment le configurer.

  • MongoDB installé sur votre ordinateur local. Vous allez l’utiliser pour tester votre connexion à votre serveur MongoDB.

Étape 1 - Configuration du VPN pour le transfert d’adresses IP privées

Si vous avez suivi l’article prérequis OpenVPN, vous avez probablement configuré votre serveur pour qu’il transfère les demandes à l’interface réseau publique, mais pas à l’interface privée. Dans ce didacticiel, nous allons configurer le serveur MongoDB pour qu’il ne soit accessible que sur son interface privée, à laquelle nous ne pourrons accéder que via notre connexion VPN. Nous devons modifier les règles de transmission IP sur le serveur VPN afin que le trafic des clients VPN soit également acheminé vers le réseau privé.

Connectez-vous à votre serveur OpenVPN.

ssh @

Accédez ensuite au tableau de bord DigitalOcean, sélectionnez votre droplet VPN et recherchez son adresse IP privée.

Une fois que vous avez l’adresse IP privée, exécutez cette commande sur votre droplet VPN pour identifier l’interface réseau qui utilise cette adresse IP:

sudo nano /etc/ufw/before.rules
ip route | grep

Vous devriez voir une sortie similaire à celle-ci:

Output10.132.0.0/16 dev   proto kernel  scope link  src

Prenez note de l’interface réseau dans votre sortie. Dans cet exemple, l’interface est + eth1 +, mais la vôtre peut être différente.

Une fois que vous avez identifié l’interface réseau privée, éditez le fichier + / etc / ufw / before.rules:

sudo nano /etc/ufw/before.rules

Recherchez la section que vous avez définie dans le didacticiel relatif aux prérequis, qui ressemble à ceci:

/etc/ufw/before.rules

# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES

Ajoutez une nouvelle règle pour l’interface de réseau privé:

/etc/ufw/before.rules

# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE

COMMIT
# END OPENVPN RULES

Assurez-vous de substituer + eth1 + avec l’interface de votre réseau privé. Enregistrez ensuite le fichier et quittez l’éditeur.

Désactiver et réactiver le pare-feu:

sudo ufw disable
sudo ufw enable

Puis déconnectez-vous de votre serveur VPN.

exit

Etablissez maintenant une connexion VPN de votre ordinateur local à votre serveur VPN. Maintenez cette connexion tout au long de ce tutoriel.

Connectons maintenant le serveur MongoDB en utilisant son adresse IP privée et configurons son pare-feu.

Étape 2 - Configuration du pare-feu du serveur MongoDB

Nous allons nous connecter au serveur MongoDB en utilisant son adresse IP privée. Si vous ne l’avez pas, retournez au tableau de bord DigitalOcean et recherchez l’adresse IP privée du droplet MongoDB Docker. Vous l’utiliserez ici pour vous connecter au serveur, puis pour vous connecter directement à MongoDB, car nous sommes sur le point de limiter l’accès au serveur de base de données aux clients VPN. De cette façon, vous évitez d’exposer la base de données publiquement, ce qui est une mesure de sécurité indispensable.

Assurez-vous d’être connecté à votre VPN et SSH au serveur MongoDB à l’aide de son adresse IP privée:

ssh @

Une fois connecté, supprimez toutes les règles de pare-feu existantes pour empêcher tout accès depuis le monde extérieur:

sudo ufw delete limit ssh
sudo ufw delete allow 2375/tcp
sudo ufw delete allow 2376/tcp

Ajoutez ensuite deux nouvelles règles autorisant l’accès SSH et MongoDB uniquement à partir d’ordinateurs connectés à votre VPN. Pour ce faire, utilisez l’adresse IP privée de votre serveur VPN pour l’adresse IP d’origine:

sudo ufw allow from  to any port 22 proto tcp
sudo ufw allow from  to any port 28018 proto tcp

Assurez-vous que ce sont les deux seules règles configurées:

sudo ufw status

Vous devriez voir la sortie suivante:

OutputTo                         Action      From
--                         ------      ----
22/tcp                     ALLOW
28018/tcp                  ALLOW

Activez le pare-feu et déconnectez-vous du serveur:

sudo ufw enable
exit

Reconnectez-vous ensuite au serveur MongoDB pour vous assurer que vous avez toujours accès au serveur après avoir activé le filtre IP.

ssh @

Si vous ne parvenez pas à établir une connexion SSH, assurez-vous que vous êtes connecté au VPN et que vous avez configuré le serveur VPN pour transférer le trafic sur le réseau privé. Si cela ne fonctionne pas, connectez-vous à l’aide de la console DigitalOcean et cochez les règles du pare-feu. Assurez-vous d’avoir spécifié l’adresse IP privée de votre serveur VPN dans les règles et non l’adresse IP privée de votre serveur MongoDB.

Pour en savoir plus sur UFW, explorez this tutoriel DigitalOcean UFW .

Maintenant que vous avez configuré les mesures de sécurité de base, passez à la configuration de MongoDB.

Étape 3 - Création du fichier de configuration MongoDB

Dans cette étape, nous allons créer une configuration MongoDB personnalisée qui configurera MongoDB pour l’utilisation de certificats SSL.

Créons une structure de répertoires pour notre configuration et les fichiers associés. Nous allons créer un répertoire nommé + mongoconf +, puis créer un répertoire + config + à l’intérieur de celui-ci pour nos fichiers de configuration. Dans le répertoire + config, nous allons créer un répertoire appelé` + ssls`, où nous allons stocker les certificats.

Créez la structure avec la commande suivante:

mkdir -p ~/mongoconf/config/ssl

Puis passez dans le dossier + ~ / mongod conf / config:

cd ~/mongoconf/config

Ouvrez un nouveau fichier nommé + mongod.conf + avec votre éditeur de texte:

nano mongod.conf

Commencez par configurer la base de données pour qu’elle se connecte à chaque interface réseau sur le port + 28018 +. La liaison à «+ 0.0.0.0 +» n’est pas un problème de sécurité dans ce cas, car le pare-feu n’autorisera de toute façon pas les connexions du monde extérieur. Mais nous devons autoriser la connexion des clients à l’intérieur du VPN. Ajoutez ce qui suit au fichier:

mongodb.conf

net:
 bindIp: 0.0.0.0
 port: 28018

Également dans la section + net +, définissez les chemins d’accès aux certificats SSL et spécifiez la phrase de passe du certificat. Nous allons créer les fichiers de certificat et la phrase secrète sous peu.

mongodb.conf

net:
. . .
 ssl:
   CAFile: /etc/mongo/ssl/client.pem
   PEMKeyFile: /etc/mongo/ssl/server.pem
   PEMKeyPassword: test
   mode: requireSSL

Enfin, définissez le répertoire de stockage par défaut et activez la journalisation.

mongodb.conf

. . .
storage:
 dbPath: /mongo/db
 journal:
   enabled: true

Pour en savoir plus sur toutes les options de configuration disponibles, consultez read la documentation de MongoDB.

Pour l’instant, enregistrez le fichier et quittez l’éditeur. Il est temps de générer les certificats SSL que nous utiliserons.

Étape 4 - Génération de certificats SSL

Pour sécuriser le transport des données, vous devez générer deux certificats SSL pour MongoDB: un pour le serveur et un pour le client qui accédera à la base de données.

Commencez par accéder au répertoire + ~ / mongoconf / config / ssl + et générez la paire certificat-clé du serveur. Remplissez les invites avec les informations de votre choix. Faites attention aux champs + Common Name et` + PEM Pass Phrase`.

cd ~/mongoconf/config/ssl
openssl req -new -x509 -days 365 -out server.crt -keyout server.key

Vous verrez le résultat suivant et il vous sera demandé de fournir des détails tout au long du processus:

Server certificate-key generation. . .
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
. . .
Common Name (e.g. server FQDN or YOUR name) []:
. . .

Lorsque la phrase de passe PEM vous est demandée, assurez-vous d’utiliser la même valeur que celle utilisée dans votre fichier de configuration MongoDB à l’étape précédente.

MongoDB n’accepte pas les fichiers de clé et de certificat séparés, combinez-les dans un seul fichier + .pem +:

cat server.crt server.key >>

Ensuite, générez la paire certificat-clé pour le client:

openssl req -new -x509 -days 365 -out client.crt -keyout

Vous suivrez le même processus qu’auparavant, mais cette fois-ci, utilisez l’adresse IP privée du serveur VPN. La phrase de passe PEM peut être celle que vous souhaitiez pour cette étape.

Client certificate-key generation. . .
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
. . .
Common Name (e.g. server FQDN or YOUR name) []:
. . .

Concaténez les fichiers que vous venez de générer dans un seul fichier + .pem +:

cat client.crt client.key >> client.pem

Ensuite, copiez les deux fichiers de certificat sur votre ordinateur local afin que vous puissiez vous connecter au serveur MongoDB à distance. Vous pouvez le faire avec la commande + scp + sur votre machine locale:

scp @:/home//mongoconf/config/ssl/\{client.pem,server.pem\} .

Vous pouvez également suivre le didacticiel Comment utiliser SFTP pour Transférer des fichiers de manière sécurisée avec un serveur distant pour transférer les fichiers + client.pem + et + server.pem + sur votre ordinateur local.

Créons maintenant l’image Docker et exécutons le moteur de base de données dans un conteneur afin que cette configuration soit plus portable.

Étape 5 - Création de l’image MongoDB Docker et exécution du conteneur

Vous avez créé une configuration MongoDB sécurisée et généré des certificats. Maintenant, faisons-le portable avec Docker. Nous allons créer une image personnalisée pour MongoDB, mais nous transmettrons notre fichier de configuration et nos certificats lorsque nous exécutons le conteneur.

Pour construire une image, vous avez besoin d’un fichier Docker.

Basculez vers le répertoire racine du projet et ouvrez un fichier Dockerfile vide dans votre éditeur:

cd ~/mongoconf
nano Dockerfile

Ajoutez les éléments suivants au nouveau fichier:

Dockerfile

FROM ubuntu:xenial

RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
RUN echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-3.4.list
RUN apt-get update && apt-get install -y mongodb-org
RUN mkdir -p /mongo/db /etc/mongo

EXPOSE 28018
ENTRYPOINT ["mongod", "--config", "/etc/mongo/mongod.conf"]

Ce fichier indique à Docker de créer une image basée sur Ubuntu 16.04 Xenial, de télécharger les derniers fichiers binaires MongoDB et de créer quelques répertoires dans lesquels nous allons stocker les fichiers de configuration et la base de données. Il met le port + 28018 + du conteneur à la disposition de l’hôte et exécute Mongo à chaque fois que l’utilisateur redémarre le conteneur.

Enregistrez le fichier et quittez votre éditeur. Puis construisez l’image:

docker build -t mongo .

Une fois l’image générée, exécutez un conteneur basé sur l’image. Nous allons monter le répertoire + config + en tant que volume à l’intérieur du conteneur afin que notre configuration personnalisée et nos clés soient visibles pour l’instance MongoDB à l’intérieur du conteneur:

docker run \
--detach \
--publish 28018:28018 \
--volume $PWD/config:/etc/mongo \
--name mongodb \
mongo

Maintenant que vous avez une instance MongoDB en cours d’exécution, accédez-y à partir de votre ordinateur local.

Étape 6 - Accéder à MongoDB

Dans un nouveau terminal sur votre ordinateur local, connectez-vous à la base de données à l’aide de l’adresse IP privée du serveur MongoDB. Vous allez fournir les fichiers client.pem et server.pem que vous avez téléchargés sur votre ordinateur local, ainsi que la phrase secrète que vous avez utilisée lors de la création du certificat client. Exécutez cette commande:

mongo \
--ssl \
--sslCAFile  \
--sslPEMKeyFile  \
--sslPEMKeyPassword  \
--host  \
--port 28018

Si tout va bien, vous devriez voir l’invite MongoDB.

Si une erreur apparaît, vérifiez que vous vous connectez à l’adresse IP privée du serveur MongoDB et non à l’adresse IP du serveur VPN. Vérifiez également que l’emplacement de la clé et la phrase secrète sont corrects et que votre connexion au VPN est toujours en cours d’exécution.

Conclusion

Vous avez maintenant une MongoDB personnalisée configurée qui s’exécute dans un conteneur Docker. Sa sécurité est assurée par l’authentification SSL client-serveur et le cryptage de transport. Vous avez ajouté une sécurité supplémentaire en configurant le pare-feu pour limiter les connexions de base de données aux clients connectés à un serveur VPN.

Bien que cette configuration soit optimale pour les tests, n’oubliez pas que dans un environnement de production, vous devez utiliser une autorité de certification approuvée et des certificats signés. De plus, vous devez analyser vos besoins en matière de sécurité et agir en conséquence. Par exemple, vous pouvez définir des utilisateurs, des mots de passe et des rôles dans la base de données. Le tutoriel Comment installer et sécuriser MongoDB sur Ubuntu 16.04 contient plus d’informations sur la création d’utilisateurs et constitue un excellent pas en avant vers une configuration prête pour la production.