Compte tenu de la popularité de notre article sur la connexion SSL MongoDB avec des certificats auto-signés dans Node.js, nous avons décidé d'écrire un tutoriel sur la connexion MongoDB avec Ruby. Dans ce blog, nous allons vous montrer comment vous connecter à un serveur MongoDB configuré avec des certificats auto-signés pour SSL en utilisant à la fois le pilote Ruby MongoDB et le populaire mongoid Object-Document-Mapper (ODM).
ScaleGrid utilise actuellement des certificats auto-signés pour SSL lors de la création de nœuds pour un nouveau cluster. De plus, nous vous offrons également la possibilité d'acheter vos propres certificats SSL et de les configurer sur le serveur MongoDB, et vous pouvez envoyer un e-mail à [email protected] pour en savoir plus sur cette offre.
Connexion à un jeu de répliques à l'aide du pilote Ruby MongoDB
Nous utiliserons la dernière version 2.8 du pilote Ruby MongoDB stable pour cet exemple. Les versions 2.5.x du pilote ont un bogue connu qui les empêche de travailler avec les déploiements ScaleGrid. La version de Ruby utilisée dans les deux exemples ci-dessous est 2.6.3.
Les options de connexion disponibles pour le pilote sont documentées ici, et les options dont nous aurons besoin sont :
- :ssl
- :ssl_verify
- :ssl_ca_cert .
Tout d'abord, recherchez et copiez votre chaîne de connexion MongoDB à partir de la page des détails du cluster sur la console ScaleGrid :
Le fichier de certificat CA est également disponible en téléchargement à partir de la page des détails du cluster. Téléchargez et stockez le fichier de certificat à un emplacement accessible à l'application :
Voici un extrait montrant comment se connecter à un jeu de répliques MongoDB à partir de Ruby :
require 'mongo'Mongo::Logger.logger.level =::Logger::DEBUGMONGODB_CA_CERT ="/path/to/ca_cert.pem"MONGODB_CONN_URL ="mongodb://testuser:@SG-example- 17026.servers.mongodirector.com:27017,SG-example-17027.servers.mongodirector.com:27017,SG-example-17028.servers.mongodirector.com:27017/test?replicaSet=RS-example-0&ssl=true" options ={ ssl:true, ssl_verify:true, :ssl_ca_cert => MONGODB_CA_CERT }client =Mongo::Client.new(MONGODB_CONN_URL, options)db =client.databasecollections =db.collection_namesputs "db #{db.name} a des collections # {collections}"client.close
Pour garder l'exemple simple, nous avons spécifié la chaîne de connexion et le chemin du fichier cert directement dans l'extrait de code - vous les placeriez généralement dans un fichier yaml ou les spécifieriez comme Variables d'environnement. En outre, l'exemple définit le niveau de journalisation sur DEBUG
afin que tous les problèmes de connectivité puissent être débogués. Il devrait être remplacé par un niveau moins détaillé une fois les problèmes de connectivité résolus.
Comment connecter MongoDB à une application Ruby avec SSLCliquez pour tweeter
Connexion à l'aide de Mongoid
La version mongoid que nous utiliserons dans notre exemple est la dernière version stable - 7.0.2. Nous utiliserons un fichier yaml pour fournir la configuration à mongoid, et les détails d'un tel fichier de configuration sont documentés ici. Les options de configuration spécifiques à SSL dont nous aurons besoin pour nous connecter à notre jeu de répliques sont :
- ssl
- ssl_verify
- ssl_ca_cert
Notre fichier yml :
development :# Configurer les clients de base de données disponibles. (requis) clients :# Définissez le client par défaut. (obligatoire) par défaut :# Un uri peut être défini pour un client :# uri :'mongodb://user:[email protected]:27017/my_db' # Veuillez consulter la documentation du pilote pour plus de détails. Alternativement, vous pouvez définir ce qui suit :# # Définissez le nom de la base de données par défaut à laquelle Mongoid peut se connecter. # (obligatoire). database:test # Indiquez les hôtes auxquels le client par défaut peut se connecter. Doit être un tableau # de paires hôte:port. (obligatoire) hôtes :- SG-example-17026.servers.mongodirector.com:27017 - SG-example-17027.servers.mongodirector.com:27017 - SG-example-17028.servers.mongodirector.com:47100 options :# Le nom de l'utilisateur pour l'authentification. utilisateur :'testuser' # Le mot de passe de l'utilisateur pour l'authentification. mot de passe :'pwd' # Les rôles de base de données de l'utilisateur. rôles :- 'readWrite' # Change le mécanisme d'authentification par défaut. Les options valides sont ::scram, # :mongodb_cr, :mongodb_x509 et :plain. (la valeur par défaut sur 3.0 est :scram, # la valeur par défaut sur 2.4 et 2.6 est :plain) auth_mech::scram # La base de données ou la source par rapport à laquelle authentifier l'utilisateur. (par défaut :admin) auth_source :test # Force le pilote à se connecter d'une manière spécifique au lieu de la # découverte automatique. Il peut s'agir de ::direct, :replica_set, :sharded. Définissez sur :direct # lors de la connexion à des membres masqués d'un jeu de réplicas. connect::replica_set ... ... # Le nom du jeu de répliques auquel se connecter. Les serveurs fournis en tant que graines # qui n'appartiennent pas à cet ensemble de répliques seront ignorés. plica_set :RS-example-0 # S'il faut se connecter aux serveurs via ssl. (par défaut :faux) ssl :vrai # S'il faut ou non faire la validation de la certification par les pairs. (par défaut :vrai) ssl_verify :vrai # Fichier contenant un ensemble de certifications d'autorité de certification concaténées # utilisé pour valider les certificats transmis depuis l'autre extrémité de la connexion. ssl_ca_cert :/chemin/vers/ca_cert.pem # Configurez les options spécifiques à Mongoid. (facultatif) options :# Définissez les niveaux de journalisation des pilotes Mongoid et Ruby. (par défaut ::info) log_level ::debug
Exemple de connexion :
gem 'mongoid', '7.0.2'require 'mongoid'Mongoid.load!("/path/to/mongoid.yml", :development)# N'utilisant aucune des fonctionnalités ODM - récupérez simplement le mongo sous-jacent client et tentative de connexionclient =Mongoid::Clients.defaultdb =client.databasecollections =db.collection_namesputs "db #{db.name} has collections #{collections}"Mongoid::Clients.disconnect
Encore une fois, dans les applications Ruby on Rails de production, le chemin du fichier yaml serait récupéré à partir des variables d'environnement.
Test du comportement de basculement
Comme les autres pilotes MongoDB, le pilote Ruby MongoDB est également conçu pour reconnaître en interne les changements de topologie dus à des événements tels que le basculement. Cependant, il est bon de tester et de valider le comportement du driver lors des basculements pour éviter les surprises en production.
Comme mon article précédent sur MongoDB PyMongo, nous pouvons écrire un programme de test d'écriture perpétuel pour observer le comportement de basculement du pilote.
Le moyen le plus simple d'induire un basculement consiste à exécuter la commande rs.stepDown() :
RS-example-0:PRIMARY> rs.stepDown()2019-04-18T19:44:42.257+0530 E QUERY [thread1] Erreur :erreur lors de la requête :échec :erreur réseau lors de la tentative d'exécution de la commande 'replSetStepDown' sur l'hôte 'SG-example-1.servers.mongodirector.com:27017' :DB.prototype.runCommand@src/mongo/shell/db.js:168:1DB.prototype.adminCommand@src/mongo/shell/db. js:185:1rs.stepDown@src/mongo/shell/utils.js:1305:12@(shell):1:12019-04-18T19:44:42.261+0530 I NETWORK [thread1] essayant de se reconnecter à SG-example -1.servers.mongodirector.com:27017 (X.X.X.X) a échoué2019-04-18T19:44:43.267+0530 I NETWORK [thread1] reconnect SG-example-1.servers.mongodirector.com:27017 (X.X.X.X) okRS-example- 0:SECONDAIRE>
Voici les parties pertinentes de notre code de test :
require 'mongo'...logger =Logger.new(STDOUT)logger.level =Logger::INFOMONGODB_CA_CERT ="/path/to/ca_cert.pem"MONGODB_CONN_URL ="mongodb://testuser:@ SG-example-17026.servers.mongodirector.com:27017,SG-example-17027.servers.mongodirector.com:27017,SG-example-17028.servers.mongodirector.com:27017/test?replicaSet=RS-example- 0&ssl=true"options ={ ssl:true, ssl_verify:true, :ssl_ca_cert => MONGODB_CA_CERT }begin logger.info("Tentative de connexion...") client =Mongo::Client.new(MONGODB_CONN_URL, options) i =0 loop do db =client.database collection =db[:test] begin doc ={"idx":i, "date":DateTime.now, "text":SecureRandom.base64(3) } result =collection.insert_one( doc) logger.info("Enregistrement inséré - id :#{result.inserted_id}") i +=1 sleep(3) rescue Mongo::Error => e logger.error("Erreur Mong vue :#{e.message }") logger.error(e.backtrace) logger.i nfo("Réessayer...") end end logger.info("Done")rescue => err logger.error("Exception vue :#{err.message}") logger.error(err.backtrace)assurer le client. fermer à moins que client.nil?end
Ceci écrit en continu des entrées comme celles-ci dans la collection de test de la base de données de test :
RS-test-0:PRIMARY> db.test.find(){ "_id" :ObjectId("5cf50ff1896cd172a4f7c6ee"), "idx" :0, "date" :ISODate("2019-06-03T12:17 :53.008Z"), "texte" :"HTvd" }{ "_id" :ObjectId("5cf50ff6896cd172a4f7c6ef"), "idx" :1, "date" :ISODate("2019-06-03T12:17:58.697Z" ), "text" :"/e5Z" }{ "_id" :ObjectId("5cf50ff9896cd172a4f7c6f0"), "idx" :2, "date" :ISODate("2019-06-03T12:18:01.940Z"), " text" :"quuw" }{ "_id" :ObjectId("5cf50ffd896cd172a4f7c6f1"), "idx" :3, "date" :ISODate("2019-06-03T12:18:05.194Z"), "text" :" gTyY" }{ "_id" :ObjectId("5cf51000896cd172a4f7c6f2"), "idx" :4, "date" :ISODate("2019-06-03T12:18:08.442Z"), "texte" :"VDXX" }{ "_id" :ObjectId("5cf51003896cd172a4f7c6f3"), "idx" :5, "date" :ISODate("2019-06-03T12:18:11.691Z"), "texte" :"UY87" }...Voyons le comportement lors d'un basculement :
I, [2019-06-03T17:53:25.079829 #9464] INFO -- :Tentative de connexion...I, [2019-06-03T17:53:30.577099 #9464] INFO -- :Enregistrement inséré - id :5cf5113f896cd124f8f31062I, [2019-06-03T17:53:33.816528 #9464] INFO -- :Enregistrement inséré - id :5cf51145896cd124f8f31063I, [2019-06-03T17:53:37.047043] #94 5cf51148896cd124f8f31064I, [2019-06-03T17:53:40.281537 #9464] INFO -- :Record inserted - id:5cf5114c896cd124f8f31065I, [2019-06-03T17:53:43.520010 #9464] INFO -- :Record inserted - id:5cf5114f896cd124f8f31066I, [2019-06-03T17:53:46.747080 #9464] INFO -- :Enregistrement inséré - id :5cf51152896cd124f8f31067I, [2019-06-03T17:53:49.978077 #9464] INFO -- :Enregistrement inséré - id :5cf511554896cd12 <<Il est évident que si les erreurs correctes sont détectées et que les lectures/écritures sont réessayées, le pilote détectera automatiquement le changement de topologie et se reconnectera au nouveau maître. Pour les écritures, l'option :retry_writes assurez-vous que le pilote réessayera une fois de lui-même avant de notifier l'application d'une erreur.
Il existe également plusieurs délais d'attente du pilote qui peuvent être modifiés en fonction du comportement et de la latence exacts que vous voyez sur votre configuration. Ceux-ci sont documentés ici.
Dépannage
Si vous rencontrez des difficultés pour vous connecter à votre déploiement MongoDB compatible SSL, voici quelques conseils de débogage :
- Tout d'abord, vérifiez que vous pouvez réellement vous connecter au serveur MongoDB à partir du serveur sur lequel votre application s'exécute. Pour ce faire, le moyen le plus simple consiste à installer mongo shell sur la machine cliente. Sous Linux, vous n'auriez pas besoin d'installer l'intégralité du serveur MongoDB - vous pouvez choisir d'installer simplement le shell séparément. Une fois le shell disponible, essayez d'utiliser la "syntaxe de ligne de commande" que nous fournissons pour tenter de vous connecter au serveur.
- Si vous n'arrivez pas à vous connecter via le shell mongo, cela signifie que la machine cliente n'arrive pas à atteindre le port 27017 des serveurs MongoDB. Examinez les paramètres de votre groupe de sécurité, de votre VPC et de votre pare-feu ScaleGrid pour vous assurer qu'il existe une connectivité entre les ordinateurs client et serveur.
- Si la connectivité réseau est correcte, la prochaine chose à vérifier est que vous utilisez des versions de Ruby, mongoid et mongo gem qui sont compatibles avec la version de votre serveur MongoDB.
- Si vous avez confirmé que les versions du pilote sont correctes, essayez d'exécuter un exemple de script Ruby, similaire à l'exemple que nous avons fourni ci-dessus, sur l'IRB. Une exécution étape par étape peut indiquer où se situe le problème.
- Si le script de test fonctionne correctement, mais que vous ne parvenez toujours pas à vous connecter avec mongoid, essayez d'exécuter un script de test simple, comme l'exemple que nous avons fourni ci-dessus .
- Si vous rencontrez toujours des problèmes de connexion à votre instance, veuillez nous écrire à [email protected] avec les résultats détaillés des étapes de dépannage ci-dessus et avec les versions exactes des pilotes Ruby, mongoid et mongo que vous utilisez. Le Gemfile.lock vous fournira les versions exactes.
Si vous êtes nouveau sur ScaleGrid et que vous souhaitez essayer ce didacticiel, inscrivez-vous pour un essai gratuit de 30 jours pour explorer la plate-forme et tester connecter MongoDB à votre application Ruby.