Search code examples
ruby-on-railssslruby-on-rails-4compose-dbmongoid5

Mongo SSL config with CA cert only works for rails console, not rails server


I am trying to configure a Rails 4.2.6 app to connect over SSL to a MongoDB cluster on compose.io. The app uses the mongo 2.4.1 and mongoid 5.1.5 gems. Compose.io MongoDB clusters use self-signed SSL certificates so I downloaded the CA certificate from compose.io and placed it in lib/certs/mongo-ca-bundle.pem.

My mongoid.yml file looks like this (redacted):

development:
  clients:
    default:
      uri: mongodb://myuser:[email protected]:1111,some-other-host.dblayer.com:2222/mydb?ssl=true
      options:
        ssl_ca_cert: /path/to/myapp/lib/certs/mongo-ca-bundle.pem

The above configuration works perfectly when I run rails console and I can successfully run queries against collections in the compose.io database.

However, when I try to run rails server it crashes after 30 seconds with a "No server is available" error message:

[..]/mongo/server_selector/selectable.rb:115:in `select_server': No server is available matching preference: #<Mongo::ServerSelector::Primary:0x47167439625640 tag_sets=[] max_staleness=nil> using server_selection_timeout=30 and local_threshold=0.015 (Mongo::Error::NoServerAvailable)
[..]/mongo/cluster.rb:226:in `next_primary'

When I enable debug logging for mongoid it indicates that the problem is with the SSL handshake:

DEBUG -- : MONGODB | Server some-host.dblayer.com:1111 initializing.
DEBUG -- : MONGODB | SSL handshake failed. MongoDB may not be configured with SSL support.

I used to get the same error in the rails console until I added the ssl_ca_cert configuration. I did manage to get the server to connect by specifying ssl_verify: false but I don't consider that a valid workaround. How can I fix this? How come the console works but the server doesn't?


Solution

  • It seems I was missing a certificate in the CA-bundle causing the connection to fail. With the proper CA cert in the bundle, rails server can connect just fine.

    The reason that rails console worked seems to be that it connects to the local mongodb instance even if I specify a different URL in mongoid.yml. This seems buggy to me, but I haven't investigated further.