Reputation: 2710
We have some Ruby code which does something like:
require 'pg'
# Create a remote Postgres database instance, and wait
# until it's online, then try to connect:
conn = PG::Connection.new(
... params ...
sslmode: 'require')
The important part is that the remote Postgres instance is configured such that SSL usage is mandatory (e.g. like this) -- the sslmode: 'require'
in the client code is redundant.
This works fine on many developer machines, but some developers are noticing that they get some error like:
FATAL: no pg_hba.conf entry for host "...", user "...", database "...", SSL off (PG::ConnectionBad)
and the root cause seems to be that their pg
gem does not actually have SSL support.
My question: is there any way to determine if the pg
gem does in fact have SSL support, without actually trying to connect to a server requiring SSL? (It would be much better if we could detect the problem right away, instead of waiting until a remote Postgres instance has been created, and only then discovering the problem.)
My first thought was to check a method on the pg
gem such as init_openssl, but the documentation claims:
When SSL support is not compiled in, this function is present but does nothing.
and this behavior appears to be the same whether SSL support is present or not:
2.3.1 :002 > PG.init_openssl(true, true)
=> nil
Environment info: ruby 2.3 on recent OS X, pg
gem 0.19.0, various versions of libpq
Upvotes: 1
Views: 615
Reputation: 10526
First, make sure Ruby is compiled with OpenSSL support:
ruby -r rbconfig -e 'puts RbConfig::CONFIG["configure_args"]'
'--prefix=/Users/foo/.rvm/rubies/ruby-2.6.0-preview2' '' '--with-opt-dir=/usr/local/opt/libyaml:/usr/local/opt/readline:/usr/local/opt/libksba:/usr/local/opt/[email protected]' '--disable-install-doc' '--enable-shared' 'build_alias=' 'host_alias=' 'target_alias=' 'CC=gcc'
Make sure openssl
is somewhere in the --with-opt-dir
output. Alternatively, you can check with this:
ruby -r openssl -e 'puts OpenSSL::OPENSSL_LIBRARY_VERSION'
OpenSSL 1.1.1 11 Sep 2018
Next, locate your pg_ext.bundle
. The location of this will vary depending on how you install Ruby and gems, but if you're using RVM it's fairly straightforward to locate in ~/.rvm/gems
. For example, it is located here for me:
~/.rvm/gems/ruby-2.6.0-preview2/gems/pg-1.1.3/ext/pg_ext.bundle
Now run otool -L
to find the libraries it is linked against:
otool -L /Users/foo/.rvm/gems/ruby-2.6.0-preview2/gems/pg-1.1.3/ext/pg_ext.bundle
/Users/foo/.rvm/gems/ruby-2.6.0-preview2/gems/pg-1.1.3/ext/pg_ext.bundle:
/Users/foo/.rvm/rubies/ruby-2.6.0-preview2/lib/libruby.2.6.dylib (compatibility version 2.6.0, current version 2.6.0)
/usr/local/opt/postgresql/lib/libpq.5.dylib (compatibility version 5.0.0, current version 5.11.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
Now run otool -L
against the libpq
dylib listed in the above output to see what it's linked against:
otool -L /usr/local/opt/postgresql/lib/libpq.5.dylib
/usr/local/opt/postgresql/lib/libpq.5.dylib:
/usr/local/opt/postgresql/lib/libpq.5.dylib (compatibility version 5.0.0, current version 5.11.0)
/usr/local/opt/openssl/lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Kerberos.framework/Versions/A/Kerberos (compatibility version 5.0.0, current version 6.0.0)
/System/Library/Frameworks/LDAP.framework/Versions/A/LDAP (compatibility version 1.0.0, current version 2.4.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
As long as it's linked against libssl
and libcrypto
, the installed pg
gem should support OpenSSL as well.
Upvotes: 1