我们有一些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
的各种版本
答案 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)
只要链接到libssl
和libcrypto
,已安装的pg
gem就应该也支持OpenSSL。