使用rbenv和ruby-build构建ruby时会出现未定义的符号:SSLv2_method

我正在尝试在带有ARMv7处理器的Synology DS215j上安装ruby 2.2.4或2.3.0。 我使用optware-ng来安装gcc,make,openssl,openssl-dev和zlib。 我按照自述文件中的说明安装了rbenv(版本1.0.0-19-g29b4da7)和ruby-build插件。

这些是使用optware-ng安装的软件包及其版本

binutils - 2.25.1-1 gcc - 5.3.0-6 gconv-modules - 2.21-3 glibc-opt - 2.21-4 libc-dev - 2.21-1 libgmp - 6.0.0a-1 libmpc - 1.0.2-1 libmpfr - 3.1.3-1 libnsl - 2.21-3 libstdc++ - 6.0.21-6 make - 4.1-1 ncurses - 5.7-4 openssl - 1.0.2f-1 openssl-dev - 1.0.2f-1 readline - 6.1-2 ruby - 2.2.0-1 screen - 4.2.1-2 termcap - 1.3.1-3 zlib - 1.2.8-2 

当我在两种情况下运行rbenv install 2.2.4rbenv install 2.3.0 ,构建失败并显示错误消息“undefined symbol:SSLv2_method”。 这是2.2.4版本的错误:

 installing bundle gems: /var/services/homes/florian/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0 (build_info, cache, doc, extensions, gems, specifications) /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require': /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/.ext/armv7l-linux-eabihf/openssl.so: undefined symbol: SSLv2_method - /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/.ext/armv7l-linux-eabihf/openssl.so (LoadError) from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/.ext/common/openssl.rb:17:in `' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/security.rb:11:in `' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/package.rb:43:in `' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/dependency_installer.rb:3:in `' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems/core_ext/kernel_require.rb:54:in `require' from /tmp/ruby-build.20160329115213.2672/ruby-2.2.4/lib/rubygems.rb:556:in `install' from ./tool/rbinstall.rb:722:in `block (2 levels) in ' from ./tool/rbinstall.rb:721:in `each' from ./tool/rbinstall.rb:721:in `block in ' from ./tool/rbinstall.rb:757:in `call' from ./tool/rbinstall.rb:757:in `block in ' from ./tool/rbinstall.rb:754:in `each' from ./tool/rbinstall.rb:754:in `' uncommon.mk:246: recipe for target 'do-install-all' failed make: *** [do-install-all] Error 1 

这似乎与rubygems中的某些内容有关。

有趣的是,我尝试自己构建ruby的原因是,当我尝试安装gem时,Synology 6提供的ruby版本会返回类似的错误:

 florian@synology:~/.rbenv/plugins$ /usr/bin/gem install rails ERROR: Loading command: install (LoadError) /usr/lib/ruby/2.3.0/armle-linux-gnu/openssl.so: undefined symbol: SSLv2_method - /usr/lib/ruby/2.3.0/armle-linux-gnu/openssl.so ERROR: While executing gem ... (NoMethodError) undefined method `invoke_with_build_args' for nil:NilClass 

什么可能导致这些问题,我该如何解决它们?

当我在两种情况下运行rbenv install 2.2.4或rbenv install 2.3.0时,构建失败并显示错误消息"undefined symbol: SSLv2_method"

什么可能导致这些问题……

由于CVE-2016-0800 ( DROWN Attack ),3月份SSLv2设备已从OpenSSL中完全删除。

我认为完全删除有点苛刻,因为你正在经历的影响。 应该有警告和过渡期。 它应该发生在10年前左右。

我认为SSLv2_methodSSLv2_client_methodSSLv2_server_method应该设置一个适当的错误代码,如ERR_R_REMOVED_INSECURE并返回NULL,而不是由于DROWN而完全删除。 应该无条件地设置OPENSSL_NO_SSL2

OpenSSL意识到它们破坏了ABI兼容性,并使用Commit 133138569f37d149将符号添加回1.0.2。 签SSLv2_server_method再次提供符号SSLv2_methodSSLv2_client_methodSSLv2_server_method ,但它们返回NULL而不设置错误代码。 它们也没有定义OPENSSL_NO_SSL2 。 另见[openssl.org#4398] BUG / 1.0.2g打破了CURL扩展 。

SSLv2已经不安全15或20年了。 Ruby之类的软件包不应该引用这些符号。 您应该针对Ruby提交安全错误报告以引用该符号。


……我怎么能解决它们?

要解决此问题,我相信您需要(1)等待OpenSSL 1.0.2h,(2),手动修补OpenSSL 1.0.2g,或(3)删除所有对SSLv2_methodSSLv2_client_methodSSLv2_server_method Ruby引用。

这是你需要的补丁(2),手动补丁OpenSSL 1.0.2g:

 diff --git a/ssl/s2_meth.cb/ssl/s2_meth.c index b312f17..d46e2f5 100644 --- a/ssl/s2_meth.c +++ b/ssl/s2_meth.c @@ -74,8 +74,8 @@ IMPLEMENT_ssl2_meth_func(SSLv2_method, ssl2_accept, ssl2_connect, ssl2_get_method) #else /* !OPENSSL_NO_SSL2 */ -# if PEDANTIC -static void *dummy = &dummy; -# endif +SSL_METHOD *SSLv2_method(void) { return NULL; } +SSL_METHOD *SSLv2_client_method(void) { return NULL; } +SSL_METHOD *SSLv2_server_method(void) { return NULL; } #endif 

您还应该使用至少no-ssl2 no-ssl3 no-comp标志配置和编译OpenSSL,因为它们是已知的安全问题。 configure选项在定义OPENSSL_NO_SSL2OPENSSL_NO_SSL3OPENSSL_NO_COMP

经过多次尝试和大量搜索后,我发现了这个ruby-build问题并重新阅读了ruby-build wiki中的指令,这些指令建议其他平台安装autoconf。 我安装了automaker,autoconf和gdbm(我在ruby-build日志中发现了一些警告),ipkg没有直接帮助。 只有在我用RUBY_CONFIGURE_OPTS=--with-openssl-dir=/opt作为rbenv前缀后才有效。

作为参考,这些是我用ipkg安装的软件包

 autoconf - 2.69-1 automake - 1.15-3 binutils - 2.25.1-1 gcc - 5.3.0-6 gconv-modules - 2.21-3 gdbm - 1.8.3-4 glibc-opt - 2.21-4 libc-dev - 2.21-1 libgmp - 6.0.0a-1 libmpc - 1.0.2-1 libmpfr - 3.1.3-1 libnsl - 2.21-3 libstdc++ - 6.0.21-6 m4 - 1.4.17-1 make - 4.1-1 ncurses - 5.7-4 openssl - 1.0.2f-1 openssl-dev - 1.0.2f-1 readline - 6.1-2 ruby - 2.2.0-1 screen - 4.2.1-2 termcap - 1.3.1-3 zlib - 1.2.8-2 

这是最终为我工作的rbenv命令

 RUBY_CONFIGURE_OPTS=--with-openssl-dir=/opt rbenv install 2.3.0 -v