sql >> データベース >  >> NoSQL >> MongoDB

SSL用の自己署名証明書を使用してMongoDBをRubyに接続する

    Node.jsでMongoDBSSLを自己署名証明書に接続することに関する投稿が人気を博していることから、MongoDBをRubyに接続するためのチュートリアルを作成することにしました。このブログでは、Ruby MongoDBドライバーと人気のあるObject-Document-Mapper(ODM)モンゴイドの両方を使用して、SSLの自己署名証明書で構成されたMongoDBサーバーに接続する方法を紹介します。

    ScaleGridは現在、新しいクラスターのノードを作成するときにSSLに自己署名証明書を使用しています。さらに、独自のSSL証明書を購入し、MongoDBサーバーで構成するオプションも提供しています。このオファーの詳細については、[email protected]にメールでお問い合わせください。

    RubyMongoDBドライバーを使用したレプリカセットへの接続

    この例では、最新の安定したRubyMongoDBドライバーバージョン2.8を使用します。 2.5.xバージョンのドライバーには、ScaleGridデプロイメントでの動作を妨げる既知のバグがあります。以下の両方の例で使用されているRubyのバージョンは2.6.3です。

    ドライバーで使用できる接続オプションはここに記載されており、必要なオプションは次のとおりです。

    • :ssl
    • :ssl_verify
    • :ssl_ca_cert

    まず、ScaleGridコンソールのクラスターの詳細ページからMongoDB接続文字列を見つけてコピーします。

    CA証明書ファイルは、クラスターの詳細ページからダウンロードすることもできます。アプリケーションで使用可能な場所に証明書ファイルをダウンロードして保存します。
    これは、RubyからMongoDBレプリカセットに接続する方法を示すスニペットです:

     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}にはコレクションがあります# {collections} "client.close 

    例を単純にするために、接続文字列と証明書ファイルのパスをコードスニペットで直接指定しました。通常は、yamlファイルに入れるか、次のように指定します。環境変数。また、この例では、ログレベルをDEBUG に設定しています。 接続の問題をデバッグできるようにします。接続の問題が解決されたら、より詳細なレベルに変更する必要があります。

    SSLを使用してMongoDBをRubyアプリケーションに接続する方法クリックしてツイート

    Mongoidを使用した接続

    この例で使用するモンゴイドバージョンは、最新の安定バージョンである7.0.2です。 yamlファイルを使用してmongoidに構成を提供します。このような構成ファイルの詳細は、ここに記載されています。レプリカセットに接続するために必要なSSL固有の構成オプションは次のとおりです。

    • ssl
    • ssl_verify
    • ssl_ca_cert

    ymlファイル:

     development:#使用可能なデータベースクライアントを構成します。 (必須)clients:#デフォルトのクライアントを定義します。 (必須)デフォルト:#クライアントにURIを定義できます:#uri:'mongodb:// user:[email protected]:27017 / my_db'#詳細については、ドライバーのドキュメントを参照してください。または、以下を定義することもできます。##Mongoidが接続できるデフォルトのデータベースの名前を定義します。 # (必要)。 database:test#デフォルトのクライアントが接続できるホストを提供します。 host:portペアの配列#である必要があります。 (必須)ホスト:-SG-example-17026.servers.mongodirector.com:27017-SG-example-17027.servers.mongodirector.com:27017-SG-example-17028.servers.mongodirector.com:47100  options:#認証用のユーザーの名前。 ユーザー:'testuser'  #認証用のユーザーのパスワード。 パスワード:'pwd'  #ユーザーのデータベースの役割。ロール:-'readWrite'#デフォルトの認証メカニズムを変更します。有効なオプションは、:scram、#:mongodb_cr、:mongodb_x509、および:plainです。 (3.0のデフォルトは:scram、2.4および2.6のデフォルト#は:plainです)auth_mech::scram#ユーザーを認証するためのデータベースまたはソース。 (デフォルト:admin) auth_source:test  #自動検出ではなく、特定の方法でドライバーを強制的に接続します。 ::direct、:replica_set、:shardedのいずれかになります。レプリカセットの非表示のメンバーに接続する場合は、:direct#に設定します。 connect::replica_set ... ...#接続するレプリカセットの名前。 #このレプリカセットに属さないシードとして提供されたサーバーは無視されます。 レプリカセット:RS-example-0  #sslを介してサーバーに接続するかどうか。 (デフォルト:false) ssl:true  #ピア認証の検証を行うかどうか。 (デフォルト:true) ssl_verify:true  #接続のもう一方の端から渡された証明書を検証するために使用される、連結された認証局証明書のセットを含むファイル。  ssl_ca_cert:/path/to/ca_cert.pem  #Mongoid固有のオプションを構成します。 (オプション)オプション:#MongoidおよびRubyドライバーのログレベルを設定します。 (デフォルト::info)log_level::debug 

    接続例:

     gem'mongoid'、 '7.0.2' require'mongoid' Mongoid.load!( "/ path / to / mongoid.yml"、:development)#ODM機能を使用せず-基盤となるmongoをフェッチするだけクライアントと接続を試みますclient=Mongoid ::Clients.defaultdb =client.databasecollections =db.collection_namesputs "db#{db.name} has collections#{collections}" Mongoid ::Clients.disconnect 

    繰り返しになりますが、本番環境のRuby on Railsアプリケーションでは、yamlファイルパスが環境変数から取得されます。

    フェイルオーバー動作のテスト

    他のMongoDBドライバーと同様に、Ruby MongoDBドライバーも、フェイルオーバーなどのイベントによるトポロジの変更を内部的に認識するように設計されています。ただし、本番環境での予期しない事態を回避するために、フェイルオーバー中のドライバーの動作をテストおよび検証することをお勧めします。

    MongoDB PyMongoに関する以前の投稿と同様に、ドライバーのフェイルオーバー動作を観察するための永続的なライターテストプログラムを作成できます。

    フェイルオーバーを誘発する最も簡単な方法は、rs.stepDown()コマンドを実行することです:

     RS-example-0:PRIMARY> rs.stepDown()2019-04-18T19:44:42.257 + 0530 E QUERY [thread1]エラー:クエリの実行中にエラーが発生しました:失敗しました:コマンド'replSetStepDown'を実行しようとしたときにネットワークエラーが発生しましたホスト'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]SGへの再接続を試みています-例-1.servers.mongodirector.com:27017(X.X.X.X)failed2019-04-18T19:44:43.267 + 0530 I NETWORK [thread1] reconnect SG-example-1.servers.mongodirector.com:27017(X.X.X.X)okRS-example- 0:2番目> 

    テストコードの関連部分は次のとおりです:

     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("接続しようとしています... ")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( "レコードが挿入されました-id:#{result.inserted_id}")i + =1 sleep(3)rescue Mongo ::Error => e logger.error( "Mong Error used:#{e.message } ")logger.error(e.backtrace)logger.i nfo( "Retrying ...")end end logger.info( "Done")rescue => err logger.error( "例外が表示されました:#{err.message}")logger.error(err.backtrace)ensureclient。 client.nil?end
    でない限り閉じます

    これにより、次のようなエントリがテストデータベースのテストコレクションに継続的に書き込まれます。

     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: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 ")、" text ":" VDXX "} { "_id":ObjectId( "5cf51003896cd172a4f7c6f3")、 "idx":5、 "date":ISODate( "2019-06-03T12:18:11.691Z")、 "text": "UY87"} ... 

    フェイルオーバー中の動作を見てみましょう:

     I、[2019-06-03T17:53:25.079829#9464] INFO-:接続しようとしています... I、[2019-06-03T17:53:30.577099#9464] INFO-:レコードが挿入されました- id:5cf5113f896cd124f8f31062I、[2019-06-03T17:53:33.816528#9464]情報-:挿入されたレコード-id:5cf51145896cd124f8f31063I、[2019-06-03T17:53:37.047043#9464]情報-:挿入されたレコード-id: 5cf51148896cd124f8f31064I、[2019-06-03T17:53:40.281537#9464]情報-:挿入されたレコード-id:5cf5114c896cd124f8f31065I、[2019-06-03T17:53:43.520010#9464]情報-:挿入されたレコード-id:5cf5114f896cd124f8f31066I、 [2019-06-03T17:53:46.747080#9464]情報-:挿入されたレコード-id:5cf51152896cd124f8f31067I、[2019-06-03T17:53:49.978077#9464]情報-:挿入されたレコード-id:5cf51155896cd124f8f31068 <<<ここでフェイルオーバーが開始されましたE、[2019-06-03T17:53:52.980434#9464]エラー-:Mongエラーが表示されました:EOFError:ファイルの終わりに達しました(x.x.x.x:27017の場合(sg-example-17026.servers.mongodirector.com:27017) 、TLS))E、[2019-06-03T17:53:52.980533#9464]エラー-:["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]情報-:再試行中... W、[ 2019-06-03T17:53:52.981575#9464]警告-:sg-example-17026.servers.mongodirector.com:27017でismasterを再試行しています:Mongo ::Error ::SocketError EOFError:ファイルの終わりに達しました( x.x.x.x:27017(sg-example-17026.servers.mongodirector.com:27017、TLS))I、[2019-06-03T17:54:06.293100#9464]情報-:挿入されたレコード-id:5cf51163896cd124f8f3106aI、[2019- 06-03T17:54:09.547716#9464]情報-:挿入されたレコード-id:5cf51169896cd124f8f3106bI、[2019-06-03T17:54:12.806636#9464]情報-:挿入されたレコード-id:5cf5116c896cd124f8f3106c  

    正しいエラーが検出され、読み取り/書き込みが再試行された場合、ドライバーはトポロジーの変更を自動的に検出し、新しいマスターに再接続することは明らかです。書き込みの場合、オプション:retry_writes アプリケーションにエラーを通知する前に、ドライバーが自分で1回再試行することを確認してください。

    セットアップで見られる正確な動作と遅延に基づいて調整できる複数のドライバータイムアウトもあります。これらはここに文書化されています。

    トラブルシューティング

    SSL対応のMongoDBデプロイメントへの接続に問題がある場合は、デバッグのヒントをいくつか紹介します。

    • まず、アプリケーションが実行されているサーバーから実際にMongoDBサーバーに接続できることを確認します。これを行う最も簡単な方法は、クライアントマシンにmongoシェルをインストールすることです。 Linuxでは、MongoDBサーバー全体をインストールする必要はありません。シェルを個別にインストールすることを選択できます。シェルが利用可能になったら、サーバーへの接続を試みるために提供されている「コマンドライン構文」を使用してみてください。
    • mongoシェルを介して接続できない場合は、クライアントマシンがMongoDBサーバーのポート27017に到達できないことを意味します。セキュリティグループ、VPC、ScaleGridファイアウォールの設定を調べて、クライアントマシンとサーバーマシンの間に接続があることを確認します。
    • ネットワーク接続が正しい場合、次に確認することは、バージョンと互換性のあるバージョンのRuby、mongoid、およびmongogemを使用していることです。 MongoDBサーバーの。
    • ドライバーのバージョンが正しいことを確認したら、上記の例と同様のサンプルRubyスクリプトをIRBで実行してみてください。ステップバイステップの実行により、問題がどこにあるかが指摘される場合があります。
    • テストスクリプトは正常に実行されても、mongoidに接続できない場合は、上記の例のような簡単なテストスクリプトを実行してみてください。 。
    • それでもインスタンスへの接続に問題がある場合は、上記のトラブルシューティング手順の詳細な結果と使用しているRuby、mongoid、mongoドライバーの正確なバージョン。 Gemfile.lockは正確なバージョンを提供します。

    ScaleGridを初めて使用し、このチュートリアルを試してみたい場合は、30日間の無料トライアルにサインアップして、プラットフォームを探索してテストしてください。 MongoDBをRubyアプリケーションに接続します。


    1. MongoDBの耐久性と書き込みの安全性を理解する

    2. MongoDB update()

    3. MongoDBで多言語テキストインデックスを作成する

    4. mongodbが失敗しました:データベースサーバーへの接続中にエラーが発生しました:到達可能なサーバーがありません