pg gem中对SSL支持的运行时检测

时间:2018-12-12 15:59:12

标签: ruby postgresql ssl

我们有一些Ruby代码,其功能类似于:

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')

重要的是,远程Postgres实例配置为强制使用SSL(例如like this)-客户端代码中的sslmode: 'require'是多余的。

这在许多开发人员机器上都能正常工作,但一些开发人员注意到他们遇到了以下错误:

 FATAL:  no pg_hba.conf entry for host "...", user "...", database "...", SSL off (PG::ConnectionBad)

,根本原因似乎是他们的pg gem实际上没有SSL支持。

我的问题:有没有办法确定pg宝石是否确实具有SSL支持,而无需实际尝试连接到需要SSL的服务器? (如果我们能够立即发现问题,而不是等到创建远程Postgres实例然后才发现问题,那就更好了。)

我的第一个想法是检查pg宝石上的方法,例如init_openssl,但是文档声称:

  

未编译SSL支持时,此功能存在,但不执行任何操作。

,无论是否提供SSL支持,此行为似乎都是相同的:

2.3.1 :002 > PG.init_openssl(true, true)
 => nil 

环境信息:最新OS X上的ruby 2.3,pg gem 0.19.0,libpq的各种版本

1 个答案:

答案 0 :(得分:1)

首先,确保Ruby是在OpenSSL支持下编译的:

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/openssl@1.1' '--disable-install-doc' '--enable-shared' 'build_alias=' 'host_alias=' 'target_alias=' 'CC=gcc'

确保openssl--with-opt-dir输出中。或者,您可以使用以下方法进行检查:

ruby -r openssl -e 'puts OpenSSL::OPENSSL_LIBRARY_VERSION'
OpenSSL 1.1.1  11 Sep 2018

接下来,找到您的pg_ext.bundle。具体位置取决于您安装Ruby和gems的方式,但是如果您使用的是RVM,则在~/.rvm/gems中定位是相当简单的。例如,它在我这里:

~/.rvm/gems/ruby-2.6.0-preview2/gems/pg-1.1.3/ext/pg_ext.bundle

现在运行otool -L来查找与其链接的库:

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)

现在对以上输出中列出的otool -L dylib运行libpq,以查看其链接的内容:

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)

只要链接到libssllibcrypto,已安装的pg gem就应该也支持OpenSSL。