sql >> Database teknologi >  >> NoSQL >> MongoDB

Forbinder MongoDB til Ruby med selvsignerede certifikater til SSL

I betragtning af populariteten af ​​vores indlæg om at forbinde MongoDB SSL med selvsignerede certifikater i Node.js, besluttede vi at skrive et selvstudie om at forbinde MongoDB med Ruby. I denne blog viser vi dig, hvordan du opretter forbindelse til en MongoDB-server, der er konfigureret med selvsignerede certifikater til SSL ved hjælp af både Ruby MongoDB-driveren og den populære Object-Document-Mapper (ODM)-mongoid.

ScaleGrid bruger i øjeblikket selvsignerede certifikater til SSL ved oprettelse af noder til en ny klynge. Derudover giver vi dig også mulighed for at købe dine egne SSL-certifikater og konfigurere dem på MongoDB-serveren, og du kan sende en e-mail til [email protected] for at lære mere om dette tilbud.

Tilslutning til et replikasæt ved hjælp af Ruby MongoDB-driver

Vi vil bruge den seneste stabile Ruby MongoDB-driverversion 2.8 til dette eksempel. 2.5.x-versionerne af driveren har en kendt fejl, der forhindrer dem i at arbejde med ScaleGrid-implementeringer. Ruby-versionen, der bruges i begge eksempler nedenfor, er 2.6.3.

De tilgængelige forbindelsesmuligheder for driveren er dokumenteret her, og de muligheder, vi skal bruge, er:

  • :ssl
  • :ssl_verify
  • :ssl_ca_cert .

Find og kopier først din MongoDB-forbindelsesstreng fra siden med klyngedetaljer på ScaleGrid-konsollen:

CA-certifikatfilen kan også downloades fra siden med klyngedetaljer. Download og gem certifikatfilen på et sted, der er tilgængeligt for applikationen:
Her er et uddrag, der viser, hvordan man opretter forbindelse til et MongoDB-repliksæt fra 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&ss" 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} has collections #name} {collections}"client.close

For at holde eksemplet simpelt har vi specificeret forbindelsesstrengen og certfilstien direkte i kodestykket – du ville normalt enten lægge dem i en yaml-fil eller angive dem som miljøvariabler. Eksemplet sætter også logniveauet til DEBUG så eventuelle forbindelsesproblemer kan fejlsøges. Det bør ændres til et mindre udførligt niveau, når forbindelsesproblemer er blevet løst.

Sådan forbinder du MongoDB til en Ruby-applikation med SSLClick To Tweet

Opretter forbindelse ved hjælp af Mongoid

Den mongoid-version, vi vil bruge i vores eksempel, er den seneste stabile version – 7.0.2. Vi vil bruge en yaml-fil til at give konfiguration til mongoid, og detaljerne for en sådan konfigurationsfil er dokumenteret her. De SSL-specifikke konfigurationsmuligheder, vi skal bruge for at oprette forbindelse til vores replikasæt, er:

  • ssl
  • ssl_verify
  • ssl_ca_cert

Vores yml-fil:

udvikling:# Konfigurer tilgængelige databaseklienter. (påkrævet) klienter:# Definer standardklienten. (påkrævet) standard:# En uri kan defineres for en klient:# uri:'mongodb://user:[email protected]:27017/my_db' # Se venligst driverdokumentationen for detaljer. Alternativt kan du definere følgende:# # Definer navnet på standarddatabasen, som Mongoid kan oprette forbindelse til. # (påkrævet). database:test # Angiv de værter, som standardklienten kan oprette forbindelse til. Skal være et array # af host:port-par. (påkrævet) værter:- SG-example-17026.servers.mongodirector.com:27017 - SG-example-17027.servers.mongodirector.com:27017 - SG-example-17028.servers.mongodirector.com:471000 muligheder:# Navnet på brugeren til godkendelse. bruger:'testbruger' # Brugerens adgangskode til godkendelse. adgangskode:'pwd' # Brugerens databaseroller. roller:- 'readWrite' # Skift standardgodkendelsesmekanismen. Gyldige muligheder er::scram, # :mongodb_cr, :mongodb_x509 og :plain. (standard på 3.0 er :scram, standard # på 2.4 og 2.6 er :plain) auth_mech::scram # Databasen eller kilden til at godkende brugeren imod. (standard:admin) auth_source:test # Tving driveren til at oprette forbindelse på en bestemt måde i stedet for automatisk at # opdage. Kan være en af::direct, :replica_set, :sharded. Indstil til :direct #, når du opretter forbindelse til skjulte medlemmer af et replikasæt. connect::replica_set ... ... # Navnet på det replikasæt, der skal oprettes forbindelse til. Servere, der leveres som frø, der # ikke tilhører dette replikasæt, vil blive ignoreret. replika_sæt:RS-eksempel-0 # Om der skal oprettes forbindelse til serverne via ssl. (standard:falsk) ssl:sand # Hvorvidt der skal udføres peer-certificeringsvalidering. (standard:sand) ssl_verify:sand # Filen, der indeholder et sæt sammenkædede certificeringsmyndighedscertificeringer # bruges til at validere certifikater sendt fra den anden ende af forbindelsen. ssl_ca_cert:/path/to/ca_cert.pem # Konfigurer Mongoid-specifikke muligheder. (valgfrit) muligheder:# Indstil Mongoid- og Ruby-driverlogniveauerne. (standard::info) log_level::debug

Eksempel på forbindelse:

gem 'mongoid', '7.0.2'require 'mongoid'Mongoid.load!("/path/to/mongoid.yml", :development)# Bruger ikke nogen af ​​ODM-funktionerne - bare hent den underliggende mongo klient og forsøg på at forbinde klient =Mongoid::Clients.defaultdb =client.databasecollections =db.collection_namesputs "db #{db.name} har samlinger #{collections}"Mongoid::Clients.disconnect

Igen, i produktions Ruby on Rails-applikationer, ville yaml-filstien blive hentet fra miljøvariablerne.

Test af failover-adfærd

Ligesom andre MongoDB-drivere er Ruby MongoDB-driveren også designet til internt at genkende ændringer i topologi på grund af hændelser som failover. Det er dog godt at teste og validere driverens adfærd under failovers for at undgå overraskelser i produktionen.

Ligesom mit tidligere indlæg på MongoDB PyMongo kan vi skrive et evigt forfattertestprogram for at observere driverens failover-adfærd.

Den nemmeste måde at fremkalde failover på er at køre kommandoen rs.stepDown():

RS-example-0:PRIMARY> rs.stepDown()2019-04-18T19:44:42.257+0530 E QUERY [thread1] Fejl:fejl ved at udføre forespørgsel:mislykkedes:netværksfejl under forsøg på at køre kommandoen 'replSetStepDown' på vært '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 NETVÆRK [thread1] prøver at oprette forbindelse til SG-eksempel igen -1.servers.mongodirector.com:27017 (X.X.X.X) failed2019-04-18T19:44:43.267+0530 JEG NETVÆRK [thread1] genopretter forbindelse til SG-example-1.servers.mongodirector.com:27017 (X.) ok.eks. 0:SEKUNDÆR>

Her er de relevante dele af vores testkode:

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 }begynd logger.info("Forsøg på at oprette forbindelse...") client =Mongo::Client.new(MONGODB_CONN_URL, optioner) i =0 loop do db =client.database collection =db[:test] start doc ={"idx":i, "date":DateTime.now, "text":SecureRandom.base64(3) } result =collection.insert_one( doc) logger.info("Record inserted - id:#{result.inserted_id}") i +=1 sleep(3) rescue Mongo::Error => e logger.error("Mong Error set:#{e.message }") logger.error(e.backtrace) logger.i nfo("Prøver igen...") end end logger.info("Done")rescue => err logger.error("Undtagelse set:#{err.message}") logger.error(err.backtrace)ensure client. luk, medmindre client.nil?end

Dette skriver løbende poster som disse til testsamlingen på testdatabasen:

RS-test-0:PRIMARY> db.test.find(){ "_id" :ObjectId("5cf50ff1896cd172a4f7c6ee"), "idx" :0, "date" :ISODate("2019-06-03T12:17 :53.008Z"), "text" :"HTvd" }{ "_id" :ObjectId("5cf50ff6896cd172a4f7c6ef"), "idx" :1, "date" :ISODate("2019-06-03T12:697:58". ), "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"), "tekst" :" gTyY" }{ "_id" :ObjectId("5cf51000896cd172a4f7c6f2"), "idx" :4, "date" :ISODate("2019-06-03T12:18:08.442Z"), "text" :"VDXX" "_id" :ObjectId("5cf51003896cd172a4f7c6f3"), "idx" :5, "date" :ISODate("2019-06-03T12:18:11.691Z"), "text" :"UY87" }...

før>

Lad os se adfærden under en failover:

I, [2019-06-03T17:53:25.079829 #9464] INFO -- :Forsøg på at oprette forbindelse...I, [2019-06-03T17:53:30.577099 #9464] INFO -- :Record indsat - ID:5CF5113F896CD124F8F31062I, [2019-06-03T17:53:33.816528 #9464] INFO-:Record Instented-ID:5CF51145896CD124F8F31063I, [2019-06-03T17:537.024744244242424242424242424242424424424424424424424424424242424242424242424242424242424242424242424242444 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-:Record Insterated-ID:5CF51152896CD124F8F31067i, [2019-06-03T17:53:49.978077 #9464] Info-:posten indsat-Id:5cf51111115111111111111111111111111111111111111111111111111111111111111111111 Failover påbegyndt herE, [2019-06-03T17:53:52.980434 #9464] FEJL -- :Mong Fejl set:EOFError:slutningen af ​​filen nået (for x.x.x.x:27017 (sg-example-17026.directorservers.com:2go70directorservers.com:2go70directorservers. , TLS))E, [2019-06-03T17:53:52.980533 #9464] FEJL -- :["C:/Ruby 26-x64/lib/ruby/gems/2.6.0/gems/mongo-2.8.0/lib/mongo/socket.rb:300:in `rescue in handle_errors'", "C:/Ruby26-x64/lib/ ruby/gems/2.6.0/gems/mongo-2.8.0/lib/mongo/socket.rb:294:in `handle_errors'", "C:/Ruby26-x64/lib/ruby/gems/2.6.0/ gems/mongo-2.8.0/lib/mongo/socket.rb:126:in `read'", "C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/mongo-2.8.0/ lib/mongo/protocol/message.rb:139:in `deserialize'",......I, [2019-06-03T17:53:52.980688 #9464] INFO -- :Prøver igen...W, [ 2019-06-03T17:53:52.981575 #9464] ADVARSEL -- :Prøver ismaster igen på sg-example-17026.servers.mongodirector.com:27017 på grund af:Mongo::Error::SocketError EOFError nået (for end of file x.x.x.x:27017 (sg-example-17026.servers.mongodirector.com:27017, TLS))I, [2019-06-03T17:54:06.293100 #9464] INFO -- :Record indsat - 5916cf id:5916cf 59116cf 5116cf 59116cf 06-03T17:54:09.547716 #9464] INFO -- :Optegnelse indsat - id:5cf51169896cd124f8f3106bI, [2019-06-03T17:54:12.8046636] INERf 6c:1cd 6cd 6d 1cd 6d 1cd 6d 1cd 1cf 1cf 6cd 6cf 1cd 2019. re> 

Det er tydeligt, at hvis korrekte fejl fanges og læse/skrive forsøges igen, vil driveren automatisk registrere topologiændringen og genoprette forbindelse til den nye master. For skrivninger, muligheden :retry_writes sørg for, at driveren vil prøve igen én gang af sig selv, før han giver besked om en fejl.

Der er også flere driver-timeouts, der kan justeres baseret på den nøjagtige adfærd og forsinkelse, du ser på din opsætning. Disse er dokumenteret her.

Fejlfinding

Hvis du har problemer med at oprette forbindelse til din SSL-aktiverede MongoDB-implementering, er her et par tip til fejlretning:

  • Først skal du kontrollere, at du faktisk kan oprette forbindelse til MongoDB-serveren fra serveren, hvor din applikation kører. Den nemmeste måde at gøre dette på er at installere mongo shell på klientmaskinen. På Linux behøver du ikke installere hele MongoDB-serveren - du kan vælge bare at installere skallen separat. Når shellen er tilgængelig, kan du prøve at bruge den 'Kommandolinjesyntaks', vi leverer, til at forsøge at oprette forbindelse til serveren.
  • Hvis du ikke er i stand til at oprette forbindelse via mongo-skallen, betyder det, at klientmaskinen ikke er i stand til at nå port 27017 på MongoDB-serverne. Se på dine sikkerhedsgruppe-, VPC- og ScaleGrid-firewallindstillinger for at sikre, at der er forbindelse mellem klient- og servermaskinerne.
  • Hvis netværksforbindelsen er korrekt, er den næste ting at kontrollere, at du bruger versioner af Ruby, mongoid og mongo gem, der er kompatible med versionen af din MongoDB-server.
  • Hvis du har bekræftet, at driverversionerne er korrekte, kan du prøve at køre et eksempel på Ruby-script, svarende til eksemplet, vi har givet ovenfor, på IRB'en. En trin-for-trin udførelse kan pege på, hvor problemet er.
  • Hvis testscriptet kører fint, men du stadig ikke er i stand til at oprette forbindelse til mongoid, så prøv at køre et simpelt testscript, som eksemplet ovenfor. .
  • Hvis du stadig har problemer med at oprette forbindelse til din instans, bedes du skrive til os på [email protected] med detaljerede resultater af ovenstående fejlfindingstrin og med de nøjagtige versioner af Ruby, mongoid og mongo driver du bruger. Gemfile.lock vil give dig de nøjagtige versioner.

Hvis du er ny i ScaleGrid og vil prøve denne tutorial, kan du tilmelde dig en gratis 30-dages prøveperiode for at udforske platformen og afprøve platformen forbinder MongoDB til din Ruby-applikation.


  1. MongoDB:Er det muligt at lave en forespørgsel uden store og små bogstaver?

  2. Strengfeltværdilængde i mongoDB

  3. Sådan håndteres bruger- og socket-par med node.js + redis

  4. Returner hgetall-listen fra redis i nodejs